#!/usr/bin/python # # Copyright (C) 2006, 2007 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 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 ganeti.cli import * from ganeti import opcodes from ganeti import utils from ganeti import constants def ListOS(opts, args): """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(output_fields=["name", "valid", "variants"], names=[]) result = SubmitOpCode(op) if not result: ToStderr("Can't get the OS list") return 1 if not opts.no_headers: headers = {"name": "Name"} else: headers = None os_names = [] for (name, valid, variants) in result: if valid: os_names.extend([[n] for n in CalculateOSNames(name, variants)]) data = GenerateTable(separator=None, headers=headers, fields=["name"], data=os_names, units=None) for line in data: 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(output_fields=["name", "valid", "variants", "node_status"], names=[]) result = SubmitOpCode(op) if not result: ToStderr("Can't get the OS list") return 1 has_bad = False for os_name, os_valid, os_variants, node_data in result: nodes_valid = {} nodes_bad = {} 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, first_os_variants) = node_info.pop(0) if not first_os_variants: first_os_variants = [] first_os_msg = ("%s (path: %s) [variants: %s]" % (_OsStatus(first_os_status, first_os_msg), first_os_path, utils.CommaJoin(first_os_variants))) 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 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) if os_variants: ToStdout(" Variants: [%s]" % utils.CommaJoin(os_variants)) _OutputPerNodeOSStatus(nodes_valid) _OutputPerNodeOSStatus(nodes_bad) ToStdout("") return int(has_bad) commands = { 'list': ( ListOS, ARGS_NONE, [NOHDR_OPT], "", "Lists all valid OSes on the master"), 'diagnose': ( DiagnoseOS, ARGS_NONE, [], "", "Diagnose all OSes"), } if __name__ == '__main__': sys.exit(GenericMain(commands))