Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-os @ af1a81d1

History | View | Annotate | Download (7.7 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 db5a8a2d Iustin Pop
# Copyright (C) 2006, 2007, 2010 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 7260cfbe Iustin Pop
"""OS scripts related commands"""
22 a8083063 Iustin Pop
23 2d54e29c Iustin Pop
# pylint: disable-msg=W0401,W0613,W0614,C0103
24 2f79bd34 Iustin Pop
# W0401: Wildcard import ganeti.cli
25 2d54e29c Iustin Pop
# W0613: Unused argument, since all functions follow the same API
26 2f79bd34 Iustin Pop
# W0614: Unused import %s from wildcard import (since we need cli)
27 7260cfbe Iustin Pop
# C0103: Invalid name gnt-os
28 2f79bd34 Iustin Pop
29 a8083063 Iustin Pop
import sys
30 a8083063 Iustin Pop
31 a8083063 Iustin Pop
from ganeti.cli import *
32 ccadf1ff Iustin Pop
from ganeti import constants
33 a8083063 Iustin Pop
from ganeti import opcodes
34 a8083063 Iustin Pop
from ganeti import utils
35 216fe2f3 Guido Trotter
36 fbdb07b9 Guido Trotter
37 a8083063 Iustin Pop
def ListOS(opts, args):
38 6099bfcf Iustin Pop
  """List the valid OSes in the cluster.
39 6099bfcf Iustin Pop
40 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
41 6099bfcf Iustin Pop
  @type args: list
42 6099bfcf Iustin Pop
  @param args: should be an empty list
43 6099bfcf Iustin Pop
  @rtype: int
44 6099bfcf Iustin Pop
  @return: the desired exit code
45 a8083063 Iustin Pop
46 a8083063 Iustin Pop
  """
47 e3ac208c Guido Trotter
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "variants"],
48 e3ac208c Guido Trotter
                            names=[])
49 400ca2f7 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
50 a8083063 Iustin Pop
51 a8083063 Iustin Pop
  if not result:
52 3a24c527 Iustin Pop
    ToStderr("Can't get the OS list")
53 a8083063 Iustin Pop
    return 1
54 a8083063 Iustin Pop
55 a8083063 Iustin Pop
  if not opts.no_headers:
56 606d909d Michael Hanselmann
    headers = {"name": "Name"}
57 606d909d Michael Hanselmann
  else:
58 606d909d Michael Hanselmann
    headers = None
59 a8083063 Iustin Pop
60 e3ac208c Guido Trotter
  os_names = []
61 e3ac208c Guido Trotter
  for (name, valid, variants) in result:
62 e3ac208c Guido Trotter
    if valid:
63 e3ac208c Guido Trotter
      os_names.extend([[n] for n in CalculateOSNames(name, variants)])
64 e3ac208c Guido Trotter
65 16be8703 Iustin Pop
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
66 e3ac208c Guido Trotter
                       data=os_names, units=None)
67 16be8703 Iustin Pop
68 16be8703 Iustin Pop
  for line in data:
69 3a24c527 Iustin Pop
    ToStdout(line)
70 a8083063 Iustin Pop
71 a8083063 Iustin Pop
  return 0
72 a8083063 Iustin Pop
73 b07a9f05 Guido Trotter
74 ae5b1530 Iustin Pop
def ShowOSInfo(opts, args):
75 ae5b1530 Iustin Pop
  """List detailed information about OSes in the cluster.
76 ae5b1530 Iustin Pop
77 ae5b1530 Iustin Pop
  @param opts: the command line options selected by the user
78 ae5b1530 Iustin Pop
  @type args: list
79 ae5b1530 Iustin Pop
  @param args: should be an empty list
80 ae5b1530 Iustin Pop
  @rtype: int
81 ae5b1530 Iustin Pop
  @return: the desired exit code
82 ae5b1530 Iustin Pop
83 ae5b1530 Iustin Pop
  """
84 ae5b1530 Iustin Pop
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "variants",
85 ae5b1530 Iustin Pop
                                           "parameters", "api_versions"],
86 ae5b1530 Iustin Pop
                            names=[])
87 ae5b1530 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
88 ae5b1530 Iustin Pop
89 ae5b1530 Iustin Pop
  if not result:
90 ae5b1530 Iustin Pop
    ToStderr("Can't get the OS list")
91 ae5b1530 Iustin Pop
    return 1
92 ae5b1530 Iustin Pop
93 ae5b1530 Iustin Pop
  do_filter = bool(args)
94 ae5b1530 Iustin Pop
95 ae5b1530 Iustin Pop
  for (name, valid, variants, parameters, api_versions) in result:
96 ae5b1530 Iustin Pop
    if do_filter:
97 ae5b1530 Iustin Pop
      if name not in args:
98 ae5b1530 Iustin Pop
        continue
99 ae5b1530 Iustin Pop
      else:
100 ae5b1530 Iustin Pop
        args.remove(name)
101 ae5b1530 Iustin Pop
    ToStdout("%s:", name)
102 ae5b1530 Iustin Pop
    ToStdout("  - valid: %s", valid)
103 ae5b1530 Iustin Pop
    if valid:
104 ae5b1530 Iustin Pop
      ToStdout("  - API versions:")
105 ae5b1530 Iustin Pop
      for version in sorted(api_versions):
106 ae5b1530 Iustin Pop
        ToStdout("    - %s", version)
107 ae5b1530 Iustin Pop
      ToStdout("  - variants:")
108 ae5b1530 Iustin Pop
      for vname in variants:
109 ae5b1530 Iustin Pop
        ToStdout("    - %s", vname)
110 ae5b1530 Iustin Pop
      ToStdout("  - parameters:")
111 ae5b1530 Iustin Pop
      for pname, pdesc in parameters:
112 ae5b1530 Iustin Pop
        ToStdout("    - %s: %s", pname, pdesc)
113 ae5b1530 Iustin Pop
    ToStdout("")
114 ae5b1530 Iustin Pop
115 ae5b1530 Iustin Pop
  if args:
116 ae5b1530 Iustin Pop
    for name in args:
117 ae5b1530 Iustin Pop
      ToStdout("%s: ", name)
118 ae5b1530 Iustin Pop
      ToStdout("")
119 ae5b1530 Iustin Pop
120 ae5b1530 Iustin Pop
  return 0
121 ae5b1530 Iustin Pop
122 ae5b1530 Iustin Pop
123 255dcebd Iustin Pop
def _OsStatus(status, diagnose):
124 255dcebd Iustin Pop
  """Beautifier function for OS status.
125 255dcebd Iustin Pop
126 255dcebd Iustin Pop
  @type status: boolean
127 255dcebd Iustin Pop
  @param status: is the OS valid
128 255dcebd Iustin Pop
  @type diagnose: string
129 255dcebd Iustin Pop
  @param diagnose: the error message for invalid OSes
130 255dcebd Iustin Pop
  @rtype: string
131 255dcebd Iustin Pop
  @return: a formatted status
132 255dcebd Iustin Pop
133 255dcebd Iustin Pop
  """
134 255dcebd Iustin Pop
  if status:
135 255dcebd Iustin Pop
    return "valid"
136 255dcebd Iustin Pop
  else:
137 255dcebd Iustin Pop
    return "invalid - %s" % diagnose
138 255dcebd Iustin Pop
139 af1a81d1 Michael Hanselmann
140 a8083063 Iustin Pop
def DiagnoseOS(opts, args):
141 a8083063 Iustin Pop
  """Analyse all OSes on this cluster.
142 a8083063 Iustin Pop
143 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
144 6099bfcf Iustin Pop
  @type args: list
145 6099bfcf Iustin Pop
  @param args: should be an empty list
146 6099bfcf Iustin Pop
  @rtype: int
147 6099bfcf Iustin Pop
  @return: the desired exit code
148 6099bfcf Iustin Pop
149 a8083063 Iustin Pop
  """
150 e16dfb5b Guido Trotter
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "variants",
151 e16dfb5b Guido Trotter
                                           "node_status"], names=[])
152 400ca2f7 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
153 a8083063 Iustin Pop
154 a8083063 Iustin Pop
  if not result:
155 3a24c527 Iustin Pop
    ToStderr("Can't get the OS list")
156 a8083063 Iustin Pop
    return 1
157 a8083063 Iustin Pop
158 a2656173 Michael Hanselmann
  has_bad = False
