Revision 2cbcf95d lib/client/gnt_instance.py

b/lib/client/gnt_instance.py
29 29
import itertools
30 30
import simplejson
31 31
import logging
32
from cStringIO import StringIO
33 32

  
34 33
from ganeti.cli import *
35 34
from ganeti import opcodes
......
929 928
                                                            convert=roman))),
930 929
      ("nodeB", "%s, minor=%s" % (node_b, compat.TryToRoman(minor_b,
931 930
                                                            convert=roman))),
932
      ("port", compat.TryToRoman(port, convert=roman)),
933
      ("auth key", key),
931
      ("port", str(compat.TryToRoman(port, convert=roman))),
932
      ("auth key", str(key)),
934 933
      ]
935 934
  elif dev_type == constants.LD_LV:
936 935
    vg_name, lv_name = logical_id
......
941 940
  return data
942 941

  
943 942

  
943
def _FormatListInfo(data):
944
  return list(str(i) for i in data)
945

  
946

  
944 947
def _FormatBlockDevInfo(idx, top_level, dev, roman):
945 948
  """Show block device information.
946 949

  
......
1023 1026
  if isinstance(dev["size"], int):
1024 1027
    nice_size = utils.FormatUnit(dev["size"], "h")
1025 1028
  else:
1026
    nice_size = dev["size"]
1027
  d1 = ["- %s: %s, size %s" % (txt, dev["dev_type"], nice_size)]
1028
  data = []
1029
    nice_size = str(dev["size"])
1030
  data = [(txt, "%s, size %s" % (dev["dev_type"], nice_size))]
1029 1031
  if top_level:
1030 1032
    data.append(("access mode", dev["mode"]))
1031 1033
  if dev["logical_id"] is not None:
......
1038 1040
    else:
1039 1041
      data.extend(l_id)
1040 1042
  elif dev["physical_id"] is not None:
1041
    data.append("physical_id:")
1042
    data.append([dev["physical_id"]])
1043
    data.append(("physical_id:", _FormatListInfo(dev["physical_id"])))
1043 1044

  
1044 1045
  if dev["pstatus"]:
1045 1046
    data.append(("on primary", helper(dev["dev_type"], dev["pstatus"])))
......
1048 1049
    data.append(("on secondary", helper(dev["dev_type"], dev["sstatus"])))
1049 1050

  
1050 1051
  if dev["children"]:
1051
    data.append("child devices:")
1052
    for c_idx, child in enumerate(dev["children"]):
1053
      data.append(_FormatBlockDevInfo(c_idx, False, child, roman))
1054
  d1.append(data)
1055
  return d1
1056

  
1057

  
1058
def _FormatList(buf, data, indent_level):
1059
  """Formats a list of data at a given indent level.
1060

  
1061
  If the element of the list is:
1062
    - a string, it is simply formatted as is
1063
    - a tuple, it will be split into key, value and the all the
1064
      values in a list will be aligned all at the same start column
1065
    - a list, will be recursively formatted
1052
    data.append(("child devices", [
1053
      _FormatBlockDevInfo(c_idx, False, child, roman)
1054
      for c_idx, child in enumerate(dev["children"])
1055
      ]))
1056
  return data
1066 1057

  
1067
  @type buf: StringIO
1068
  @param buf: the buffer into which we write the output
1069
  @param data: the list to format
1070
  @type indent_level: int
1071
  @param indent_level: the indent level to format at
1072 1058

  
1073
  """
1074
  max_tlen = max([len(elem[0]) for elem in data
1075
                 if isinstance(elem, tuple)] or [0])
1076
  for elem in data:
1077
    if isinstance(elem, basestring):
1078
      buf.write("%*s%s\n" % (2 * indent_level, "", elem))
1079
    elif isinstance(elem, tuple):
1080
      key, value = elem
1081
      spacer = "%*s" % (max_tlen - len(key), "")
1082
      buf.write("%*s%s:%s %s\n" % (2 * indent_level, "", key, spacer, value))
1083
    elif isinstance(elem, list):
1084
      _FormatList(buf, elem, indent_level + 1)
1059
def _FormatInstanceNicInfo(idx, nic):
1060
  """Helper function for L{_FormatInstanceInfo()}"""
1061
  (ip, mac, mode, link, _, netinfo) = nic
1062
  network_name = None
1063
  if netinfo:
1064
    network_name = netinfo["name"]
1065
  return [
1066
    ("nic/%d" % idx, ""),
1067
    ("MAC", str(mac)),
1068
    ("IP", str(ip)),
1069
    ("mode", str(mode)),
1070
    ("link", str(link)),
1071
    ("network", str(network_name)),
1072
    ]
1073

  
1074

  
1075
def _FormatInstanceNodesInfo(instance):
1076
  """Helper function for L{_FormatInstanceInfo()}"""
1077
  pgroup = ("%s (UUID %s)" %
1078
            (instance["pnode_group_name"], instance["pnode_group_uuid"]))
1079
  secs = utils.CommaJoin(("%s (group %s, group UUID %s)" %
1080
                          (name, group_name, group_uuid))
1081
                         for (name, group_name, group_uuid) in
1082
                           zip(instance["snodes"],
1083
                               instance["snodes_group_names"],
1084
                               instance["snodes_group_uuids"]))
1085
  return [
1086
    [
1087
      ("primary", instance["pnode"]),
1088
      ("group", pgroup),
1089
      ],
1090
    [("secondaries", secs)],
1091
    ]
1092

  
1093

  
1094
def _GetVncConsoleInfo(instance):
1095
  """Helper function for L{_FormatInstanceInfo()}"""
1096
  vnc_bind_address = instance["hv_actual"].get(constants.HV_VNC_BIND_ADDRESS,
1097
                                               None)
1098
  if vnc_bind_address:
1099
    port = instance["network_port"]
1100
    display = int(port) - constants.VNC_BASE_PORT
1101
    if display > 0 and vnc_bind_address == constants.IP4_ADDRESS_ANY:
1102
      vnc_console_port = "%s:%s (display %s)" % (instance["pnode"],
1103
                                                 port,
1104
                                                 display)
1105
    elif display > 0 and netutils.IP4Address.IsValid(vnc_bind_address):
1106
      vnc_console_port = ("%s:%s (node %s) (display %s)" %
1107
                           (vnc_bind_address, port,
1108
                            instance["pnode"], display))
1109
    else:
1110
      # vnc bind address is a file
1111
      vnc_console_port = "%s:%s" % (instance["pnode"],
1112
                                    vnc_bind_address)
1113
    ret = "vnc to %s" % vnc_console_port
1114
  else:
1115
    ret = None
1116
  return ret
1117

  
1118

  
1119
def _FormatInstanceInfo(instance, roman_integers):
1120
  """Format instance information for L{cli.PrintGenericInfo()}"""
1121
  istate = "configured to be %s" % instance["config_state"]
1122
  if instance["run_state"]:
1123
    istate += ", actual state is %s" % instance["run_state"]
1124
  info = [
1125
    ("Instance name", instance["name"]),
1126
    ("UUID", instance["uuid"]),
1127
    ("Serial number",
1128
     str(compat.TryToRoman(instance["serial_no"], convert=roman_integers))),
1129
    ("Creation time", utils.FormatTime(instance["ctime"])),
1130
    ("Modification time", utils.FormatTime(instance["mtime"])),
1131
    ("State", istate),
1132
    ("Nodes", _FormatInstanceNodesInfo(instance)),
1133
    ("Operating system", instance["os"]),
1134
    ("Operating system parameters",
1135
     FormatParamsDictInfo(instance["os_instance"], instance["os_actual"])),
1136
    ]
1137

  
1138
  if "network_port" in instance:
1139
    info.append(("Allocated network port",
1140
                 str(compat.TryToRoman(instance["network_port"],
1141
                                       convert=roman_integers))))
1142
  info.append(("Hypervisor", instance["hypervisor"]))
1143
  console = _GetVncConsoleInfo(instance)
1144
  if console:
1145
    info.append(("console connection", console))
1146
  # deprecated "memory" value, kept for one version for compatibility
1147
  # TODO(ganeti 2.7) remove.
1148
  be_actual = copy.deepcopy(instance["be_actual"])
1149
  be_actual["memory"] = be_actual[constants.BE_MAXMEM]
1150
  info.extend([
1151
    ("Hypervisor parameters",
1152
     FormatParamsDictInfo(instance["hv_instance"], instance["hv_actual"])),
1153
    ("Back-end parameters",
1154
     FormatParamsDictInfo(instance["be_instance"], be_actual)),
1155
    ("NICs", [
1156
      _FormatInstanceNicInfo(idx, nic)
1157
      for (idx, nic) in enumerate(instance["nics"])
1158
      ]),
1159
    ("Disk template", instance["disk_template"]),
1160
    ("Disks", [
1161
      _FormatBlockDevInfo(idx, True, device, roman_integers)
1162
      for (idx, device) in enumerate(instance["disks"])
1163
      ]),
1164
    ])
1165
  return info
1085 1166

  
1086 1167

  
1087 1168
def ShowInstanceConfig(opts, args):
......
1112 1193
    ToStdout("No instances.")
1113 1194
    return 1
1114 1195

  
1115
  buf = StringIO()
1116
  retcode = 0
1117
  for instance_name in result:
1118
    instance = result[instance_name]
1119
    buf.write("Instance name: %s\n" % instance["name"])
1120
    buf.write("UUID: %s\n" % instance["uuid"])
1121
    buf.write("Serial number: %s\n" %
1122
              compat.TryToRoman(instance["serial_no"],
1123
                                convert=opts.roman_integers))
1124
    buf.write("Creation time: %s\n" % utils.FormatTime(instance["ctime"]))
1125
    buf.write("Modification time: %s\n" % utils.FormatTime(instance["mtime"]))
1126
    buf.write("State: configured to be %s" % instance["config_state"])
1127
    if instance["run_state"]:
1128
      buf.write(", actual state is %s" % instance["run_state"])
1129
    buf.write("\n")
1130
    ##buf.write("Considered for memory checks in cluster verify: %s\n" %
1131
    ##          instance["auto_balance"])
1132
    buf.write("  Nodes:\n")
1133
    buf.write("    - primary: %s\n" % instance["pnode"])
1134
    buf.write("      group: %s (UUID %s)\n" %
1135
              (instance["pnode_group_name"], instance["pnode_group_uuid"]))
1136
    buf.write("    - secondaries: %s\n" %
1137
              utils.CommaJoin("%s (group %s, group UUID %s)" %
1138
                                (name, group_name, group_uuid)
1139
                              for (name, group_name, group_uuid) in
1140
                                zip(instance["snodes"],
1141
                                    instance["snodes_group_names"],
1142
                                    instance["snodes_group_uuids"])))
1143
    buf.write("  Operating system: %s\n" % instance["os"])
1144
    FormatParameterDict(buf, instance["os_instance"], instance["os_actual"],
1145
                        level=2)
1146
    if "network_port" in instance:
1147
      buf.write("  Allocated network port: %s\n" %
1148
                compat.TryToRoman(instance["network_port"],
1149
                                  convert=opts.roman_integers))
1150
    buf.write("  Hypervisor: %s\n" % instance["hypervisor"])
1151

  
1152
    # custom VNC console information
1153
    vnc_bind_address = instance["hv_actual"].get(constants.HV_VNC_BIND_ADDRESS,
1154
                                                 None)
1155
    if vnc_bind_address:
1156
      port = instance["network_port"]
1157
      display = int(port) - constants.VNC_BASE_PORT
1158
      if display > 0 and vnc_bind_address == constants.IP4_ADDRESS_ANY:
1159
        vnc_console_port = "%s:%s (display %s)" % (instance["pnode"],
1160
                                                   port,
1161
                                                   display)
1162
      elif display > 0 and netutils.IP4Address.IsValid(vnc_bind_address):
1163
        vnc_console_port = ("%s:%s (node %s) (display %s)" %
1164
                             (vnc_bind_address, port,
1165
                              instance["pnode"], display))
1166
      else:
1167
        # vnc bind address is a file
1168
        vnc_console_port = "%s:%s" % (instance["pnode"],
1169
                                      vnc_bind_address)
1170
      buf.write("    - console connection: vnc to %s\n" % vnc_console_port)
1171

  
1172
    FormatParameterDict(buf, instance["hv_instance"], instance["hv_actual"],
1173
                        level=2)
1174
    buf.write("  Hardware:\n")
1175
    # deprecated "memory" value, kept for one version for compatibility
1176
    # TODO(ganeti 2.7) remove.
1177
    be_actual = copy.deepcopy(instance["be_actual"])
1178
    be_actual["memory"] = be_actual[constants.BE_MAXMEM]
1179
    FormatParameterDict(buf, instance["be_instance"], be_actual, level=2)
1180
    # TODO(ganeti 2.7) rework the NICs as well
1181
    buf.write("    - NICs:\n")
1182
    for idx, (ip, mac, mode, link, _, netinfo) in enumerate(instance["nics"]):
1183
      network_name = None
1184
      if netinfo:
1185
        network_name = netinfo["name"]
1186
      buf.write("      - nic/%d: MAC: %s, IP: %s,"
1187
                " mode: %s, link: %s, network: %s\n" %
1188
                (idx, mac, ip, mode, link, network_name))
1189
    buf.write("  Disk template: %s\n" % instance["disk_template"])
1190
    buf.write("  Disks:\n")
1191

  
1192
    for idx, device in enumerate(instance["disks"]):
1193
      _FormatList(buf, _FormatBlockDevInfo(idx, True, device,
1194
                  opts.roman_integers), 2)
1195

  
1196
  ToStdout(buf.getvalue().rstrip("\n"))
1196
  PrintGenericInfo([
1197
    _FormatInstanceInfo(instance, opts.roman_integers)
1198
    for instance in result.values()
1199
    ])
1197 1200
  return retcode
1198 1201

  
1199 1202

  

Also available in: Unified diff