Revision 19708787 scripts/gnt-instance

b/scripts/gnt-instance
847 847
      os._exit(1)
848 848

  
849 849

  
850
def _FormatBlockDevInfo(buf, dev, indent_level, static):
850
def _FormatLogicalID(dev_type, logical_id):
851
  """Formats the logical_id of a disk.
852

  
853
  """
854
  if dev_type == constants.LD_DRBD8:
855
    node_a, node_b, port, minor_a, minor_b, key = logical_id
856
    data = [
857
      ("nodeA", "%s, minor=%s" % (node_a, minor_a)),
858
      ("nodeB", "%s, minor=%s" % (node_b, minor_b)),
859
      ("port", port),
860
      ("auth key", key),
861
      ]
862
  elif dev_type == constants.LD_LV:
863
    vg_name, lv_name = logical_id
864
    data = ["%s/%s" % (vg_name, lv_name)]
865
  else:
866
    data = [str(logical_id)]
867

  
868
  return data
869

  
870

  
871
def _FormatBlockDevInfo(idx, top_level, dev, static):
851 872
  """Show block device information.
852 873

  
853 874
  This is only used by L{ShowInstanceConfig}, but it's too big to be
854 875
  left for an inline definition.
855 876

  
856
  @type buf: StringIO
857
  @param buf: buffer that will accumulate the output
877
  @type idx: int
878
  @param idx: the index of the current disk
879
  @type top_level: boolean
880
  @param top_level: if this a top-level disk?
858 881
  @type dev: dict
859 882
  @param dev: dictionary with disk information
860
  @type indent_level: int
861
  @param indent_level: the indendation level we are at, used for
862
      the layout of the device tree
863 883
  @type static: boolean
864 884
  @param static: wheter the device information doesn't contain
865 885
      runtime information but only static data
886
  @return: a list of either strings, tuples or lists
887
      (which should be formatted at a higher indent level)
866 888

  
867 889
  """
868
  def helper(buf, dtype, status):
890
  def helper(dtype, status):
869 891
    """Format one line for physical device status.
870 892

  
871
    @type buf: StringIO
872
    @param buf: buffer that will accumulate the output
873 893
    @type dtype: str
874 894
    @param dtype: a constant from the L{constants.LDS_BLOCK} set
875 895
    @type status: tuple
876 896
    @param status: a tuple as returned from L{backend.FindBlockDevice}
897
    @return: the string representing the status
877 898

  
878 899
    """
879 900
    if not status:
880
      buf.write("not active\n")
901
      return "not active"
902
    txt = ""
903
    (path, major, minor, syncp, estt, degr, ldisk) = status
904
    if major is None:
905
      major_string = "N/A"
881 906
    else:
882
      (path, major, minor, syncp, estt, degr, ldisk) = status
883
      if major is None:
884
        major_string = "N/A"
885
      else:
886
        major_string = str(major)
907
      major_string = str(major)
887 908

  
888
      if minor is None:
889
        minor_string = "N/A"
890
      else:
891
        minor_string = str(minor)
892

  
893
      buf.write("%s (%s:%s)" % (path, major_string, minor_string))
894
      if dtype in (constants.LD_DRBD8, ):
895
        if syncp is not None:
896
          sync_text = "*RECOVERING* %5.2f%%," % syncp
897
          if estt:
898
            sync_text += " ETA %ds" % estt
899
          else:
900
            sync_text += " ETA unknown"
901
        else:
902
          sync_text = "in sync"
903
        if degr:
904
          degr_text = "*DEGRADED*"
905
        else:
906
          degr_text = "ok"
907
        if ldisk:
908
          ldisk_text = " *MISSING DISK*"
909
        else:
910
          ldisk_text = ""
911
        buf.write(" %s, status %s%s" % (sync_text, degr_text, ldisk_text))
912
      elif dtype == constants.LD_LV:
913
        if ldisk:
914
          ldisk_text = " *FAILED* (failed drive?)"
909
    if minor is None:
910
      minor_string = "N/A"
911
    else:
912
      minor_string = str(minor)
913

  
914
    txt += ("%s (%s:%s)" % (path, major_string, minor_string))
915
    if dtype in (constants.LD_DRBD8, ):
916
      if syncp is not None:
917
        sync_text = "*RECOVERING* %5.2f%%," % syncp
918
        if estt:
919
          sync_text += " ETA %ds" % estt
915 920
        else:
916
          ldisk_text = ""
917
        buf.write(ldisk_text)
918
      buf.write("\n")
919

  
920
  if dev["iv_name"] is not None:
921
    data = "  - %s, " % dev["iv_name"]
921
          sync_text += " ETA unknown"
922
      else:
923
        sync_text = "in sync"
924
      if degr:
925
        degr_text = "*DEGRADED*"
926
      else:
927
        degr_text = "ok"
