blob: f5d51adfc77bb6f89d6d0c6a12bae945b44d6548 [file] [log] [blame]
#
#
# Copyright (C) 2012 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""External Storage related commands"""
# pylint: disable=W0401,W0613,W0614,C0103
# W0401: Wildcard import ganeti.cli
# W0613: Unused argument, since all functions follow the same API
# W0614: Unused import %s from wildcard import (since we need cli)
# C0103: Invalid name gnt-storage
from ganeti.cli import *
from ganeti import opcodes
from ganeti import utils
def ShowExtStorageInfo(opts, args):
"""List detailed information about ExtStorage providers.
@param opts: the command line options selected by the user
@type args: list
@param args: empty list or list of ExtStorage providers' names
@rtype: int
@return: the desired exit code
"""
op = opcodes.OpExtStorageDiagnose(output_fields=["name", "nodegroup_status",
"parameters"],
names=[])
result = SubmitOpCode(op, opts=opts)
if not result:
ToStderr("Can't get the ExtStorage providers list")
return 1
do_filter = bool(args)
for (name, nodegroup_data, parameters) in result:
if do_filter:
if name not in args:
continue
else:
args.remove(name)
nodegroups_valid = []
for nodegroup_name, nodegroup_status in nodegroup_data.iteritems():
if nodegroup_status:
nodegroups_valid.append(nodegroup_name)
ToStdout("%s:", name)
if nodegroups_valid != []:
ToStdout(" - Valid for nodegroups:")
for ndgrp in utils.NiceSort(nodegroups_valid):
ToStdout(" %s", ndgrp)
ToStdout(" - Supported parameters:")
for pname, pdesc in parameters:
ToStdout(" %s: %s", pname, pdesc)
else:
ToStdout(" - Invalid for all nodegroups")
ToStdout("")
if args:
for name in args:
ToStdout("%s: Not Found", name)
ToStdout("")
return 0
def _ExtStorageStatus(status, diagnose):
"""Beautifier function for ExtStorage status.
@type status: boolean
@param status: is the ExtStorage provider valid
@type diagnose: string
@param diagnose: the error message for invalid ExtStorages
@rtype: string
@return: a formatted status
"""
if status:
return "valid"
else:
return "invalid - %s" % diagnose
def DiagnoseExtStorage(opts, args):
"""Analyse all ExtStorage providers.
@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.OpExtStorageDiagnose(output_fields=["name", "node_status",
"nodegroup_status"],
names=[])
result = SubmitOpCode(op, opts=opts)
if not result:
ToStderr("Can't get the list of ExtStorage providers")
return 1
for provider_name, node_data, nodegroup_data in result:
nodes_valid = {}
nodes_bad = {}
nodegroups_valid = {}
nodegroups_bad = {}
# Per node diagnose
for node_name, node_info in node_data.iteritems():
if node_info: # at least one entry in the per-node list
(fo_path, fo_status, fo_msg, fo_params) = node_info.pop(0)
fo_msg = "%s (path: %s)" % (_ExtStorageStatus(fo_status, fo_msg),
fo_path)
if fo_params:
fo_msg += (" [parameters: %s]" %
utils.CommaJoin([v[0] for v in fo_params]))
else:
fo_msg += " [no parameters]"
if fo_status:
nodes_valid[node_name] = fo_msg
else:
nodes_bad[node_name] = fo_msg
else:
nodes_bad[node_name] = "ExtStorage provider not found"
# Per nodegroup diagnose
for nodegroup_name, nodegroup_status in nodegroup_data.iteritems():
status = nodegroup_status
if status:
nodegroups_valid[nodegroup_name] = "valid"
else:
nodegroups_bad[nodegroup_name] = "invalid"
def _OutputPerNodegroupStatus(msg_map):
map_k = utils.NiceSort(msg_map.keys())
for nodegroup in map_k:
ToStdout(" For nodegroup: %s --> %s", nodegroup,
msg_map[nodegroup])
def _OutputPerNodeStatus(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])
# Print the output
st_msg = "Provider: %s" % provider_name
ToStdout(st_msg)
ToStdout("---")
_OutputPerNodeStatus(nodes_valid)
_OutputPerNodeStatus(nodes_bad)
ToStdout(" --")
_OutputPerNodegroupStatus(nodegroups_valid)
_OutputPerNodegroupStatus(nodegroups_bad)
ToStdout("")
return 0
commands = {
"diagnose": (
DiagnoseExtStorage, ARGS_NONE, [PRIORITY_OPT],
"", "Diagnose all ExtStorage providers"),
"info": (
ShowExtStorageInfo, [ArgOs()], [PRIORITY_OPT],
"", "Show info about ExtStorage providers"),
}
def Main():
return GenericMain(commands)