From bad78e6657cd20d04fd32b0c8cae686b53efac25 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Tue, 15 Jun 2010 01:45:20 +0200 Subject: [PATCH] LUDiagnoseOS: add more fields, cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch exports all the way from backend a new field βapi_versionβ which holds the list of support API versions, and exposes the (already computed) βparametersβ field. The patch also reworks (again) the field calculation in its Exec() method. All callers of LUDiagnoseOS pass in the 'valid' and 'variants' parameters, thus having the special casing of whether to compute or not the validity seems overkill. We move to a model where we always compute these across-nodes arguments, in order to simplify the code, and we also change the parameters set to be intersection of all node's values (which means a change in description will drop the parameter from the list of parameters). Additionally, we update scripts/gnt-os, which was broken for multi-dir OSes since the introduction of variantsβ¦ Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/backend.py | 12 ++++++++---- lib/cmdlib.py | 50 ++++++++++++++++++++++++++++---------------------- scripts/gnt-os | 9 +++++---- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index 4e719ac6f..366a3b459 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 029f641ad..0941fa5e5 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 e7177c333..ef42106e4 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: -- GitLab