Merge branch 'devel-2.7'
[ganeti-local] / lib / client / gnt_storage.py
1 #
2 #
3
4 # Copyright (C) 2012 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 """External Storage related commands"""
22
23 # pylint: disable=W0401,W0613,W0614,C0103
24 # W0401: Wildcard import ganeti.cli
25 # W0613: Unused argument, since all functions follow the same API
26 # W0614: Unused import %s from wildcard import (since we need cli)
27 # C0103: Invalid name gnt-storage
28
29 from ganeti.cli import *
30 from ganeti import opcodes
31 from ganeti import utils
32
33
34 def ShowExtStorageInfo(opts, args):
35   """List detailed information about ExtStorage providers.
36
37   @param opts: the command line options selected by the user
38   @type args: list
39   @param args: empty list or list of ExtStorage providers' names
40   @rtype: int
41   @return: the desired exit code
42
43   """
44   op = opcodes.OpExtStorageDiagnose(output_fields=["name", "nodegroup_status",
45                                                    "parameters"],
46                                     names=[])
47
48   result = SubmitOpCode(op, opts=opts)
49
50   if not result:
51     ToStderr("Can't get the ExtStorage providers list")
52     return 1
53
54   do_filter = bool(args)
55
56   for (name, nodegroup_data, parameters) in result:
57     if do_filter:
58       if name not in args:
59         continue
60       else:
61         args.remove(name)
62
63     nodegroups_valid = []
64     for nodegroup_name, nodegroup_status in nodegroup_data.iteritems():
65       if nodegroup_status:
66         nodegroups_valid.append(nodegroup_name)
67
68     ToStdout("%s:", name)
69
70     if nodegroups_valid != []:
71       ToStdout("  - Valid for nodegroups:")
72       for ndgrp in utils.NiceSort(nodegroups_valid):
73         ToStdout("      %s", ndgrp)
74       ToStdout("  - Supported parameters:")
75       for pname, pdesc in parameters:
76         ToStdout("      %s: %s", pname, pdesc)
77     else:
78       ToStdout("  - Invalid for all nodegroups")
79
80     ToStdout("")
81
82   if args:
83     for name in args:
84       ToStdout("%s: Not Found", name)
85       ToStdout("")
86
87   return 0
88
89
90 def _ExtStorageStatus(status, diagnose):
91   """Beautifier function for ExtStorage status.
92
93   @type status: boolean
94   @param status: is the ExtStorage provider valid
95   @type diagnose: string
96   @param diagnose: the error message for invalid ExtStorages
97   @rtype: string
98   @return: a formatted status
99
100   """
101   if status:
102     return "valid"
103   else:
104     return "invalid - %s" % diagnose
105
106
107 def DiagnoseExtStorage(opts, args):
108   """Analyse all ExtStorage providers.
109
110   @param opts: the command line options selected by the user
111   @type args: list
112   @param args: should be an empty list
113   @rtype: int
114   @return: the desired exit code
115
116   """
117   op = opcodes.OpExtStorageDiagnose(output_fields=["name", "node_status",
118                                                    "nodegroup_status"],
119                                     names=[])
120
121   result = SubmitOpCode(op, opts=opts)
122
123   if not result:
124     ToStderr("Can't get the list of ExtStorage providers")
125     return 1
126
127   for provider_name, node_data, nodegroup_data in result:
128
129     nodes_valid = {}
130     nodes_bad = {}
131     nodegroups_valid = {}
132     nodegroups_bad = {}
133
134     # Per node diagnose
135     for node_name, node_info in node_data.iteritems():
136       if node_info: # at least one entry in the per-node list
137         (fo_path, fo_status, fo_msg, fo_params) = node_info.pop(0)
138         fo_msg = "%s (path: %s)" % (_ExtStorageStatus(fo_status, fo_msg),
139                                     fo_path)
140         if fo_params:
141           fo_msg += (" [parameters: %s]" %
142                      utils.CommaJoin([v[0] for v in fo_params]))
143         else:
144           fo_msg += " [no parameters]"
145         if fo_status:
146           nodes_valid[node_name] = fo_msg
147         else:
148           nodes_bad[node_name] = fo_msg
149       else:
150         nodes_bad[node_name] = "ExtStorage provider not found"
151
152     # Per nodegroup diagnose
153     for nodegroup_name, nodegroup_status in nodegroup_data.iteritems():
154       status = nodegroup_status
155       if status:
156         nodegroups_valid[nodegroup_name] = "valid"
157       else:
158         nodegroups_bad[nodegroup_name] = "invalid"
159
160     def _OutputPerNodegroupStatus(msg_map):
161       map_k = utils.NiceSort(msg_map.keys())
162       for nodegroup in map_k:
163         ToStdout("  For nodegroup: %s --> %s", nodegroup,
164                  msg_map[nodegroup])
165
166     def _OutputPerNodeStatus(msg_map):
167       map_k = utils.NiceSort(msg_map.keys())
168       for node_name in map_k:
169         ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
170
171     # Print the output
172     st_msg = "Provider: %s" % provider_name
173     ToStdout(st_msg)
174     ToStdout("---")
175     _OutputPerNodeStatus(nodes_valid)
176     _OutputPerNodeStatus(nodes_bad)
177     ToStdout("  --")
178     _OutputPerNodegroupStatus(nodegroups_valid)
179     _OutputPerNodegroupStatus(nodegroups_bad)
180     ToStdout("")
181
182   return 0
183
184
185 commands = {
186   "diagnose": (
187     DiagnoseExtStorage, ARGS_NONE, [PRIORITY_OPT],
188     "", "Diagnose all ExtStorage providers"),
189   "info": (
190     ShowExtStorageInfo, [ArgOs()], [PRIORITY_OPT],
191     "", "Show info about ExtStorage providers"),
192   }
193
194
195 def Main():
196   return GenericMain(commands)