Commit ec223efb authored by Iustin Pop's avatar Iustin Pop
Browse files

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