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
  - 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):
"""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"],
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):
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:
for secnode in inst.secondary_nodes:
if secnode in node_to_secondary:
# end data gathering
......@@ -1193,19 +1199,22 @@ class LUQueryNodes(NoHooksLU):
for field in self.op.output_fields:
if field == "name":
val =
elif field == "pinst":
val = node_to_primary[]
elif field == "sinst":
val = node_to_secondary[]
elif field == "pinst_list":
val = list(node_to_primary[])
elif field == "sinst_list":
val = list(node_to_secondary[])
elif field == "pinst_cnt":
val = len(node_to_primary[])
elif field == "sinst_cnt":
val = len(node_to_secondary[])
elif field == "pip":
val = node.primary_ip
elif field == "sip":
val = node.secondary_ip
elif field in self.dynamic_fields:
val = live_data[].get(field, "?")
val = live_data[].get(field, None)
raise errors.ParameterError(field)
val = str(val)
......@@ -113,7 +113,7 @@ class OpAddNode(OpCode):
class OpQueryNodes(OpCode):
"""Compute the list of nodes."""
__slots__ = ["output_fields"]
__slots__ = ["output_fields", "nodes"]
class OpQueryNodeData(OpCode):
......@@ -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"]
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):
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,
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