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 |
|