159 a2656173 Michael Hanselmann
160 f4ad2ef0 Iustin Pop
  for os_name, _, os_variants, node_data in result:
161 b07a9f05 Guido Trotter
    nodes_valid = {}
162 a8083063 Iustin Pop
    nodes_bad = {}
163 1f9430d6 Iustin Pop
    nodes_hidden = {}
164 1f9430d6 Iustin Pop
    for node_name, node_info in node_data.iteritems():
165 1f9430d6 Iustin Pop
      nodes_hidden[node_name] = []
166 1f9430d6 Iustin Pop
      if node_info: # at least one entry in the per-node list
167 ccadf1ff Iustin Pop
        (fo_path, fo_status, fo_msg, fo_variants,
168 ccadf1ff Iustin Pop
         fo_params, fo_api) = node_info.pop(0)
169 ccadf1ff Iustin Pop
        fo_msg = "%s (path: %s)" % (_OsStatus(fo_status, fo_msg), fo_path)
170 ccadf1ff Iustin Pop
        if fo_api:
171 ccadf1ff Iustin Pop
          max_os_api = max(fo_api)
172 ccadf1ff Iustin Pop
          fo_msg += " [API versions: %s]" % utils.CommaJoin(fo_api)
173 b07a9f05 Guido Trotter
        else:
174 ccadf1ff Iustin Pop
          max_os_api = 0
175 ccadf1ff Iustin Pop
          fo_msg += " [no API versions declared]"
176 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V15:
177 ccadf1ff Iustin Pop
          if fo_variants:
178 ccadf1ff Iustin Pop
            fo_msg += " [variants: %s]" % utils.CommaJoin(fo_variants)
179 ccadf1ff Iustin Pop
          else:
180 ccadf1ff Iustin Pop
            fo_msg += " [no variants]"
181 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V20:
182 ccadf1ff Iustin Pop
          if fo_params:
183 ccadf1ff Iustin Pop
            fo_msg += (" [parameters: %s]" %
184 ccadf1ff Iustin Pop
                       utils.CommaJoin([v[0] for v in fo_params]))
185 ccadf1ff Iustin Pop
          else:
186 ccadf1ff Iustin Pop
            fo_msg += " [no parameters]"
187 ccadf1ff Iustin Pop
        if fo_status:
188 ccadf1ff Iustin Pop
          nodes_valid[node_name] = fo_msg
189 ccadf1ff Iustin Pop
        else:
190 ccadf1ff Iustin Pop
          nodes_bad[node_name] = fo_msg
191 bad78e66 Iustin Pop
        for hpath, hstatus, hmsg, _, _, _ in node_info:
192 1f9430d6 Iustin Pop
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
193 255dcebd Iustin Pop
                                         (hpath, _OsStatus(hstatus, hmsg)))
194 a8083063 Iustin Pop
      else:
195 b07a9f05 Guido Trotter
        nodes_bad[node_name] = "OS not found"
196 a8083063 Iustin Pop
197 a8083063 Iustin Pop
    if nodes_valid and not nodes_bad:
198 a8083063 Iustin Pop
      status = "valid"
199 a8083063 Iustin Pop
    elif not nodes_valid and nodes_bad:
200 a8083063 Iustin Pop
      status = "invalid"
201 a2656173 Michael Hanselmann
      has_bad = True
202 a8083063 Iustin Pop
    else:
203 a8083063 Iustin Pop
      status = "partial valid"
204 a2656173 Michael Hanselmann
      has_bad = True
205 694e2444 Guido Trotter
206 48f85f75 Guido Trotter
    def _OutputPerNodeOSStatus(msg_map):
207 48f85f75 Guido Trotter
      map_k = utils.NiceSort(msg_map.keys())
208 b07a9f05 Guido Trotter
      for node_name in map_k:
209 3a24c527 Iustin Pop
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
210 1f9430d6 Iustin Pop
        for msg in nodes_hidden[node_name]:
211 3a24c527 Iustin Pop
          ToStdout(msg)
212 b07a9f05 Guido Trotter
213 3a24c527 Iustin Pop
    ToStdout("OS: %s [global status: %s]", os_name, status)
214 e16dfb5b Guido Trotter
    if os_variants:
215 1f864b60 Iustin Pop
      ToStdout("  Variants: [%s]" % utils.CommaJoin(os_variants))
216 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_valid)
217 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_bad)
218 3a24c527 Iustin Pop
    ToStdout("")
219 a8083063 Iustin Pop
220 a2656173 Michael Hanselmann
  return int(has_bad)
221 a2656173 Michael Hanselmann
222 a8083063 Iustin Pop
223 429ae766 René Nussbaumer
def ModifyOS(opts, args):
224 429ae766 René Nussbaumer
  """Modify OS parameters for one OS.
225 429ae766 René Nussbaumer
226 429ae766 René Nussbaumer
  @param opts: the command line options selected by the user
227 429ae766 René Nussbaumer
  @type args: list
228 429ae766 René Nussbaumer
  @param args: should be a list with one entry
229 429ae766 René Nussbaumer
  @rtype: int
230 429ae766 René Nussbaumer
  @return: the desired exit code
231 429ae766 René Nussbaumer
232 429ae766 René Nussbaumer
  """
233 429ae766 René Nussbaumer
  os = args[0]
234 429ae766 René Nussbaumer
235 625ac113 Iustin Pop
  if opts.hvparams:
236 625ac113 Iustin Pop
    os_hvp = {os: dict(opts.hvparams)}
237 625ac113 Iustin Pop
  else:
238 625ac113 Iustin Pop
    os_hvp = None
239 625ac113 Iustin Pop
240 625ac113 Iustin Pop
  if opts.osparams:
241 625ac113 Iustin Pop
    osp = {os: opts.osparams}
242 625ac113 Iustin Pop
  else:
243 625ac113 Iustin Pop
    osp = None
244 625ac113 Iustin Pop
245 625ac113 Iustin Pop
  if not (os_hvp or osp):
246 625ac113 Iustin Pop
    ToStderr("At least one of OS parameters or hypervisor parameters"
247 625ac113 Iustin Pop
             " must be passed")
248 625ac113 Iustin Pop
    return 1
249 625ac113 Iustin Pop
250 429ae766 René Nussbaumer
  op = opcodes.OpSetClusterParams(vg_name=None,
251 429ae766 René Nussbaumer
                                  enabled_hypervisors=None,
252 429ae766 René Nussbaumer
                                  hvparams=None,
253 429ae766 René Nussbaumer
                                  beparams=None,
254 429ae766 René Nussbaumer
                                  nicparams=None,
255 429ae766 René Nussbaumer
                                  candidate_pool_size=None,
256 625ac113 Iustin Pop
                                  os_hvp=os_hvp,
257 625ac113 Iustin Pop
                                  osparams=osp)
258 48418fea Iustin Pop
  SubmitOpCode(op, opts=opts)
259 429ae766 René Nussbaumer
260 429ae766 René Nussbaumer
  return 0
261 429ae766 René Nussbaumer
262 429ae766 René Nussbaumer
263 a8083063 Iustin Pop
commands = {
264 6ea815cf Iustin Pop
  'list': (
265 625ac113 Iustin Pop
    ListOS, ARGS_NONE, [NOHDR_OPT], "", "Lists all valid operating systems"
266 625ac113 Iustin Pop
    " on the cluster"),
267 6ea815cf Iustin Pop
  'diagnose': (
268 625ac113 Iustin Pop
    DiagnoseOS, ARGS_NONE, [], "", "Diagnose all operating systems"),
269 ae5b1530 Iustin Pop
  'info': (
270 ae5b1530 Iustin Pop
    ShowOSInfo, [ArgOs()], [], "", "Show detailed information about "
271 ae5b1530 Iustin Pop
    "operating systems"),
272 429ae766 René Nussbaumer
  'modify': (
273 db5a8a2d Iustin Pop
    ModifyOS, ARGS_ONE_OS, [HVLIST_OPT, OSPARAMS_OPT, DRY_RUN_OPT], "",
274 625ac113 Iustin Pop
    "Modify the OS parameters"),
275 a8083063 Iustin Pop
  }
276 a8083063 Iustin Pop
277 a8083063 Iustin Pop
if __name__ == '__main__':
278 3ecf6786 Iustin Pop
  sys.exit(GenericMain(commands))