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: