X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/305a729705447b2d02506f7e5b3a9469645cdb2d..b757f8307de2e61291cd3cc0221502113b1e1ad6:/scripts/gnt-os diff --git a/scripts/gnt-os b/scripts/gnt-os index 899185a..1e2550f 100755 --- a/scripts/gnt-os +++ b/scripts/gnt-os @@ -19,122 +19,129 @@ # 02110-1301, USA. +# pylint: disable-msg=W0401,W0614 +# W0401: Wildcard import ganeti.cli +# W0614: Unused import %s from wildcard import (since we need cli) + import sys -from optparse import make_option from ganeti.cli import * from ganeti import opcodes -from ganeti import logger -from ganeti import objects from ganeti import utils -from ganeti import errors +from ganeti import constants + def ListOS(opts, args): - """List the OSes existing on this node. + """List the valid OSes in the cluster. + + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ - op = opcodes.OpDiagnoseOS() + op = opcodes.OpDiagnoseOS(output_fields=["name", "valid"], names=[]) result = SubmitOpCode(op) if not result: - logger.ToStdout("Can't get the OS list") + ToStderr("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]]) - if not opts.no_headers: headers = {"name": "Name"} else: headers = None data = GenerateTable(separator=None, headers=headers, fields=["name"], - data=[[os] for os in os_set]) + data=[[row[0]] for row in result if row[1]], + units=None) for line in data: - logger.ToStdout(line) + ToStdout(line) return 0 + +def _OsStatus(status, diagnose): + """Beautifier function for OS status. + + @type status: boolean + @param status: is the OS valid + @type diagnose: string + @param diagnose: the error message for invalid OSes + @rtype: string + @return: a formatted status + + """ + if status: + return "valid" + else: + return "invalid - %s" % diagnose + def DiagnoseOS(opts, args): """Analyse all OSes on this cluster. + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code + """ - op = opcodes.OpDiagnoseOS() + op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "node_status"], + names=[]) result = SubmitOpCode(op) if not result: - logger.ToStdout("Can't get the OS list") + ToStderr("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) - - max_name = len('Name') - if all_os: - max_name = max(max_name, max([len(name) for name in all_os])) + has_bad = False - max_node = len('Status/Node') - max_node = max(max_node, max([len(name) for name in node_data])) - - logger.ToStdout(format % (max_name, 'Name', max_node, 'Status/Node', - 'Details')) - - for os_name in all_os: - nodes_valid = [] + for os_name, os_valid, node_data in result: + nodes_valid = {} nodes_bad = {} - for node_name in node_data: - if node_name in all_os[os_name]: - nos = all_os[os_name][node_name] - if isinstance(nos[0], objects.OS): - nodes_valid.append(node_name) - elif isinstance(nos[0], errors.InvalidOS): - nodes_bad[node_name] = ("%s (path: %s)" % - (nos[0].args[2], nos[0].args[1])) + nodes_hidden = {} + for node_name, node_info in node_data.iteritems(): + 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 = node_info.pop(0) + first_os_msg = ("%s (path: %s)" % (_OsStatus(first_os_status, + first_os_msg), + first_os_path)) + 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: + nodes_hidden[node_name].append(" [hidden] path: %s, status: %s" % + (hpath, _OsStatus(hstatus, hmsg))) else: - nodes_bad[node_name] = "os dir not found" + nodes_bad[node_name] = "OS not found" if nodes_valid and not nodes_bad: status = "valid" elif not nodes_valid and nodes_bad: status = "invalid" + has_bad = True else: status = "partial valid" + has_bad = True + + def _OutputPerNodeOSStatus(msg_map): + map_k = utils.NiceSort(msg_map.keys()) + for node_name in map_k: + ToStdout(" Node: %s, status: %s", node_name, msg_map[node_name]) + for msg in nodes_hidden[node_name]: + ToStdout(msg) + + ToStdout("OS: %s [global status: %s]", os_name, status) + _OutputPerNodeOSStatus(nodes_valid) + _OutputPerNodeOSStatus(nodes_bad) + ToStdout("") - logger.ToStdout(format % (max_name, os_name, max_node, status, "")) - nodes_valid = utils.NiceSort(nodes_valid) - for node_name in nodes_valid: - logger.ToStdout(format % (max_name, "", max_node, node_name, - "valid (path: %s)" % all_os[os_name][node_name][0].path)) - nbk = utils.NiceSort(nodes_bad.keys()) - for node_name in nbk: - logger.ToStdout(format % (max_name, "", max_node, - node_name, nodes_bad[node_name])) + return int(has_bad) commands = {