diff --git a/lib/backend.py b/lib/backend.py
index 4e719ac6fbfbe6ae2914e10ea35500930395dde9..366a3b459cd0c0100f03bbd84dffd8bd6655104f 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1774,14 +1774,16 @@ def DiagnoseOS(top_dirs=None):
search (if not given defaults to
L{constants.OS_SEARCH_PATH})
@rtype: list of L{objects.OS}
- @return: a list of tuples (name, path, status, diagnose, variants)
- for all (potential) OSes under all search paths, where:
+ @return: a list of tuples (name, path, status, diagnose, variants,
+ parameters, api_version) for all (potential) OSes under all
+ search paths, where:
- name is the (potential) OS name
- path is the full path to the OS
- status True/False is the validity of the OS
- diagnose is the error message for an invalid OS, otherwise empty
- variants is a list of supported OS variants, if any
- parameters is a list of (name, help) parameters, if any
+ - api_version is a list of support OS API versions
"""
if top_dirs is None:
@@ -1802,10 +1804,12 @@ def DiagnoseOS(top_dirs=None):
diagnose = ""
variants = os_inst.supported_variants
parameters = os_inst.supported_parameters
+ api_versions = os_inst.api_versions
else:
diagnose = os_inst
- variants = parameters = []
- result.append((name, os_path, status, diagnose, variants, parameters))
+ variants = parameters = api_versions = []
+ result.append((name, os_path, status, diagnose, variants,
+ parameters, api_versions))
return result
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 029f641adf02d6f1e2c6f4914f3321e58abd930e..0941fa5e5ae78812bf618c185d66747b8fc2bf60 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2738,9 +2738,8 @@ class LUDiagnoseOS(NoHooksLU):
_OP_REQP = ["output_fields", "names"]
REQ_BGL = False
_FIELDS_STATIC = utils.FieldSet()
- _FIELDS_DYNAMIC = utils.FieldSet("name", "valid", "node_status", "variants")
- # Fields that need calculation of global os validity
- _FIELDS_NEEDVALID = frozenset(["valid", "variants"])
+ _FIELDS_DYNAMIC = utils.FieldSet("name", "valid", "node_status", "variants",
+ "parameters", "api_versions")
def ExpandNames(self):
if self.op.names:
@@ -2772,7 +2771,7 @@ class LUDiagnoseOS(NoHooksLU):
@rtype: dict
@return: a dictionary with osnames as keys and as value another
map, with nodes as keys and tuples of (path, status, diagnose,
- variants, parameters) as values, eg::
+ variants, parameters, api_versions) as values, eg::
{"debian-etch": {"node1": [(/usr/lib/..., True, "", [], []),
(/srv/..., False, "invalid api")],
@@ -2789,15 +2788,18 @@ class LUDiagnoseOS(NoHooksLU):
for node_name, nr in rlist.items():
if nr.fail_msg or not nr.payload:
continue
- for name, path, status, diagnose, variants, params in nr.payload:
+ for (name, path, status, diagnose, variants,
+ params, api_versions) in nr.payload:
if name not in all_os:
# build a list of nodes for this os containing empty lists
# for each node in node_list
all_os[name] = {}
for nname in good_nodes:
all_os[name][nname] = []
+ # convert params from [name, help] to (name, help)
+ params = [tuple(v) for v in params]
all_os[name][node_name].append((path, status, diagnose,
- variants, params))
+ variants, params, api_versions))
return all_os
def Exec(self, feedback_fn):
@@ -2808,25 +2810,25 @@ class LUDiagnoseOS(NoHooksLU):
node_data = self.rpc.call_os_diagnose(valid_nodes)
pol = self._DiagnoseByOS(node_data)
output = []
- calc_valid = self._FIELDS_NEEDVALID.intersection(self.op.output_fields)
- calc_variants = "variants" in self.op.output_fields
for os_name, os_data in pol.items():
row = []
- if calc_valid:
- valid = True
- variants = None
- for osl in os_data.values():
- valid = bool(valid and osl and osl[0][1])
- if not valid:
- variants = set()
- break
- if calc_variants:
- node_variants = osl[0][3]
- if variants is None:
- variants = set(node_variants)
- else:
- variants.intersection_update(node_variants)
+ valid = True
+ (variants, params, api_versions) = null_state = (set(), set(), set())
+ for idx, osl in enumerate(os_data.values()):
+ valid = bool(valid and osl and osl[0][1])
+ if not valid:
+ (variants, params, api_versions) = null_state
+ break
+ node_variants, node_params, node_api = osl[0][3:6]
+ if idx == 0: # first entry
+ variants = set(node_variants)
+ params = set(node_params)
+ api_versions = set(node_api)
+ else: # keep consistency
+ variants.intersection_update(node_variants)
+ params.intersection_update(node_params)
+ api_versions.intersection_update(node_api)
for field in self.op.output_fields:
if field == "name":
@@ -2840,6 +2842,10 @@ class LUDiagnoseOS(NoHooksLU):
val[node_name] = nos_list
elif field == "variants":
val = list(variants)
+ elif field == "parameters":
+ val = list(params)
+ elif field == "api_versions":
+ val = list(api_versions)
else:
raise errors.ParameterError(field)
row.append(val)
diff --git a/scripts/gnt-os b/scripts/gnt-os
index e7177c3333a9bbaeeb01fa51f58e0b97167649ae..ef42106e493ec3cabc8f4ec85b44670c07b9d78c 100755
--- a/scripts/gnt-os
+++ b/scripts/gnt-os
@@ -114,17 +114,18 @@ def DiagnoseOS(opts, args):
nodes_hidden[node_name] = []
if node_info: # at least one entry in the per-node list
(first_os_path, first_os_status, first_os_msg,
- first_os_variants, _) = node_info.pop(0)
+ first_os_variants, _, first_os_api) = node_info.pop(0)
if not first_os_variants:
first_os_variants = []
- first_os_msg = ("%s (path: %s) [variants: %s]" %
+ first_os_msg = ("%s (path: %s) [variants: %s] [api: %s]" %
(_OsStatus(first_os_status, first_os_msg),
- first_os_path, utils.CommaJoin(first_os_variants)))
+ first_os_path, utils.CommaJoin(first_os_variants),
+ utils.CommaJoin(first_os_api)))
if first_os_status:
nodes_valid[node_name] = first_os_msg
else:
nodes_bad[node_name] = first_os_msg
- for hpath, hstatus, hmsg in node_info:
+ for hpath, hstatus, hmsg, _, _, _ in node_info:
nodes_hidden[node_name].append(" [hidden] path: %s, status: %s" %
(hpath, _OsStatus(hstatus, hmsg)))
else: