35 |
35 |
- Human-readable description, must not end with punctuation or
|
36 |
36 |
contain newlines
|
37 |
37 |
- Data request type, see e.g. C{NQ_*}
|
|
38 |
- OR-ed flags, see C{QFF_*}
|
38 |
39 |
- A retrieval function, see L{Query.__init__} for description
|
39 |
40 |
- Pass list of fields through L{_PrepareFieldList} for preparation and
|
40 |
41 |
checks
|
... | ... | |
92 |
93 |
GQ_NODE,
|
93 |
94 |
GQ_INST) = range(200, 203)
|
94 |
95 |
|
|
96 |
# Query field flags
|
|
97 |
QFF_HOSTNAME = 0x01
|
|
98 |
QFF_IP_ADDRESS = 0x02
|
|
99 |
# Next values: 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200
|
|
100 |
QFF_ALL = (QFF_HOSTNAME | QFF_IP_ADDRESS)
|
95 |
101 |
|
96 |
102 |
FIELD_NAME_RE = re.compile(r"^[a-z0-9/._]+$")
|
97 |
103 |
TITLE_RE = re.compile(r"^[^\s]+$")
|
... | ... | |
152 |
158 |
fdef = fielddefs[name]
|
153 |
159 |
except KeyError:
|
154 |
160 |
fdef = (_MakeField(name, name, QFT_UNKNOWN, "Unknown field '%s'" % name),
|
155 |
|
None, _GetUnknownField)
|
|
161 |
None, 0, _GetUnknownField)
|
156 |
162 |
|
157 |
|
assert len(fdef) == 3
|
|
163 |
assert len(fdef) == 4
|
158 |
164 |
|
159 |
165 |
result.append(fdef)
|
160 |
166 |
|
... | ... | |
167 |
173 |
@rtype: list of L{objects.QueryFieldDefinition}
|
168 |
174 |
|
169 |
175 |
"""
|
170 |
|
return [fdef for (fdef, _, _) in fielddefs]
|
|
176 |
return [fdef for (fdef, _, _, _) in fielddefs]
|
171 |
177 |
|
172 |
178 |
|
173 |
179 |
class Query:
|
... | ... | |
199 |
205 |
|
200 |
206 |
"""
|
201 |
207 |
return frozenset(datakind
|
202 |
|
for (_, datakind, _) in self._fields
|
|
208 |
for (_, datakind, _, _) in self._fields
|
203 |
209 |
if datakind is not None)
|
204 |
210 |
|
205 |
211 |
def GetFields(self):
|
... | ... | |
219 |
225 |
support iteration using C{__iter__}
|
220 |
226 |
|
221 |
227 |
"""
|
222 |
|
result = [[_ProcessResult(fn(ctx, item)) for (_, _, fn) in self._fields]
|
|
228 |
result = [[_ProcessResult(fn(ctx, item)) for (_, _, _, fn) in self._fields]
|
223 |
229 |
for item in ctx]
|
224 |
230 |
|
225 |
231 |
# Verify result
|
... | ... | |
235 |
241 |
See L{Query.Query} for arguments.
|
236 |
242 |
|
237 |
243 |
"""
|
238 |
|
unknown = set(fdef.name
|
239 |
|
for (fdef, _, _) in self._fields if fdef.kind == QFT_UNKNOWN)
|
|
244 |
unknown = set(fdef.name for (fdef, _, _, _) in self._fields
|
|
245 |
if fdef.kind == QFT_UNKNOWN)
|
240 |
246 |
if unknown:
|
241 |
247 |
raise errors.OpPrereqError("Unknown output fields selected: %s" %
|
242 |
248 |
(utils.CommaJoin(unknown), ),
|
... | ... | |
273 |
279 |
"""
|
274 |
280 |
assert len(row) == len(fields)
|
275 |
281 |
errs = []
|
276 |
|
for ((status, value), (fdef, _, _)) in zip(row, fields):
|
|
282 |
for ((status, value), (fdef, _, _, _)) in zip(row, fields):
|
277 |
283 |
if status == RS_NORMAL:
|
278 |
284 |
if not _VERIFY_FN[fdef.kind](value):
|
279 |
285 |
errs.append("normal field %s fails validation (value is %s)" %
|
... | ... | |
302 |
308 |
"""
|
303 |
309 |
if __debug__:
|
304 |
310 |
duplicates = utils.FindDuplicates(fdef.title.lower()
|
305 |
|
for (fdef, _, _) in fields)
|
|
311 |
for (fdef, _, _, _) in fields)
|
306 |
312 |
assert not duplicates, "Duplicate title(s) found: %r" % duplicates
|
307 |
313 |
|
308 |
314 |
result = {}
|
309 |
315 |
|
310 |
316 |
for field in fields:
|
311 |
|
(fdef, _, fn) = field
|
|
317 |
(fdef, _, flags, fn) = field
|
312 |
318 |
|
313 |
319 |
assert fdef.name and fdef.title, "Name and title are required"
|
314 |
320 |
assert FIELD_NAME_RE.match(fdef.name)
|
... | ... | |
319 |
325 |
assert callable(fn)
|
320 |
326 |
assert fdef.name not in result, \
|
321 |
327 |
"Duplicate field name '%s' found" % fdef.name
|
|
328 |
assert (flags & ~QFF_ALL) == 0, "Unknown flags for field '%s'" % fdef.name
|
322 |
329 |
|
323 |
330 |
result[fdef.name] = field
|
324 |
331 |
|
325 |
332 |
for alias, target in aliases:
|
326 |
333 |
assert alias not in result, "Alias %s overrides an existing field" % alias
|
327 |
334 |
assert target in result, "Missing target %s for alias %s" % (target, alias)
|
328 |
|
(fdef, k, fn) = result[target]
|
|
335 |
(fdef, k, flags, fn) = result[target]
|
329 |
336 |
fdef = fdef.Copy()
|
330 |
337 |
fdef.name = alias
|
331 |
|
result[alias] = (fdef, k, fn)
|
|
338 |
result[alias] = (fdef, k, flags, fn)
|
332 |
339 |
|
333 |
340 |
assert len(result) == len(fields) + len(aliases)
|
334 |
341 |
assert compat.all(name == fdef.name
|
335 |
|
for (name, (fdef, _, _)) in result.items())
|
|
342 |
for (name, (fdef, _, _, _)) in result.items())
|
336 |
343 |
|
337 |
344 |
return result
|
338 |
345 |
|
... | ... | |
442 |
449 |
"""
|
443 |
450 |
return [
|
444 |
451 |
(_MakeField("ctime", "CTime", QFT_TIMESTAMP, "Creation timestamp"),
|
445 |
|
datatype, _GetItemTimestamp(operator.attrgetter("ctime"))),
|
|
452 |
datatype, 0, _GetItemTimestamp(operator.attrgetter("ctime"))),
|
446 |
453 |
(_MakeField("mtime", "MTime", QFT_TIMESTAMP, "Modification timestamp"),
|
447 |
|
datatype, _GetItemTimestamp(operator.attrgetter("mtime"))),
|
|
454 |
datatype, 0, _GetItemTimestamp(operator.attrgetter("mtime"))),
|
448 |
455 |
]
|
449 |
456 |
|
450 |
457 |
|
... | ... | |
486 |
493 |
|
487 |
494 |
#: Fields that are direct attributes of an L{objects.Node} object
|
488 |
495 |
_NODE_SIMPLE_FIELDS = {
|
489 |
|
"drained": ("Drained", QFT_BOOL, "Whether node is drained"),
|
490 |
|
"master_candidate": ("MasterC", QFT_BOOL,
|
|
496 |
"drained": ("Drained", QFT_BOOL, 0, "Whether node is drained"),
|
|
497 |
"master_candidate": ("MasterC", QFT_BOOL, 0,
|
491 |
498 |
"Whether node is a master candidate"),
|
492 |
|
"master_capable": ("MasterCapable", QFT_BOOL,
|
|
499 |
"master_capable": ("MasterCapable", QFT_BOOL, 0,
|
493 |
500 |
"Whether node can become a master candidate"),
|
494 |
|
"name": ("Node", QFT_TEXT, "Node name"),
|
495 |
|
"offline": ("Offline", QFT_BOOL, "Whether node is marked offline"),
|
496 |
|
"serial_no": ("SerialNo", QFT_NUMBER, _SERIAL_NO_DOC % "Node"),
|
497 |
|
"uuid": ("UUID", QFT_TEXT, "Node UUID"),
|
498 |
|
"vm_capable": ("VMCapable", QFT_BOOL, "Whether node can host instances"),
|
|
501 |
"name": ("Node", QFT_TEXT, QFF_HOSTNAME, "Node name"),
|
|
502 |
"offline": ("Offline", QFT_BOOL, 0, "Whether node is marked offline"),
|
|
503 |
"serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Node"),
|
|
504 |
"uuid": ("UUID", QFT_TEXT, 0, "Node UUID"),
|
|
505 |
"vm_capable": ("VMCapable", QFT_BOOL, 0, "Whether node can host instances"),
|
499 |
506 |
}
|
500 |
507 |
|
501 |
508 |
|
... | ... | |
632 |
639 |
"""
|
633 |
640 |
fields = [
|
634 |
641 |
(_MakeField("pip", "PrimaryIP", QFT_TEXT, "Primary IP address"),
|
635 |
|
NQ_CONFIG, _GetItemAttr("primary_ip")),
|
|
642 |
NQ_CONFIG, 0, _GetItemAttr("primary_ip")),
|
636 |
643 |
(_MakeField("sip", "SecondaryIP", QFT_TEXT, "Secondary IP address"),
|
637 |
|
NQ_CONFIG, _GetItemAttr("secondary_ip")),
|
638 |
|
(_MakeField("tags", "Tags", QFT_OTHER, "Tags"), NQ_CONFIG,
|
|
644 |
NQ_CONFIG, 0, _GetItemAttr("secondary_ip")),
|
|
645 |
(_MakeField("tags", "Tags", QFT_OTHER, "Tags"), NQ_CONFIG, 0,
|
639 |
646 |
lambda ctx, node: list(node.GetTags())),
|
640 |
647 |
(_MakeField("master", "IsMaster", QFT_BOOL, "Whether node is master"),
|
641 |
|
NQ_CONFIG, lambda ctx, node: node.name == ctx.master_name),
|
642 |
|
(_MakeField("group", "Group", QFT_TEXT, "Node group"), NQ_GROUP,
|
|
648 |
NQ_CONFIG, 0, lambda ctx, node: node.name == ctx.master_name),
|
|
649 |
(_MakeField("group", "Group", QFT_TEXT, "Node group"), NQ_GROUP, 0,
|
643 |
650 |
_GetGroup(_GetNodeGroup)),
|
644 |
651 |
(_MakeField("group.uuid", "GroupUUID", QFT_TEXT, "UUID of node group"),
|
645 |
|
NQ_CONFIG, _GetItemAttr("group")),
|
|
652 |
NQ_CONFIG, 0, _GetItemAttr("group")),
|
646 |
653 |
(_MakeField("powered", "Powered", QFT_BOOL,
|
647 |
654 |
"Whether node is thought to be powered on"),
|
648 |
|
NQ_OOB, _GetNodePower),
|
|
655 |
NQ_OOB, 0, _GetNodePower),
|
649 |
656 |
(_MakeField("ndparams", "NodeParameters", QFT_OTHER,
|
650 |
657 |
"Merged node parameters"),
|
651 |
|
NQ_GROUP, _GetGroup(_GetNdParams)),
|
|
658 |
NQ_GROUP, 0, _GetGroup(_GetNdParams)),
|
652 |
659 |
(_MakeField("custom_ndparams", "CustomNodeParameters", QFT_OTHER,
|
653 |
660 |
"Custom node parameters"),
|
654 |
|
NQ_GROUP, _GetItemAttr("ndparams")),
|
|
661 |
NQ_GROUP, 0, _GetItemAttr("ndparams")),
|
655 |
662 |
]
|
656 |
663 |
|
657 |
664 |
# Node role
|
... | ... | |
661 |
668 |
role_doc = ("Node role; \"%s\" for master, \"%s\" for master candidate,"
|
662 |
669 |
" \"%s\" for regular, \"%s\" for a drained, \"%s\" for offline" %
|
663 |
670 |
role_values)
|
664 |
|
fields.append((_MakeField("role", "Role", QFT_TEXT, role_doc), NQ_CONFIG,
|
|
671 |
fields.append((_MakeField("role", "Role", QFT_TEXT, role_doc), NQ_CONFIG, 0,
|
665 |
672 |
lambda ctx, node: _GetNodeRole(node, ctx.master_name)))
|
666 |
673 |
assert set(role_values) == constants.NR_ALL
|
667 |
674 |
|
... | ... | |
675 |
682 |
for prefix, titleprefix, docword, getter in \
|
676 |
683 |
[("p", "Pri", "primary", operator.attrgetter("node_to_primary")),
|
677 |
684 |
("s", "Sec", "secondary", operator.attrgetter("node_to_secondary"))]:
|
|
685 |
# TODO: Allow filterting by hostname in list
|
678 |
686 |
fields.extend([
|
679 |
687 |
(_MakeField("%sinst_cnt" % prefix, "%sinst" % prefix.upper(), QFT_NUMBER,
|
680 |
688 |
"Number of instances with this node as %s" % docword),
|
681 |
|
NQ_INST, _GetLength(getter)),
|
|
689 |
NQ_INST, 0, _GetLength(getter)),
|
682 |
690 |
(_MakeField("%sinst_list" % prefix, "%sInstances" % titleprefix,
|
683 |
691 |
QFT_OTHER,
|
684 |
692 |
"List of instances with this node as %s" % docword),
|
685 |
|
NQ_INST, _GetList(getter)),
|
|
693 |
NQ_INST, 0, _GetList(getter)),
|
686 |
694 |
])
|
687 |
695 |
|
688 |
696 |
# Add simple fields
|
689 |
|
fields.extend([(_MakeField(name, title, kind, doc), NQ_CONFIG,
|
690 |
|
_GetItemAttr(name))
|
691 |
|
for (name, (title, kind, doc)) in _NODE_SIMPLE_FIELDS.items()])
|
|
697 |
fields.extend([
|
|
698 |
(_MakeField(name, title, kind, doc), NQ_CONFIG, flags, _GetItemAttr(name))
|
|
699 |
for (name, (title, kind, flags, doc)) in _NODE_SIMPLE_FIELDS.items()
|
|
700 |
])
|
692 |
701 |
|
693 |
702 |
# Add fields requiring live data
|
694 |
703 |
fields.extend([
|
695 |
|
(_MakeField(name, title, kind, doc), NQ_LIVE,
|
|
704 |
(_MakeField(name, title, kind, doc), NQ_LIVE, 0,
|
696 |
705 |
compat.partial(_GetLiveNodeField, nfield, kind))
|
697 |
706 |
for (name, (title, kind, nfield, doc)) in _NODE_LIVE_FIELDS.items()
|
698 |
707 |
])
|
... | ... | |
979 |
988 |
# All NICs
|
980 |
989 |
(_MakeField("nic.count", "NICs", QFT_NUMBER,
|
981 |
990 |
"Number of network interfaces"),
|
982 |
|
IQ_CONFIG, lambda ctx, inst: len(inst.nics)),
|
|
991 |
IQ_CONFIG, 0, lambda ctx, inst: len(inst.nics)),
|
983 |
992 |
(_MakeField("nic.macs", "NIC_MACs", QFT_OTHER,
|
984 |
993 |
"List containing each network interface's MAC address"),
|
985 |
|
IQ_CONFIG, lambda ctx, inst: [nic.mac for nic in inst.nics]),
|
|
994 |
IQ_CONFIG, 0, lambda ctx, inst: [nic.mac for nic in inst.nics]),
|
986 |
995 |
(_MakeField("nic.ips", "NIC_IPs", QFT_OTHER,
|
987 |
996 |
"List containing each network interface's IP address"),
|
988 |
|
IQ_CONFIG, lambda ctx, inst: [nic.ip for nic in inst.nics]),
|
|
997 |
IQ_CONFIG, 0, lambda ctx, inst: [nic.ip for nic in inst.nics]),
|
989 |
998 |
(_MakeField("nic.modes", "NIC_modes", QFT_OTHER,
|
990 |
|
"List containing each network interface's mode"), IQ_CONFIG,
|
|
999 |
"List containing each network interface's mode"), IQ_CONFIG, 0,
|
991 |
1000 |
lambda ctx, inst: [nicp[constants.NIC_MODE]
|
992 |
1001 |
for nicp in ctx.inst_nicparams]),
|
993 |
1002 |
(_MakeField("nic.links", "NIC_links", QFT_OTHER,
|
994 |
|
"List containing each network interface's link"), IQ_CONFIG,
|
|
1003 |
"List containing each network interface's link"), IQ_CONFIG, 0,
|
995 |
1004 |
lambda ctx, inst: [nicp[constants.NIC_LINK]
|
996 |
1005 |
for nicp in ctx.inst_nicparams]),
|
997 |
1006 |
(_MakeField("nic.bridges", "NIC_bridges", QFT_OTHER,
|
998 |
|
"List containing each network interface's bridge"), IQ_CONFIG,
|
999 |
|
_GetInstAllNicBridges),
|
|
1007 |
"List containing each network interface's bridge"),
|
|
1008 |
IQ_CONFIG, 0, _GetInstAllNicBridges),
|
1000 |
1009 |
]
|
1001 |
1010 |
|
1002 |
1011 |
# NICs by number
|
... | ... | |
1005 |
1014 |
fields.extend([
|
1006 |
1015 |
(_MakeField("nic.ip/%s" % i, "NicIP/%s" % i, QFT_TEXT,
|
1007 |
1016 |
"IP address of %s network interface" % numtext),
|
1008 |
|
IQ_CONFIG, _GetInstNic(i, _GetInstNicIp)),
|
|
1017 |
IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicIp)),
|
1009 |
1018 |
(_MakeField("nic.mac/%s" % i, "NicMAC/%s" % i, QFT_TEXT,
|
1010 |
1019 |
"MAC address of %s network interface" % numtext),
|
1011 |
|
IQ_CONFIG, _GetInstNic(i, nic_mac_fn)),
|
|
1020 |
IQ_CONFIG, 0, _GetInstNic(i, nic_mac_fn)),
|
1012 |
1021 |
(_MakeField("nic.mode/%s" % i, "NicMode/%s" % i, QFT_TEXT,
|
1013 |
1022 |
"Mode of %s network interface" % numtext),
|
1014 |
|
IQ_CONFIG, _GetInstNic(i, nic_mode_fn)),
|
|
1023 |
IQ_CONFIG, 0, _GetInstNic(i, nic_mode_fn)),
|
1015 |
1024 |
(_MakeField("nic.link/%s" % i, "NicLink/%s" % i, QFT_TEXT,
|
1016 |
1025 |
"Link of %s network interface" % numtext),
|
1017 |
|
IQ_CONFIG, _GetInstNic(i, nic_link_fn)),
|
|
1026 |
IQ_CONFIG, 0, _GetInstNic(i, nic_link_fn)),
|
1018 |
1027 |
(_MakeField("nic.bridge/%s" % i, "NicBridge/%s" % i, QFT_TEXT,
|
1019 |
1028 |
"Bridge of %s network interface" % numtext),
|
1020 |
|
IQ_CONFIG, _GetInstNic(i, _GetInstNicBridge)),
|
|
1029 |
IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicBridge)),
|
1021 |
1030 |
])
|
1022 |
1031 |
|
1023 |
1032 |
aliases = [
|
... | ... | |
1075 |
1084 |
"Total disk space used by instance on each of its nodes;"
|
1076 |
1085 |
" this is not the disk size visible to the instance, but"
|
1077 |
1086 |
" the usage on the node"),
|
1078 |
|
IQ_DISKUSAGE, _GetInstDiskUsage),
|
|
1087 |
IQ_DISKUSAGE, 0, _GetInstDiskUsage),
|
1079 |
1088 |
(_MakeField("disk.count", "Disks", QFT_NUMBER, "Number of disks"),
|
1080 |
|
IQ_CONFIG, lambda ctx, inst: len(inst.disks)),
|
|
1089 |
IQ_CONFIG, 0, lambda ctx, inst: len(inst.disks)),
|
1081 |
1090 |
(_MakeField("disk.sizes", "Disk_sizes", QFT_OTHER, "List of disk sizes"),
|
1082 |
|
IQ_CONFIG, lambda ctx, inst: [disk.size for disk in inst.disks]),
|
|
1091 |
IQ_CONFIG, 0, lambda ctx, inst: [disk.size for disk in inst.disks]),
|
1083 |
1092 |
]
|
1084 |
1093 |
|
1085 |
1094 |
# Disks by number
|
1086 |
1095 |
fields.extend([
|
1087 |
1096 |
(_MakeField("disk.size/%s" % i, "Disk/%s" % i, QFT_UNIT,
|
1088 |
1097 |
"Disk size of %s disk" % utils.FormatOrdinal(i + 1)),
|
1089 |
|
IQ_CONFIG, _GetInstDiskSize(i))
|
|
1098 |
IQ_CONFIG, 0, _GetInstDiskSize(i))
|
1090 |
1099 |
for i in range(constants.MAX_DISKS)
|
1091 |
1100 |
])
|
1092 |
1101 |
|
... | ... | |
1122 |
1131 |
# Filled parameters
|
1123 |
1132 |
(_MakeField("hvparams", "HypervisorParameters", QFT_OTHER,
|
1124 |
1133 |
"Hypervisor parameters"),
|
1125 |
|
IQ_CONFIG, lambda ctx, _: ctx.inst_hvparams),
|
|
1134 |
IQ_CONFIG, 0, lambda ctx, _: ctx.inst_hvparams),
|
1126 |
1135 |
(_MakeField("beparams", "BackendParameters", QFT_OTHER,
|
1127 |
1136 |
"Backend parameters"),
|
1128 |
|
IQ_CONFIG, lambda ctx, _: ctx.inst_beparams),
|
|
1137 |
IQ_CONFIG, 0, lambda ctx, _: ctx.inst_beparams),
|
1129 |
1138 |
|
1130 |
1139 |
# Unfilled parameters
|
1131 |
1140 |
(_MakeField("custom_hvparams", "CustomHypervisorParameters", QFT_OTHER,
|
1132 |
1141 |
"Custom hypervisor parameters"),
|
1133 |
|
IQ_CONFIG, _GetItemAttr("hvparams")),
|
|
1142 |
IQ_CONFIG, 0, _GetItemAttr("hvparams")),
|
1134 |
1143 |
(_MakeField("custom_beparams", "CustomBackendParameters", QFT_OTHER,
|
1135 |
1144 |
"Custom backend parameters",),
|
1136 |
|
IQ_CONFIG, _GetItemAttr("beparams")),
|
|
1145 |
IQ_CONFIG, 0, _GetItemAttr("beparams")),
|
1137 |
1146 |
(_MakeField("custom_nicparams", "CustomNicParameters", QFT_OTHER,
|
1138 |
1147 |
"Custom network interface parameters"),
|
1139 |
|
IQ_CONFIG, lambda ctx, inst: [nic.nicparams for nic in inst.nics]),
|
|
1148 |
IQ_CONFIG, 0, lambda ctx, inst: [nic.nicparams for nic in inst.nics]),
|
1140 |
1149 |
]
|
1141 |
1150 |
|
1142 |
1151 |
# HV params
|
... | ... | |
1146 |
1155 |
fields.extend([
|
1147 |
1156 |
(_MakeField("hv/%s" % name, hv_title.get(name, "hv/%s" % name),
|
1148 |
1157 |
_VTToQFT[kind], "The \"%s\" hypervisor parameter" % name),
|
1149 |
|
IQ_CONFIG, _GetInstHvParam(name))
|
|
1158 |
IQ_CONFIG, 0, _GetInstHvParam(name))
|
1150 |
1159 |
for name, kind in constants.HVS_PARAMETER_TYPES.items()
|
1151 |
1160 |
if name not in constants.HVC_GLOBALS
|
1152 |
1161 |
])
|
... | ... | |
1158 |
1167 |
fields.extend([
|
1159 |
1168 |
(_MakeField("be/%s" % name, be_title.get(name, "be/%s" % name),
|
1160 |
1169 |
_VTToQFT[kind], "The \"%s\" backend parameter" % name),
|
1161 |
|
IQ_CONFIG, _GetInstBeParam(name))
|
|
1170 |
IQ_CONFIG, 0, _GetInstBeParam(name))
|
1162 |
1171 |
for name, kind in constants.BES_PARAMETER_TYPES.items()
|
1163 |
1172 |
])
|
1164 |
1173 |
|
... | ... | |
1166 |
1175 |
|
1167 |
1176 |
|
1168 |
1177 |
_INST_SIMPLE_FIELDS = {
|
1169 |
|
"disk_template": ("Disk_template", QFT_TEXT, "Instance disk template"),
|
1170 |
|
"hypervisor": ("Hypervisor", QFT_TEXT, "Hypervisor name"),
|
1171 |
|
"name": ("Instance", QFT_TEXT, "Instance name"),
|
|
1178 |
"disk_template": ("Disk_template", QFT_TEXT, 0, "Instance disk template"),
|
|
1179 |
"hypervisor": ("Hypervisor", QFT_TEXT, 0, "Hypervisor name"),
|
|
1180 |
"name": ("Instance", QFT_TEXT, QFF_HOSTNAME, "Instance name"),
|
1172 |
1181 |
# Depending on the hypervisor, the port can be None
|
1173 |
|
"network_port": ("Network_port", QFT_OTHER,
|
|
1182 |
"network_port": ("Network_port", QFT_OTHER, 0,
|
1174 |
1183 |
"Instance network port if available (e.g. for VNC console)"),
|
1175 |
|
"os": ("OS", QFT_TEXT, "Operating system"),
|
1176 |
|
"serial_no": ("SerialNo", QFT_NUMBER, _SERIAL_NO_DOC % "Instance"),
|
1177 |
|
"uuid": ("UUID", QFT_TEXT, "Instance UUID"),
|
|
1184 |
"os": ("OS", QFT_TEXT, 0, "Operating system"),
|
|
1185 |
"serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Instance"),
|
|
1186 |
"uuid": ("UUID", QFT_TEXT, 0, "Instance UUID"),
|
1178 |
1187 |
}
|
1179 |
1188 |
|
1180 |
1189 |
|
... | ... | |
1183 |
1192 |
|
1184 |
1193 |
"""
|
1185 |
1194 |
fields = [
|
1186 |
|
(_MakeField("pnode", "Primary_node", QFT_TEXT, "Primary node"), IQ_CONFIG,
|
1187 |
|
_GetItemAttr("primary_node")),
|
|
1195 |
(_MakeField("pnode", "Primary_node", QFT_TEXT, "Primary node"),
|
|
1196 |
IQ_CONFIG, QFF_HOSTNAME, _GetItemAttr("primary_node")),
|
|
1197 |
# TODO: Allow filtering by secondary node as hostname
|
1188 |
1198 |
(_MakeField("snodes", "Secondary_Nodes", QFT_OTHER,
|
1189 |
1199 |
"Secondary nodes; usually this will just be one node"),
|
1190 |
|
IQ_CONFIG, lambda ctx, inst: list(inst.secondary_nodes)),
|
|
1200 |
IQ_CONFIG, 0, lambda ctx, inst: list(inst.secondary_nodes)),
|
1191 |
1201 |
(_MakeField("admin_state", "Autostart", QFT_BOOL,
|
1192 |
1202 |
"Desired state of instance (if set, the instance should be"
|
1193 |
1203 |
" up)"),
|
1194 |
|
IQ_CONFIG, _GetItemAttr("admin_up")),
|
1195 |
|
(_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG,
|
|
1204 |
IQ_CONFIG, 0, _GetItemAttr("admin_up")),
|
|
1205 |
(_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG, 0,
|
1196 |
1206 |
lambda ctx, inst: list(inst.GetTags())),
|
1197 |
1207 |
(_MakeField("console", "Console", QFT_OTHER,
|
1198 |
|
"Instance console information"), IQ_CONSOLE,
|
|
1208 |
"Instance console information"), IQ_CONSOLE, 0,
|
1199 |
1209 |
_GetInstanceConsole),
|
1200 |
1210 |
]
|
1201 |
1211 |
|
1202 |
1212 |
# Add simple fields
|
1203 |
|
fields.extend([(_MakeField(name, title, kind, doc),
|
1204 |
|
IQ_CONFIG, _GetItemAttr(name))
|
1205 |
|
for (name, (title, kind, doc)) in _INST_SIMPLE_FIELDS.items()])
|
|
1213 |
fields.extend([
|
|
1214 |
(_MakeField(name, title, kind, doc), IQ_CONFIG, flags, _GetItemAttr(name))
|
|
1215 |
for (name, (title, kind, flags, doc)) in _INST_SIMPLE_FIELDS.items()
|
|
1216 |
])
|
1206 |
1217 |
|
1207 |
1218 |
# Fields requiring talking to the node
|
1208 |
1219 |
fields.extend([
|
1209 |
1220 |
(_MakeField("oper_state", "Running", QFT_BOOL, "Actual state of instance"),
|
1210 |
|
IQ_LIVE, _GetInstOperState),
|
|
1221 |
IQ_LIVE, 0, _GetInstOperState),
|
1211 |
1222 |
(_MakeField("oper_ram", "Memory", QFT_UNIT,
|
1212 |
1223 |
"Actual memory usage as seen by hypervisor"),
|
1213 |
|
IQ_LIVE, _GetInstLiveData("memory")),
|
|
1224 |
IQ_LIVE, 0, _GetInstLiveData("memory")),
|
1214 |
1225 |
(_MakeField("oper_vcpus", "VCPUs", QFT_NUMBER,
|
1215 |
1226 |
"Actual number of VCPUs as seen by hypervisor"),
|
1216 |
|
IQ_LIVE, _GetInstLiveData("vcpus")),
|
|
1227 |
IQ_LIVE, 0, _GetInstLiveData("vcpus")),
|
1217 |
1228 |
])
|
1218 |
1229 |
|
1219 |
1230 |
# Status field
|
... | ... | |
1230 |
1241 |
" \"%s\" if instance's primary node is marked offline" %
|
1231 |
1242 |
status_values)
|
1232 |
1243 |
fields.append((_MakeField("status", "Status", QFT_TEXT, status_doc),
|
1233 |
|
IQ_LIVE, _GetInstStatus))
|
|
1244 |
IQ_LIVE, 0, _GetInstStatus))
|
1234 |
1245 |
assert set(status_values) == constants.INSTST_ALL, \
|
1235 |
1246 |
"Status documentation mismatch"
|
1236 |
1247 |
|
... | ... | |
1297 |
1308 |
|
1298 |
1309 |
"""
|
1299 |
1310 |
return _PrepareFieldList([
|
1300 |
|
(_MakeField("name", "Name", QFT_TEXT, "Lock name"), None,
|
|
1311 |
# TODO: Lock names are not always hostnames. Should QFF_HOSTNAME be used?
|
|
1312 |
(_MakeField("name", "Name", QFT_TEXT, "Lock name"), None, 0,
|
1301 |
1313 |
lambda ctx, (name, mode, owners, pending): name),
|
1302 |
1314 |
(_MakeField("mode", "Mode", QFT_OTHER,
|
1303 |
1315 |
"Mode in which the lock is currently acquired"
|
1304 |
1316 |
" (exclusive or shared)"),
|
1305 |
|
LQ_MODE, lambda ctx, (name, mode, owners, pending): mode),
|
|
1317 |
LQ_MODE, 0, lambda ctx, (name, mode, owners, pending): mode),
|
1306 |
1318 |
(_MakeField("owner", "Owner", QFT_OTHER, "Current lock owner(s)"),
|
1307 |
|
LQ_OWNER, _GetLockOwners),
|
|
1319 |
LQ_OWNER, 0, _GetLockOwners),
|
1308 |
1320 |
(_MakeField("pending", "Pending", QFT_OTHER,
|
1309 |
1321 |
"Threads waiting for the lock"),
|
1310 |
|
LQ_PENDING, _GetLockPending),
|
|
1322 |
LQ_PENDING, 0, _GetLockPending),
|
1311 |
1323 |
], [])
|
1312 |
1324 |
|
1313 |
1325 |
|
... | ... | |
1350 |
1362 |
|
1351 |
1363 |
"""
|
1352 |
1364 |
# Add simple fields
|
1353 |
|
fields = [(_MakeField(name, title, kind, doc), GQ_CONFIG, _GetItemAttr(name))
|
|
1365 |
fields = [(_MakeField(name, title, kind, doc), GQ_CONFIG, 0,
|
|
1366 |
_GetItemAttr(name))
|
1354 |
1367 |
for (name, (title, kind, doc)) in _GROUP_SIMPLE_FIELDS.items()]
|
1355 |
1368 |
|
1356 |
1369 |
def _GetLength(getter):
|
... | ... | |
1365 |
1378 |
# Add fields for nodes
|
1366 |
1379 |
fields.extend([
|
1367 |
1380 |
(_MakeField("node_cnt", "Nodes", QFT_NUMBER, "Number of nodes"),
|
1368 |
|
GQ_NODE, _GetLength(group_to_nodes)),
|
|
1381 |
GQ_NODE, 0, _GetLength(group_to_nodes)),
|
1369 |
1382 |
(_MakeField("node_list", "NodeList", QFT_OTHER, "List of nodes"),
|
1370 |
|
GQ_NODE, _GetSortedList(group_to_nodes)),
|
|
1383 |
GQ_NODE, 0, _GetSortedList(group_to_nodes)),
|
1371 |
1384 |
])
|
1372 |
1385 |
|
1373 |
1386 |
# Add fields for instances
|
1374 |
1387 |
fields.extend([
|
1375 |
1388 |
(_MakeField("pinst_cnt", "Instances", QFT_NUMBER,
|
1376 |
1389 |
"Number of primary instances"),
|
1377 |
|
GQ_INST, _GetLength(group_to_instances)),
|
|
1390 |
GQ_INST, 0, _GetLength(group_to_instances)),
|
1378 |
1391 |
(_MakeField("pinst_list", "InstanceList", QFT_OTHER,
|
1379 |
1392 |
"List of primary instances"),
|
1380 |
|
GQ_INST, _GetSortedList(group_to_instances)),
|
|
1393 |
GQ_INST, 0, _GetSortedList(group_to_instances)),
|
1381 |
1394 |
])
|
1382 |
1395 |
|
1383 |
1396 |
fields.extend(_GetItemTimestampFields(GQ_CONFIG))
|