diff --git a/scripts/gnt-os b/scripts/gnt-os index 646e3978009c225fe72cfefbbcf1a6d79a45e4c0..e624fdeb3e99f94f30c52fb7cc20198f6b6c4f2a 100755 --- a/scripts/gnt-os +++ b/scripts/gnt-os @@ -29,6 +29,35 @@ from ganeti import objects from ganeti import utils from ganeti import errors +def _GetAllOS(rlist): + """Remap an OpDiagnoseOS() return list into an a per-os per-node dictionary + + Args: + rlist: a map with nodes as keys and diagnoseobjects as values + + Returns: + map: a map with osnames as keys and as value another map, with nodes as + keys and diagnoseobjects as values + e.g. {"debian-etch": {"node1": <object>, "node2": <object>}} + """ + + all_os = {} + for node_name, nr in rlist.iteritems(): + if not nr: + continue + for obj in nr: + if _DiagnoseOSValid(obj): + os_name = obj.name + else: + os_name = obj.args[0] + if os_name not in all_os: + all_os[os_name] = {} + if node_name not in all_os[os_name]: + all_os[os_name][node_name] = [] + all_os[os_name][node_name].append(obj) + + return all_os + def ListOS(opts, args): """List the OSes existing on this node. @@ -40,18 +69,21 @@ def ListOS(opts, args): logger.ToStdout("Can't get the OS list") return 1 - # filter non-valid OS-es - oses = {} - for node_name in result: - oses[node_name] = [obj for obj in result[node_name] - if isinstance(obj, objects.OS)] - - # Get intersection of all OSes - fnode = oses.keys()[0] - os_set = set([os_inst.name for os_inst in oses[fnode]]) - del oses[fnode] - for node in oses: - os_set &= set([os_inst.name for os_inst in oses[node]]) + node_data = result + num_nodes = len(node_data) + all_os = _GetAllOS(node_data) + + valid_os = [] + for os_name, os_node_data in all_os.iteritems(): + if len(os_node_data) != num_nodes: + continue + valid = True + for l in os_node_data.values(): + if not _DiagnoseOSValid(l[0]): + valid = False + break + if valid: + valid_os.append(os_name) if not opts.no_headers: headers = {"name": "Name"} @@ -59,7 +91,7 @@ def ListOS(opts, args): headers = None data = GenerateTable(separator=None, headers=headers, fields=["name"], - data=[[os] for os in os_set]) + data=[[os] for os in valid_os]) for line in data: logger.ToStdout(line) @@ -109,23 +141,10 @@ def DiagnoseOS(opts, args): logger.ToStdout("Can't get the OS list") return 1 - format = "%-*s %-*s %s" - node_data = result - all_os = {} - for node_name in node_data: - nr = node_data[node_name] - if nr: - for obj in nr: - if isinstance(obj, objects.OS): - os_name = obj.name - else: - os_name = obj.args[0] - if os_name not in all_os: - all_os[os_name] = {} - if node_name not in all_os[os_name]: - all_os[os_name][node_name] = [] - all_os[os_name][node_name].append(obj) + all_os = _GetAllOS(node_data) + + format = "%-*s %-*s %s" max_name = len('Name') if all_os: