diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py index 55bbdf4b9283cf5d1e625f1eb3d55e78cab79659..1ac4f5acd85b74cdad36bb796c33b87a7fb5f04c 100644 --- a/lib/client/gnt_node.py +++ b/lib/client/gnt_node.py @@ -34,6 +34,7 @@ from ganeti import utils from ganeti import constants from ganeti import errors from ganeti import netutils +from cStringIO import StringIO #: default list of field for L{ListNodes} @@ -388,11 +389,13 @@ def ShowNodeConfig(opts, args): result = cl.QueryNodes(fields=["name", "pip", "sip", "pinst_list", "sinst_list", "master_candidate", "drained", "offline", - "master_capable", "vm_capable", "powered"], + "master_capable", "vm_capable", "powered", + "ndparams", "custom_ndparams"], names=args, use_locking=False) - for (name, primary_ip, secondary_ip, pinst, sinst, - is_mc, drained, offline, master_capable, vm_capable, powered) in result: + for (name, primary_ip, secondary_ip, pinst, sinst, is_mc, drained, offline, + master_capable, vm_capable, powered, ndparams, + ndparams_custom) in result: ToStdout("Node name: %s", name) ToStdout(" primary ip: %s", primary_ip) ToStdout(" secondary ip: %s", secondary_ip) @@ -416,6 +419,10 @@ def ShowNodeConfig(opts, args): ToStdout(" - %s", iname) else: ToStdout(" secondary for no instances") + ToStdout(" node parameters:") + buf = StringIO() + FormatParameterDict(buf, ndparams_custom, ndparams, level=2) + ToStdout(buf.getvalue().rstrip("\n")) return 0 diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 97234d8eff13a036b8c88a2f873ce9d5a0a5583a..e989b2316f7927252bae43d732815c65d03c3e46 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -3595,7 +3595,7 @@ class _NodeQuery(_QueryBase): return query.NodeQueryData([all_info[name] for name in nodenames], live_data, lu.cfg.GetMasterNode(), node_to_primary, node_to_secondary, groups, - oob_support) + oob_support, lu.cfg.GetClusterInfo()) class LUQueryNodes(NoHooksLU): diff --git a/lib/query.py b/lib/query.py index 55dc63f8e2be71d0059c995b078cf629071404c4..25263ce41eceb86203426ce93b9e1a435dab688a 100644 --- a/lib/query.py +++ b/lib/query.py @@ -358,7 +358,7 @@ class NodeQueryData: """ def __init__(self, nodes, live_data, master_name, node_to_primary, - node_to_secondary, groups, oob_support): + node_to_secondary, groups, oob_support, cluster): """Initializes this class. """ @@ -369,6 +369,7 @@ class NodeQueryData: self.node_to_secondary = node_to_secondary self.groups = groups self.oob_support = oob_support + self.cluster = cluster # Used for individual rows self.curlive_data = None @@ -415,19 +416,40 @@ _NODE_LIVE_FIELDS = { } -def _GetNodeGroup(ctx, node): +def _GetGroup(cb): + """Build function for calling another function with an node group. + + @param cb: The callback to be called with the nodegroup + + """ + def fn(ctx, node): + """Get group data for a node. + + @type ctx: L{NodeQueryData} + @type inst: L{objects.Node} + @param inst: Node object + + """ + ng = ctx.groups.get(node.group, None) + if ng is None: + # Nodes always have a group, or the configuration is corrupt + return (constants.QRFS_UNAVAIL, None) + + return cb(ctx, node, ng) + + return fn + + +def _GetNodeGroup(ctx, node, ng): # pylint: disable-msg=W0613 """Returns the name of a node's group. @type ctx: L{NodeQueryData} @type node: L{objects.Node} @param node: Node object + @type ng: L{objects.NodeGroup} + @param ng: The node group this node belongs to """ - ng = ctx.groups.get(node.group, None) - if ng is None: - # Nodes always have a group, or the configuration is corrupt - return (constants.QRFS_UNAVAIL, None) - return (constants.QRFS_NORMAL, ng.name) @@ -445,6 +467,19 @@ def _GetNodePower(ctx, node): return (constants.QRFS_UNAVAIL, None) +def _GetNdParams(ctx, node, ng): + """Returns the ndparams for this node. + + @type ctx: L{NodeQueryData} + @type node: L{objects.Node} + @param node: Node object + @type ng: L{objects.NodeGroup} + @param ng: The node group this node belongs to + + """ + return (constants.QRFS_NORMAL, ctx.cluster.SimpleFillND(ng.FillND(node))) + + def _GetLiveNodeField(field, kind, ctx, node): """Gets the value of a "live" field from L{NodeQueryData}. @@ -496,11 +531,16 @@ def _BuildNodeFields(): (_MakeField("role", "Role", constants.QFT_TEXT), NQ_CONFIG, lambda ctx, node: (constants.QRFS_NORMAL, _GetNodeRole(node, ctx.master_name))), - (_MakeField("group", "Group", constants.QFT_TEXT), NQ_GROUP, _GetNodeGroup), + (_MakeField("group", "Group", constants.QFT_TEXT), NQ_GROUP, + _GetGroup(_GetNodeGroup)), (_MakeField("group.uuid", "GroupUUID", constants.QFT_TEXT), NQ_CONFIG, lambda ctx, node: (constants.QRFS_NORMAL, node.group)), (_MakeField("powered", "Powered", constants.QFT_BOOL), NQ_OOB, _GetNodePower), + (_MakeField("ndparams", "NodeParameters", constants.QFT_OTHER), NQ_GROUP, + _GetGroup(_GetNdParams)), + (_MakeField("custom_ndparams", "CustomNodeParameters", constants.QFT_OTHER), + NQ_GROUP, lambda ctx, node: (constants.QRFS_NORMAL, node.ndparams)), ] def _GetLength(getter): diff --git a/test/ganeti.query_unittest.py b/test/ganeti.query_unittest.py index cb296a319d6e67826722db306fdc86d0a9dccf3b..baace67c1734793a7b7ea20a021dda247c5123a0 100755 --- a/test/ganeti.query_unittest.py +++ b/test/ganeti.query_unittest.py @@ -289,7 +289,8 @@ class TestNodeQuery(unittest.TestCase): objects.Node(name="node3", drained=False), ] for live_data in [None, dict.fromkeys([node.name for node in nodes], {})]: - nqd = query.NodeQueryData(nodes, live_data, None, None, None, None, None) + nqd = query.NodeQueryData(nodes, live_data, None, None, None, None, None, + None) q = self._Create(["name", "drained"]) self.assertEqual(q.RequestedData(), set([query.NQ_CONFIG])) @@ -315,6 +316,17 @@ class TestNodeQuery(unittest.TestCase): set([query.NQ_CONFIG, query.NQ_LIVE, query.NQ_INST, query.NQ_GROUP, query.NQ_OOB])) + cluster = objects.Cluster(cluster_name="testcluster", + hvparams=constants.HVC_DEFAULTS, + beparams={ + constants.PP_DEFAULT: constants.BEC_DEFAULTS, + }, + nicparams={ + constants.PP_DEFAULT: constants.NICC_DEFAULTS, + }, + ndparams=constants.NDC_DEFAULTS, + ) + node_names = ["node%s" % i for i in range(20)] master_name = node_names[3] nodes = [ @@ -327,6 +339,7 @@ class TestNodeQuery(unittest.TestCase): drained=False, vm_capable=False, master_capable=False, + ndparams={}, group="default", ctime=1290006900, mtime=1290006913, @@ -373,7 +386,7 @@ class TestNodeQuery(unittest.TestCase): ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6" groups = { - ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid), + ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}), } oob_support = dict((name, False) for name in node_names) @@ -382,7 +395,7 @@ class TestNodeQuery(unittest.TestCase): nqd = query.NodeQueryData(nodes, live_data, master_name, node_to_primary, node_to_secondary, groups, - oob_support) + oob_support, cluster) result = q.Query(nqd) self.assert_(compat.all(len(row) == len(selected) for row in result)) self.assertEqual([row[field_index["name"]] for row in result], @@ -445,7 +458,7 @@ class TestNodeQuery(unittest.TestCase): live_data = dict.fromkeys([node.name for node in nodes], {}) # No data - nqd = query.NodeQueryData(None, None, None, None, None, None, None) + nqd = query.NodeQueryData(None, None, None, None, None, None, None, None) self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER, nqd, nodes[0]), (constants.QRFS_NODATA, None))