928
      if ldisk:
929
        ldisk_text = " *MISSING DISK*"
930
      else:
931
        ldisk_text = ""
932
      txt += (" %s, status %s%s" % (sync_text, degr_text, ldisk_text))
933
    elif dtype == constants.LD_LV:
934
      if ldisk:
935
        ldisk_text = " *FAILED* (failed drive?)"
936
      else:
937
        ldisk_text = ""
938
      txt += ldisk_text
939
    return txt
940

  
941
  # the header
942
  if top_level:
943
    if dev["iv_name"] is not None:
944
      txt = dev["iv_name"]
945
    else:
946
      txt = "disk %d" % idx
922 947
  else:
923
    data = "  - "
924
  data += "access mode: %s, " % dev["mode"]
925
  data += "type: %s" % dev["dev_type"]
948
    txt = "child %d" % idx
949
  d1 = ["- %s: %s" % (txt, dev["dev_type"])]
950
  data = []
951
  if top_level:
952
    data.append(("access mode", dev["mode"]))
926 953
  if dev["logical_id"] is not None:
927
    data += ", logical_id: %s" % (dev["logical_id"],)
954
    try:
955
      l_id = _FormatLogicalID(dev["dev_type"], dev["logical_id"])
956
    except ValueError:
957
      l_id = [str(dev["logical_id"])]
958
    if len(l_id) == 1:
959
      data.append(("logical_id", l_id[0]))
960
    else:
961
      data.extend(l_id)
928 962
  elif dev["physical_id"] is not None:
929
    data += ", physical_id: %s" % (dev["physical_id"],)
930
  buf.write("%*s%s\n" % (2*indent_level, "", data))
963
    data.append("physical_id:")
964
    data.append([dev["physical_id"]])
931 965
  if not static:
932
    buf.write("%*s    primary:   " % (2*indent_level, ""))
933
    helper(buf, dev["dev_type"], dev["pstatus"])
934

  
966
    data.append(("on primary", helper(dev["dev_type"], dev["pstatus"])))
935 967
  if dev["sstatus"] and not static:
936
    buf.write("%*s    secondary: " % (2*indent_level, ""))
937
    helper(buf, dev["dev_type"], dev["sstatus"])
968
    data.append(("on secondary", helper(dev["dev_type"], dev["sstatus"])))
938 969

  
939 970
  if dev["children"]:
940
    for child in dev["children"]:
941
      _FormatBlockDevInfo(buf, child, indent_level+1, static)
971
    data.append("child devices:")
972
    for c_idx, child in enumerate(dev["children"]):
973
      data.append(_FormatBlockDevInfo(c_idx, False, child, static))
974
  d1.append(data)
975
  return d1
942 976

  
943 977

  
978
def _FormatList(buf, data, indent_level):
979
  """Formats a list of data at a given indent level.
980

  
981
  If the element of the list is:
982
    - a string, it is simply formatted as is
983
    - a tuple, it will be split into key, value and the all the
984
      values in a list will be aligned all at the same start column
985
    - a list, will be recursively formatted
986

  
987
  @type buf: StringIO
988
  @param buf: the buffer into which we write the output
989
  @param data: the list to format
990
  @type indent_level: int
991
  @param indent_level: the indent level to format at
992

  
993
  """
994
  max_tlen = max([len(elem[0]) for elem in data
995
                 if isinstance(elem, tuple)] or [0])
996
  for elem in data:
997
    if isinstance(elem, basestring):
998
      buf.write("%*s%s\n" % (2*indent_level, "", elem))
999
    elif isinstance(elem, tuple):
1000
      key, value = elem
1001
      spacer = "%*s" % (max_tlen - len(key), "")
1002
      buf.write("%*s%s:%s %s\n" % (2*indent_level, "", key, spacer, value))
1003
    elif isinstance(elem, list):
1004
      _FormatList(buf, elem, indent_level+1)
1005

  
944 1006
def ShowInstanceConfig(opts, args):
945 1007
  """Compute instance run-time status.
946 1008

  
......
1022 1084
    for idx, (mac, ip, bridge) in enumerate(instance["nics"]):
1023 1085
      buf.write("      - nic/%d: MAC: %s, IP: %s, bridge: %s\n" %
1024 1086
                (idx, mac, ip, bridge))
1025
    buf.write("  Block devices:\n")
1087
    buf.write("  Disks:\n")
1026 1088

  
1027
    for device in instance["disks"]:
1028
      _FormatBlockDevInfo(buf, device, 1, opts.static)
1089
    for idx, device in enumerate(instance["disks"]):
1090
      _FormatList(buf, _FormatBlockDevInfo(idx, True, device, opts.static), 2)
1029 1091

  
1030 1092
  ToStdout(buf.getvalue().rstrip('\n'))
1031 1093
  return retcode

Also available in: Unified diff