Commit ec223efb authored by Iustin Pop's avatar Iustin Pop

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
parent a7ba5e53
...@@ -1129,7 +1129,7 @@ class LUQueryNodes(NoHooksLU): ...@@ -1129,7 +1129,7 @@ class LUQueryNodes(NoHooksLU):
"""Logical unit for querying nodes. """Logical unit for querying nodes.
""" """
_OP_REQP = ["output_fields"] _OP_REQP = ["output_fields", "nodes"]
def CheckPrereq(self): def CheckPrereq(self):
"""Check prerequisites. """Check prerequisites.
...@@ -1140,19 +1140,21 @@ class LUQueryNodes(NoHooksLU): ...@@ -1140,19 +1140,21 @@ class LUQueryNodes(NoHooksLU):
self.dynamic_fields = frozenset(["dtotal", "dfree", self.dynamic_fields = frozenset(["dtotal", "dfree",
"mtotal", "mnode", "mfree"]) "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, dynamic=self.dynamic_fields,
selected=self.op.output_fields) selected=self.op.output_fields)
self.wanted_nodes = _GetWantedNodes(self, self.op.nodes)
def Exec(self, feedback_fn): def Exec(self, feedback_fn):
"""Computes the list of nodes and their attributes. """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] nodelist = [self.cfg.GetNodeInfo(name) for name in nodenames]
# begin data gathering # begin data gathering
if self.dynamic_fields.intersection(self.op.output_fields): if self.dynamic_fields.intersection(self.op.output_fields):
...@@ -1173,17 +1175,21 @@ class LUQueryNodes(NoHooksLU): ...@@ -1173,17 +1175,21 @@ class LUQueryNodes(NoHooksLU):
else: else:
live_data = dict.fromkeys(nodenames, {}) live_data = dict.fromkeys(nodenames, {})
node_to_primary = dict.fromkeys(nodenames, 0) node_to_primary = dict([(name, set()) for name in nodenames])
node_to_secondary = dict.fromkeys(nodenames, 0) 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() instancelist = self.cfg.GetInstanceList()
for instance in instancelist: for instance_name in instancelist:
instanceinfo = self.cfg.GetInstanceInfo(instance) inst = self.cfg.GetInstanceInfo(instance_name)
node_to_primary[instanceinfo.primary_node] += 1 if inst.primary_node in node_to_primary:
for secnode in instanceinfo.secondary_nodes: node_to_primary[inst.primary_node].add(inst.name)
node_to_secondary[secnode] += 1 for secnode in inst.secondary_nodes:
if secnode in node_to_secondary:
node_to_secondary[secnode].add(inst.name)
# end data gathering # end data gathering
...@@ -1193,19 +1199,22 @@ class LUQueryNodes(NoHooksLU): ...@@ -1193,19 +1199,22 @@ class LUQueryNodes(NoHooksLU):
for field in self.op.output_fields: for field in self.op.output_fields:
if field == "name": if field == "name":
val = node.name val = node.name
elif field == "pinst": elif field == "pinst_list":
val = node_to_primary[node.name] val = list(node_to_primary[node.name])
elif field == "sinst": elif field == "sinst_list":
val = node_to_secondary[node.name] 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": elif field == "pip":
val = node.primary_ip val = node.primary_ip
elif field == "sip": elif field == "sip":
val = node.secondary_ip val = node.secondary_ip
elif field in self.dynamic_fields: elif field in self.dynamic_fields:
val = live_data[node.name].get(field, "?") val = live_data[node.name].get(field, None)
else: else:
raise errors.ParameterError(field) raise errors.ParameterError(field)
val = str(val)
node_output.append(val) node_output.append(val)
output.append(node_output) output.append(node_output)
......
...@@ -113,7 +113,7 @@ class OpAddNode(OpCode): ...@@ -113,7 +113,7 @@ class OpAddNode(OpCode):
class OpQueryNodes(OpCode): class OpQueryNodes(OpCode):
"""Compute the list of nodes.""" """Compute the list of nodes."""
OP_ID = "OP_NODE_QUERY" OP_ID = "OP_NODE_QUERY"
__slots__ = ["output_fields"] __slots__ = ["output_fields", "nodes"]
class OpQueryNodeData(OpCode): class OpQueryNodeData(OpCode):
......
...@@ -41,15 +41,16 @@ def ListNodes(opts, args): ...@@ -41,15 +41,16 @@ def ListNodes(opts, args):
if opts.output is None: if opts.output is None:
selected_fields = ["name", "dtotal", "dfree", selected_fields = ["name", "dtotal", "dfree",
"mtotal", "mnode", "mfree", "mtotal", "mnode", "mfree",
"pinst", "sinst"] "pinst_cnt", "sinst_cnt"]
else: else:
selected_fields = opts.output.split(",") selected_fields = opts.output.split(",")
op = opcodes.OpQueryNodes(output_fields=selected_fields) op = opcodes.OpQueryNodes(output_fields=selected_fields, nodes=[])
output = SubmitOpCode(op) output = SubmitOpCode(op)
if not opts.no_headers: 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", "pip": "PrimaryIP", "sip": "SecondaryIP",
"dtotal": "DTotal", "dfree": "DFree", "dtotal": "DTotal", "dfree": "DFree",
"mtotal": "MTotal", "mnode": "MNode", "mfree": "MFree"} "mtotal": "MTotal", "mnode": "MNode", "mfree": "MFree"}
...@@ -61,7 +62,21 @@ def ListNodes(opts, args): ...@@ -61,7 +62,21 @@ def ListNodes(opts, args):
else: else:
unitfields = None 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, data = GenerateTable(separator=opts.separator, headers=headers,
fields=selected_fields, unitfields=unitfields, fields=selected_fields, unitfields=unitfields,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment