return 0
-def _PrintGroupedParams(paramsdict, level=1, roman=False):
- """Print Grouped parameters (be, nic, disk) by group.
+def _FormatGroupedParams(paramsdict, roman=False):
+ """Format Grouped parameters (be, nic, disk) by group.
@type paramsdict: dict of dicts
@param paramsdict: {group: {param: value, ...}, ...}
- @type level: int
- @param level: Level of indention
+ @rtype: dict of dicts
+ @return: copy of the input dictionaries with strings as values
"""
- indent = " " * level
- for item, val in sorted(paramsdict.items()):
+ ret = {}
+ for (item, val) in paramsdict.items():
if isinstance(val, dict):
- ToStdout("%s- %s:", indent, item)
- _PrintGroupedParams(val, level=level + 1, roman=roman)
+ ret[item] = _FormatGroupedParams(val, roman=roman)
elif roman and isinstance(val, int):
- ToStdout("%s %s: %s", indent, item, compat.TryToRoman(val))
+ ret[item] = compat.TryToRoman(val)
else:
- ToStdout("%s %s: %s", indent, item, val)
+ ret[item] = str(val)
+ return ret
def ShowClusterConfig(opts, args):
cl = GetClient(query=True)
result = cl.QueryClusterInfo()
- ToStdout("Cluster name: %s", result["name"])
- ToStdout("Cluster UUID: %s", result["uuid"])
-
- ToStdout("Creation time: %s", utils.FormatTime(result["ctime"]))
- ToStdout("Modification time: %s", utils.FormatTime(result["mtime"]))
-
- ToStdout("Master node: %s", result["master"])
-
- ToStdout("Architecture (this node): %s (%s)",
- result["architecture"][0], result["architecture"][1])
-
if result["tags"]:
tags = utils.CommaJoin(utils.NiceSort(result["tags"]))
else:
tags = "(none)"
-
- ToStdout("Tags: %s", tags)
-
- ToStdout("Default hypervisor: %s", result["default_hypervisor"])
- ToStdout("Enabled hypervisors: %s",
- utils.CommaJoin(result["enabled_hypervisors"]))
-
- ToStdout("Hypervisor parameters:")
- _PrintGroupedParams(result["hvparams"])
-
- ToStdout("OS-specific hypervisor parameters:")
- _PrintGroupedParams(result["os_hvp"])
-
- ToStdout("OS parameters:")
- _PrintGroupedParams(result["osparams"])
-
- ToStdout("Hidden OSes: %s", utils.CommaJoin(result["hidden_os"]))
- ToStdout("Blacklisted OSes: %s", utils.CommaJoin(result["blacklisted_os"]))
-
- ToStdout("Cluster parameters:")
- ToStdout(" - candidate pool size: %s",
- compat.TryToRoman(result["candidate_pool_size"],
- convert=opts.roman_integers))
- ToStdout(" - master netdev: %s", result["master_netdev"])
- ToStdout(" - master netmask: %s", result["master_netmask"])
- ToStdout(" - use external master IP address setup script: %s",
- result["use_external_mip_script"])
- ToStdout(" - lvm volume group: %s", result["volume_group_name"])
if result["reserved_lvs"]:
reserved_lvs = utils.CommaJoin(result["reserved_lvs"])
else:
reserved_lvs = "(none)"
- ToStdout(" - lvm reserved volumes: %s", reserved_lvs)
- ToStdout(" - drbd usermode helper: %s", result["drbd_usermode_helper"])
- ToStdout(" - file storage path: %s", result["file_storage_dir"])
- ToStdout(" - shared file storage path: %s",
- result["shared_file_storage_dir"])
- ToStdout(" - maintenance of node health: %s",
- result["maintain_node_health"])
- ToStdout(" - uid pool: %s", uidpool.FormatUidPool(result["uid_pool"]))
- ToStdout(" - default instance allocator: %s", result["default_iallocator"])
- ToStdout(" - primary ip version: %d", result["primary_ip_version"])
- ToStdout(" - preallocation wipe disks: %s", result["prealloc_wipe_disks"])
- ToStdout(" - OS search path: %s", utils.CommaJoin(pathutils.OS_SEARCH_PATH))
- ToStdout(" - ExtStorage Providers search path: %s",
- utils.CommaJoin(pathutils.ES_SEARCH_PATH))
- ToStdout(" - enabled storage types: %s",
- utils.CommaJoin(result["enabled_storage_types"]))
-
- ToStdout("Default node parameters:")
- _PrintGroupedParams(result["ndparams"], roman=opts.roman_integers)
-
- ToStdout("Default instance parameters:")
- _PrintGroupedParams(result["beparams"], roman=opts.roman_integers)
-
- ToStdout("Default nic parameters:")
- _PrintGroupedParams(result["nicparams"], roman=opts.roman_integers)
-
- ToStdout("Default disk parameters:")
- _PrintGroupedParams(result["diskparams"], roman=opts.roman_integers)
-
- ToStdout("Instance policy - limits for instances:")
- for key in constants.IPOLICY_ISPECS:
- ToStdout(" - %s", key)
- _PrintGroupedParams(result["ipolicy"][key], roman=opts.roman_integers)
- ToStdout(" - enabled disk templates: %s",
- utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS]))
- for key in constants.IPOLICY_PARAMETERS:
- ToStdout(" - %s: %s", key, result["ipolicy"][key])
+ info = [
+ ("Cluster name", result["name"]),
+ ("Cluster UUID", result["uuid"]),
+
+ ("Creation time", utils.FormatTime(result["ctime"])),
+ ("Modification time", utils.FormatTime(result["mtime"])),
+
+ ("Master node", result["master"]),
+
+ ("Architecture (this node)",
+ "%s (%s)" % (result["architecture"][0], result["architecture"][1])),
+
+ ("Tags", tags),
+
+ ("Default hypervisor", result["default_hypervisor"]),
+ ("Enabled hypervisors",
+ utils.CommaJoin(result["enabled_hypervisors"])),
+
+ ("Hypervisor parameters", _FormatGroupedParams(result["hvparams"])),
+
+ ("OS-specific hypervisor parameters",
+ _FormatGroupedParams(result["os_hvp"])),
+
+ ("OS parameters", _FormatGroupedParams(result["osparams"])),
+
+ ("Hidden OSes", utils.CommaJoin(result["hidden_os"])),
+ ("Blacklisted OSes", utils.CommaJoin(result["blacklisted_os"])),
+
+ ("Cluster parameters", [
+ ("candidate pool size",
+ compat.TryToRoman(result["candidate_pool_size"],
+ convert=opts.roman_integers)),
+ ("master netdev", result["master_netdev"]),
+ ("master netmask", result["master_netmask"]),
+ ("use external master IP address setup script",
+ result["use_external_mip_script"]),
+ ("lvm volume group", result["volume_group_name"]),
+ ("lvm reserved volumes", reserved_lvs),
+ ("drbd usermode helper", result["drbd_usermode_helper"]),
+ ("file storage path", result["file_storage_dir"]),
+ ("shared file storage path", result["shared_file_storage_dir"]),
+ ("maintenance of node health", result["maintain_node_health"]),
+ ("uid pool", uidpool.FormatUidPool(result["uid_pool"])),
+ ("default instance allocator", result["default_iallocator"]),
+ ("primary ip version", result["primary_ip_version"]),
+ ("preallocation wipe disks", result["prealloc_wipe_disks"]),
+ ("OS search path", utils.CommaJoin(pathutils.OS_SEARCH_PATH)),
+ ("ExtStorage Providers search path",
+ utils.CommaJoin(pathutils.ES_SEARCH_PATH)),
+ ("enabled storage types",
+ utils.CommaJoin(result["enabled_storage_types"])),
+ ]),
+
+ ("Default node parameters",
+ _FormatGroupedParams(result["ndparams"], roman=opts.roman_integers)),
+
+ ("Default instance parameters",
+ _FormatGroupedParams(result["beparams"], roman=opts.roman_integers)),
+
+ ("Default nic parameters",
+ _FormatGroupedParams(result["nicparams"], roman=opts.roman_integers)),
+
+ ("Default disk parameters",
+ _FormatGroupedParams(result["diskparams"], roman=opts.roman_integers)),
+
+ ("Instance policy - limits for instances",
+ [
+ (key,
+ _FormatGroupedParams(result["ipolicy"][key], roman=opts.roman_integers))
+ for key in constants.IPOLICY_ISPECS
+ ] +
+ [
+ ("enabled disk templates",
+ utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS])),
+ ] +
+ [
+ (key, result["ipolicy"][key])
+ for key in constants.IPOLICY_PARAMETERS
+ ]),
+ ]
+
+ PrintGenericInfo(info)
return 0
AssertEqual(qa_utils.GetCommandOutput(node.primary, cmd), content)
-# "gnt-cluster info" fields
-_CIFIELD_RE = re.compile(r"^[-\s]*(?P<field>[^\s:]+):\s*(?P<value>\S.*)$")
+def _GetClusterField(field_path):
+ """Get the value of a cluster field.
-
-def _GetBoolClusterField(field):
- """Get the Boolean value of a cluster field.
-
- This function currently assumes that the field name is unique in the cluster
- configuration. An assertion checks this assumption.
-
- @type field: string
- @param field: Name of the field
- @rtype: bool
- @return: The effective value of the field
+ @type field_path: list of strings
+ @param field_path: Names of the groups/fields to navigate to get the desired
+ value, e.g. C{["Default node parameters", "oob_program"]}
+ @return: The effective value of the field (the actual type depends on the
+ chosen field)
"""
- master = qa_config.GetMasterNode()
- infocmd = "gnt-cluster info"
- info_out = qa_utils.GetCommandOutput(master.primary, infocmd)
- ret = None
- for l in info_out.splitlines():
- m = _CIFIELD_RE.match(l)
- # FIXME: There should be a way to specify a field through a hierarchy
- if m and m.group("field") == field:
- # Make sure that ignoring the hierarchy doesn't cause a double match
- assert ret is None
- ret = (m.group("value").lower() == "true")
- if ret is not None:
- return ret
- raise qa_error.Error("Field not found in cluster configuration: %s" % field)
+ assert isinstance(field_path, list)
+ assert field_path
+ ret = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
+ for key in field_path:
+ ret = ret[key]
+ return ret
# Cluster-verify errors (date, "ERROR", then error code)
AssertCommand(["gnt-cluster", "modify", "-B", bep])
-_START_IPOLICY_RE = re.compile(r"^(\s*)Instance policy")
-_START_ISPEC_RE = re.compile(r"^\s+-\s+(std|min|max)")
-_VALUE_RE = r"([^\s:][^:]*):\s+(\S.*)$"
-_IPOLICY_PARAM_RE = re.compile(r"^\s+-\s+" + _VALUE_RE)
-_ISPEC_VALUE_RE = re.compile(r"^\s+" + _VALUE_RE)
-
-
def _GetClusterIPolicy():
"""Return the run-time values of the cluster-level instance policy.
"min", "max", or "std"
"""
- mnode = qa_config.GetMasterNode()
- info = GetCommandOutput(mnode.primary, "gnt-cluster info")
- inside_policy = False
- end_ispec_re = None
- curr_spec = ""
- specs = {}
- policy = {}
- for line in info.splitlines():
- if inside_policy:
- # The order of the matching is important, as some REs overlap
- m = _START_ISPEC_RE.match(line)
- if m:
- curr_spec = m.group(1)
- continue
- m = _IPOLICY_PARAM_RE.match(line)
- if m:
- policy[m.group(1)] = m.group(2).strip()
- continue
- m = _ISPEC_VALUE_RE.match(line)
- if m:
- assert curr_spec
- par = m.group(1)
+ info = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
+ policy = info["Instance policy - limits for instances"]
+ ret_specs = {}
+ ret_policy = {}
+ for (key, val) in policy.items():
+ if key in constants.IPOLICY_ISPECS:
+ for (par, pval) in val.items():
if par == "memory-size":
par = "mem-size"
- d = specs.setdefault(par, {})
- d[curr_spec] = m.group(2).strip()
- continue
- assert end_ispec_re is not None
- if end_ispec_re.match(line):
- inside_policy = False
+ d = ret_specs.setdefault(par, {})
+ d[key] = pval
else:
- m = _START_IPOLICY_RE.match(line)
- if m:
- inside_policy = True
- # We stop parsing when we find the same indentation level
- re_str = r"^\s{%s}\S" % len(m.group(1))
- end_ispec_re = re.compile(re_str)
+ ret_policy[key] = val
+
# Sanity checks
- assert len(specs) > 0
- good = ("min" in d and "std" in d and "max" in d for d in specs)
- assert good, "Missing item in specs: %s" % specs
- assert len(policy) > 0
- return (policy, specs)
+ assert len(ret_specs) > 0
+ good = ("min" in d and "std" in d and "max" in d for d in ret_specs)
+ assert good, "Missing item in specs: %s" % ret_specs
+ assert len(ret_policy) > 0
+ return (ret_policy, ret_specs)
def TestClusterModifyIPolicy():
@return: The old value of exclusive_storage
"""
- oldvalue = _GetBoolClusterField("exclusive_storage")
+ es_path = ["Default node parameters", "exclusive_storage"]
+ oldvalue = _GetClusterField(es_path)
AssertCommand(["gnt-cluster", "modify", "--node-parameters",
"exclusive_storage=%s" % newvalue])
- effvalue = _GetBoolClusterField("exclusive_storage")
+ effvalue = _GetClusterField(es_path)
if effvalue != newvalue:
raise qa_error.Error("exclusive_storage has the wrong value: %s instead"
" of %s" % (effvalue, newvalue))