From ec223efb51e42a4acf76dc25609c170ce9d147be Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Fri, 14 Sep 2007 09:02:56 +0000 Subject: [PATCH] Change LUQueryNodes to return raw values and support selective listing LUQueryNodes it's very similar to LUQueryNodeData, but it lacks two features: - instance list (it has count though), both primary and secondary - selective node listing In order to support these features, we change it to return raw values instead of stringified ones (like the recent change to LUQueryInstances) and to support query-ing of a restricted set of nodes. This CL also modifies the gnt-node script to conform to the new protocol and the opcode OpQueryNodes to support the new "nodes" attribute. Reviewed-by: imsnah --- lib/cmdlib.py | 45 +++++++++++++++++++++++++++------------------ lib/opcodes.py | 2 +- scripts/gnt-node | 23 +++++++++++++++++++---- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 9e16c68a0..a0669dbba 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -1129,7 +1129,7 @@ class LUQueryNodes(NoHooksLU): """Logical unit for querying nodes. """ - _OP_REQP = ["output_fields"] + _OP_REQP = ["output_fields", "nodes"] def CheckPrereq(self): """Check prerequisites. @@ -1140,19 +1140,21 @@ class LUQueryNodes(NoHooksLU): self.dynamic_fields = frozenset(["dtotal", "dfree", "mtotal", "mnode", "mfree"]) - _CheckOutputFields(static=["name", "pinst", "sinst", "pip", "sip"], + _CheckOutputFields(static=["name", "pinst_cnt", "sinst_cnt", + "pinst_list", "sinst_list", + "pip", "sip"], dynamic=self.dynamic_fields, selected=self.op.output_fields) + self.wanted_nodes = _GetWantedNodes(self, self.op.nodes) def Exec(self, feedback_fn): """Computes the list of nodes and their attributes. """ - nodenames = utils.NiceSort(self.cfg.GetNodeList()) + nodenames = self.wanted_nodes nodelist = [self.cfg.GetNodeInfo(name) for name in nodenames] - # begin data gathering if self.dynamic_fields.intersection(self.op.output_fields): @@ -1173,17 +1175,21 @@ class LUQueryNodes(NoHooksLU): else: live_data = dict.fromkeys(nodenames, {}) - node_to_primary = dict.fromkeys(nodenames, 0) - node_to_secondary = dict.fromkeys(nodenames, 0) + node_to_primary = dict([(name, set()) for name in nodenames]) + node_to_secondary = dict([(name, set()) for name in nodenames]) - if "pinst" in self.op.output_fields or "sinst" in self.op.output_fields: + inst_fields = frozenset(("pinst_cnt", "pinst_list", + "sinst_cnt", "sinst_list")) + if inst_fields & frozenset(self.op.output_fields): instancelist = self.cfg.GetInstanceList() - for instance in instancelist: - instanceinfo = self.cfg.GetInstanceInfo(instance) - node_to_primary[instanceinfo.primary_node] += 1 - for secnode in instanceinfo.secondary_nodes: - node_to_secondary[secnode] += 1 + for instance_name in instancelist: + inst = self.cfg.GetInstanceInfo(instance_name) + if inst.primary_node in node_to_primary: + node_to_primary[inst.primary_node].add(inst.name) + for secnode in inst.secondary_nodes: + if secnode in node_to_secondary: + node_to_secondary[secnode].add(inst.name) # end data gathering @@ -1193,19 +1199,22 @@ class LUQueryNodes(NoHooksLU): for field in self.op.output_fields: if field == "name": val = node.name - elif field == "pinst": - val = node_to_primary[node.name] - elif field == "sinst": - val = node_to_secondary[node.name] + elif field == "pinst_list": + val = list(node_to_primary[node.name]) + elif field == "sinst_list": + val = list(node_to_secondary[node.name]) + elif field == "pinst_cnt": + val = len(node_to_primary[node.name]) + elif field == "sinst_cnt": + val = len(node_to_secondary[node.name]) elif field == "pip": val = node.primary_ip elif field == "sip": val = node.secondary_ip elif field in self.dynamic_fields: - val = live_data[node.name].get(field, "?") + val = live_data[node.name].get(field, None) else: raise errors.ParameterError(field) - val = str(val) node_output.append(val) output.append(node_output) diff --git a/lib/opcodes.py b/lib/opcodes.py index 7f04f5017..e9a125b83 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -113,7 +113,7 @@ class OpAddNode(OpCode): class OpQueryNodes(OpCode): """Compute the list of nodes.""" OP_ID = "OP_NODE_QUERY" - __slots__ = ["output_fields"] + __slots__ = ["output_fields", "nodes"] class OpQueryNodeData(OpCode): diff --git a/scripts/gnt-node b/scripts/gnt-node index c4a43116c..9fbc10a0f 100755 --- a/scripts/gnt-node +++ b/scripts/gnt-node @@ -41,15 +41,16 @@ def ListNodes(opts, args): if opts.output is None: selected_fields = ["name", "dtotal", "dfree", "mtotal", "mnode", "mfree", - "pinst", "sinst"] + "pinst_cnt", "sinst_cnt"] else: selected_fields = opts.output.split(",") - op = opcodes.OpQueryNodes(output_fields=selected_fields) + op = opcodes.OpQueryNodes(output_fields=selected_fields, nodes=[]) output = SubmitOpCode(op) if not opts.no_headers: - headers = {"name": "Node", "pinst": "Pinst", "sinst": "Sinst", + headers = {"name": "Node", "pinst_cnt": "Pinst", "sinst_cnt": "Sinst", + "pinst_list": "PriInstances", "sinst_list": "SecInstances", "pip": "PrimaryIP", "sip": "SecondaryIP", "dtotal": "DTotal", "dfree": "DFree", "mtotal": "MTotal", "mnode": "MNode", "mfree": "MFree"} @@ -61,7 +62,21 @@ def ListNodes(opts, args): else: unitfields = None - numfields = ["dtotal", "dfree", "mtotal", "mnode", "mfree", "pinst", "sinst"] + numfields = ["dtotal", "dfree", + "mtotal", "mnode", "mfree", + "pinst_cnt", "sinst_cnt"] + + # change raw values to nicer strings + for row in output: + for idx, field in enumerate(selected_fields): + val = row[idx] + if field == "pinst_list": + val = ",".join(val) + elif field == "sinst_list": + val = ",".join(val) + elif val is None: + val = "?" + row[idx] = str(val) data = GenerateTable(separator=opts.separator, headers=headers, fields=selected_fields, unitfields=unitfields, -- GitLab