Statistics
| Branch: | Tag: | Revision:

root / lib / client / gnt_os.py @ 37a978e7

History | View | Annotate | Download (8.3 kB)

1 6d50f5f9 Michael Hanselmann
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 58bc8fbc Iustin Pop
# Copyright (C) 2006, 2007, 2010, 2013 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 b459a848 Andrea Spadaccini
# pylint: disable=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
from ganeti.cli import *
30 ccadf1ff Iustin Pop
from ganeti import constants
31 a8083063 Iustin Pop
from ganeti import opcodes
32 a8083063 Iustin Pop
from ganeti import utils
33 216fe2f3 Guido Trotter
34 fbdb07b9 Guido Trotter
35 a8083063 Iustin Pop
def ListOS(opts, args):
36 6099bfcf Iustin Pop
  """List the valid OSes in the cluster.
37 6099bfcf Iustin Pop

38 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
39 6099bfcf Iustin Pop
  @type args: list
40 6099bfcf Iustin Pop
  @param args: should be an empty list
41 6099bfcf Iustin Pop
  @rtype: int
42 6099bfcf Iustin Pop
  @return: the desired exit code
43 a8083063 Iustin Pop

44 a8083063 Iustin Pop
  """
45 da2d02e7 Iustin Pop
  op = opcodes.OpOsDiagnose(output_fields=["name", "variants"], names=[])
46 400ca2f7 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
47 a8083063 Iustin Pop
48 a8083063 Iustin Pop
  if not opts.no_headers:
49 606d909d Michael Hanselmann
    headers = {"name": "Name"}
50 606d909d Michael Hanselmann
  else:
51 606d909d Michael Hanselmann
    headers = None
52 a8083063 Iustin Pop
53 e3ac208c Guido Trotter
  os_names = []
54 d22dfef7 Iustin Pop
  for (name, variants) in result:
55 d22dfef7 Iustin Pop
    os_names.extend([[n] for n in CalculateOSNames(name, variants)])
56 e3ac208c Guido Trotter
57 16be8703 Iustin Pop
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
58 e3ac208c Guido Trotter
                       data=os_names, units=None)
59 16be8703 Iustin Pop
60 16be8703 Iustin Pop
  for line in data:
61 3a24c527 Iustin Pop
    ToStdout(line)
62 a8083063 Iustin Pop
63 a8083063 Iustin Pop
  return 0
64 a8083063 Iustin Pop
65 b07a9f05 Guido Trotter
66 ae5b1530 Iustin Pop
def ShowOSInfo(opts, args):
67 ae5b1530 Iustin Pop
  """List detailed information about OSes in the cluster.
68 ae5b1530 Iustin Pop

69 ae5b1530 Iustin Pop
  @param opts: the command line options selected by the user
70 ae5b1530 Iustin Pop
  @type args: list
71 ae5b1530 Iustin Pop
  @param args: should be an empty list
72 ae5b1530 Iustin Pop
  @rtype: int
73 ae5b1530 Iustin Pop
  @return: the desired exit code
74 ae5b1530 Iustin Pop

75 ae5b1530 Iustin Pop
  """
76 da2d02e7 Iustin Pop
  op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
77 c950e9f2 Iustin Pop
                                           "parameters", "api_versions",
78 c950e9f2 Iustin Pop
                                           "blacklisted", "hidden"],
79 ae5b1530 Iustin Pop
                            names=[])
80 ae5b1530 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
81 ae5b1530 Iustin Pop
82 ae5b1530 Iustin Pop
  if not result:
83 ae5b1530 Iustin Pop
    ToStderr("Can't get the OS list")
84 ae5b1530 Iustin Pop
    return 1
85 ae5b1530 Iustin Pop
86 ae5b1530 Iustin Pop
  do_filter = bool(args)
87 ae5b1530 Iustin Pop
88 c950e9f2 Iustin Pop
  for (name, valid, variants, parameters, api_versions, blk, hid) in result:
89 ae5b1530 Iustin Pop
    if do_filter:
90 ae5b1530 Iustin Pop
      if name not in args:
91 ae5b1530 Iustin Pop
        continue
92 ae5b1530 Iustin Pop
      else:
93 ae5b1530 Iustin Pop
        args.remove(name)
94 ae5b1530 Iustin Pop
    ToStdout("%s:", name)
95 ae5b1530 Iustin Pop
    ToStdout("  - valid: %s", valid)
96 c950e9f2 Iustin Pop
    ToStdout("  - hidden: %s", hid)
97 c950e9f2 Iustin Pop
    ToStdout("  - blacklisted: %s", blk)
98 ae5b1530 Iustin Pop
    if valid:
99 ae5b1530 Iustin Pop
      ToStdout("  - API versions:")
100 ae5b1530 Iustin Pop
      for version in sorted(api_versions):
101 ae5b1530 Iustin Pop
        ToStdout("    - %s", version)
102 ae5b1530 Iustin Pop
      ToStdout("  - variants:")
103 ae5b1530 Iustin Pop
      for vname in variants:
104 ae5b1530 Iustin Pop
        ToStdout("    - %s", vname)
105 ae5b1530 Iustin Pop
      ToStdout("  - parameters:")
106 ae5b1530 Iustin Pop
      for pname, pdesc in parameters:
107 ae5b1530 Iustin Pop
        ToStdout("    - %s: %s", pname, pdesc)
108 ae5b1530 Iustin Pop
    ToStdout("")
109 ae5b1530 Iustin Pop
110 ae5b1530 Iustin Pop
  if args:
111 ae5b1530 Iustin Pop
    for name in args:
112 ae5b1530 Iustin Pop
      ToStdout("%s: ", name)
113 ae5b1530 Iustin Pop
      ToStdout("")
114 ae5b1530 Iustin Pop
115 ae5b1530 Iustin Pop
  return 0
116 ae5b1530 Iustin Pop
117 ae5b1530 Iustin Pop
118 255dcebd Iustin Pop
def _OsStatus(status, diagnose):
119 255dcebd Iustin Pop
  """Beautifier function for OS status.
120 255dcebd Iustin Pop

121 255dcebd Iustin Pop
  @type status: boolean
122 255dcebd Iustin Pop
  @param status: is the OS valid
123 255dcebd Iustin Pop
  @type diagnose: string
124 255dcebd Iustin Pop
  @param diagnose: the error message for invalid OSes
125 255dcebd Iustin Pop
  @rtype: string
126 255dcebd Iustin Pop
  @return: a formatted status
127 255dcebd Iustin Pop

128 255dcebd Iustin Pop
  """
129 255dcebd Iustin Pop
  if status:
130 255dcebd Iustin Pop
    return "valid"
131 255dcebd Iustin Pop
  else:
132 255dcebd Iustin Pop
    return "invalid - %s" % diagnose
133 255dcebd Iustin Pop
134 af1a81d1 Michael Hanselmann
135 a8083063 Iustin Pop
def DiagnoseOS(opts, args):
136 a8083063 Iustin Pop
  """Analyse all OSes on this cluster.
137 a8083063 Iustin Pop

138 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
139 6099bfcf Iustin Pop
  @type args: list
140 6099bfcf Iustin Pop
  @param args: should be an empty list
141 6099bfcf Iustin Pop
  @rtype: int
142 6099bfcf Iustin Pop
  @return: the desired exit code
143 6099bfcf Iustin Pop

144 a8083063 Iustin Pop
  """
145 da2d02e7 Iustin Pop
  op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
146 c950e9f2 Iustin Pop
                                           "node_status", "hidden",
147 c950e9f2 Iustin Pop
                                           "blacklisted"], names=[])
148 400ca2f7 Iustin Pop
  result = SubmitOpCode(op, opts=opts)
149 a8083063 Iustin Pop
150 a8083063 Iustin Pop
  if not result:
151 3a24c527 Iustin Pop
    ToStderr("Can't get the OS list")
152 a8083063 Iustin Pop
    return 1
153 a8083063 Iustin Pop
154 a2656173 Michael Hanselmann
  has_bad = False
155 a2656173 Michael Hanselmann
156 c950e9f2 Iustin Pop
  for os_name, _, os_variants, node_data, hid, blk in result:
157 b07a9f05 Guido Trotter
    nodes_valid = {}
158 a8083063 Iustin Pop
    nodes_bad = {}
159 1f9430d6 Iustin Pop
    nodes_hidden = {}
160 1f9430d6 Iustin Pop
    for node_name, node_info in node_data.iteritems():
161 1f9430d6 Iustin Pop
      nodes_hidden[node_name] = []
162 1f9430d6 Iustin Pop
      if node_info: # at least one entry in the per-node list
163 ccadf1ff Iustin Pop
        (fo_path, fo_status, fo_msg, fo_variants,
164 ccadf1ff Iustin Pop
         fo_params, fo_api) = node_info.pop(0)
165 ccadf1ff Iustin Pop
        fo_msg = "%s (path: %s)" % (_OsStatus(fo_status, fo_msg), fo_path)
166 ccadf1ff Iustin Pop
        if fo_api:
167 ccadf1ff Iustin Pop
          max_os_api = max(fo_api)
168 ccadf1ff Iustin Pop
          fo_msg += " [API versions: %s]" % utils.CommaJoin(fo_api)
169 b07a9f05 Guido Trotter
        else:
170 ccadf1ff Iustin Pop
          max_os_api = 0
171 ccadf1ff Iustin Pop
          fo_msg += " [no API versions declared]"
172 c950e9f2 Iustin Pop
173 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V15:
174 ccadf1ff Iustin Pop
          if fo_variants:
175 ccadf1ff Iustin Pop
            fo_msg += " [variants: %s]" % utils.CommaJoin(fo_variants)
176 ccadf1ff Iustin Pop
          else:
177 ccadf1ff Iustin Pop
            fo_msg += " [no variants]"
178 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V20:
179 ccadf1ff Iustin Pop
          if fo_params:
180 ccadf1ff Iustin Pop
            fo_msg += (" [parameters: %s]" %
181 ccadf1ff Iustin Pop
                       utils.CommaJoin([v[0] for v in fo_params]))
182 ccadf1ff Iustin Pop
          else:
183 ccadf1ff Iustin Pop
            fo_msg += " [no parameters]"
184 ccadf1ff Iustin Pop
        if fo_status:
185 ccadf1ff Iustin Pop
          nodes_valid[node_name] = fo_msg
186 ccadf1ff Iustin Pop
        else:
187 ccadf1ff Iustin Pop
          nodes_bad[node_name] = fo_msg
188 bad78e66 Iustin Pop
        for hpath, hstatus, hmsg, _, _, _ in node_info:
189 1f9430d6 Iustin Pop
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
190 255dcebd Iustin Pop
                                         (hpath, _OsStatus(hstatus, hmsg)))
191 a8083063 Iustin Pop
      else:
192 b07a9f05 Guido Trotter
        nodes_bad[node_name] = "OS not found"
193 a8083063 Iustin Pop
194 2932dc44 Michael Hanselmann
    # TODO: Shouldn't the global status be calculated by the LU?
195 a8083063 Iustin Pop
    if nodes_valid and not nodes_bad:
196 a8083063 Iustin Pop
      status = "valid"
197 a8083063 Iustin Pop
    elif not nodes_valid and nodes_bad:
198 a8083063 Iustin Pop
      status = "invalid"
199 a2656173 Michael Hanselmann
      has_bad = True
200 a8083063 Iustin Pop
    else:
201 a8083063 Iustin Pop
      status = "partial valid"
202 a2656173 Michael Hanselmann
      has_bad = True
203 694e2444 Guido Trotter
204 48f85f75 Guido Trotter
    def _OutputPerNodeOSStatus(msg_map):
205 48f85f75 Guido Trotter
      map_k = utils.NiceSort(msg_map.keys())
206 b07a9f05 Guido Trotter
      for node_name in map_k:
207 3a24c527 Iustin Pop
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
208 1f9430d6 Iustin Pop
        for msg in nodes_hidden[node_name]:
209 3a24c527 Iustin Pop
          ToStdout(msg)
210 b07a9f05 Guido Trotter
211 c950e9f2 Iustin Pop
    st_msg = "OS: %s [global status: %s]" % (os_name, status)
212 c950e9f2 Iustin Pop
    if hid:
213 c950e9f2 Iustin Pop
      st_msg += " [hidden]"
214 c950e9f2 Iustin Pop
    if blk:
215 c950e9f2 Iustin Pop
      st_msg += " [blacklisted]"
216 c950e9f2 Iustin Pop
    ToStdout(st_msg)
217 e16dfb5b Guido Trotter
    if os_variants:
218 1f864b60 Iustin Pop
      ToStdout("  Variants: [%s]" % utils.CommaJoin(os_variants))
219 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_valid)
220 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_bad)
221 3a24c527 Iustin Pop
    ToStdout("")
222 a8083063 Iustin Pop
223 a2656173 Michael Hanselmann
  return int(has_bad)
224 a2656173 Michael Hanselmann
225 a8083063 Iustin Pop
226 429ae766 René Nussbaumer
def ModifyOS(opts, args):
227 429ae766 René Nussbaumer
  """Modify OS parameters for one OS.
228 429ae766 René Nussbaumer

229 429ae766 René Nussbaumer
  @param opts: the command line options selected by the user
230 429ae766 René Nussbaumer
  @type args: list
231 429ae766 René Nussbaumer
  @param args: should be a list with one entry
232 429ae766 René Nussbaumer
  @rtype: int
233 429ae766 René Nussbaumer
  @return: the desired exit code
234 429ae766 René Nussbaumer

235 429ae766 René Nussbaumer
  """
236 429ae766 René Nussbaumer
  os = args[0]
237 429ae766 René Nussbaumer
238 625ac113 Iustin Pop
  if opts.hvparams:
239 625ac113 Iustin Pop
    os_hvp = {os: dict(opts.hvparams)}
240 625ac113 Iustin Pop
  else:
241 625ac113 Iustin Pop
    os_hvp = None
242 625ac113 Iustin Pop
243 625ac113 Iustin Pop
  if opts.osparams:
244 625ac113 Iustin Pop
    osp = {os: opts.osparams}
245 625ac113 Iustin Pop
  else:
246 625ac113 Iustin Pop
    osp = None
247 625ac113 Iustin Pop
248 61a14bb3 Iustin Pop
  if opts.hidden is not None:
249 61a14bb3 Iustin Pop
    if opts.hidden:
250 61a14bb3 Iustin Pop
      ohid = [(constants.DDM_ADD, os)]
251 61a14bb3 Iustin Pop
    else:
252 61a14bb3 Iustin Pop
      ohid = [(constants.DDM_REMOVE, os)]
253 61a14bb3 Iustin Pop
  else:
254 61a14bb3 Iustin Pop
    ohid = None
255 61a14bb3 Iustin Pop
256 61a14bb3 Iustin Pop
  if opts.blacklisted is not None:
257 61a14bb3 Iustin Pop
    if opts.blacklisted:
258 61a14bb3 Iustin Pop
      oblk = [(constants.DDM_ADD, os)]
259 61a14bb3 Iustin Pop
    else:
260 61a14bb3 Iustin Pop
      oblk = [(constants.DDM_REMOVE, os)]
261 61a14bb3 Iustin Pop
  else:
262 61a14bb3 Iustin Pop
    oblk = None
263 61a14bb3 Iustin Pop
264 61a14bb3 Iustin Pop
  if not (os_hvp or osp or ohid or oblk):
265 625ac113 Iustin Pop
    ToStderr("At least one of OS parameters or hypervisor parameters"
266 625ac113 Iustin Pop
             " must be passed")
267 625ac113 Iustin Pop
    return 1
268 625ac113 Iustin Pop
269 a6682fdc Iustin Pop
  op = opcodes.OpClusterSetParams(os_hvp=os_hvp,
270 61a14bb3 Iustin Pop
                                  osparams=osp,
271 87b2cd45 Iustin Pop
                                  hidden_os=ohid,
272 87b2cd45 Iustin Pop
                                  blacklisted_os=oblk)
273 ed4d8889 Michael Hanselmann
  SubmitOrSend(op, opts)
274 429ae766 René Nussbaumer
275 429ae766 René Nussbaumer
  return 0
276 429ae766 René Nussbaumer
277 429ae766 René Nussbaumer
278 a8083063 Iustin Pop
commands = {
279 d0c8c01d Iustin Pop
  "list": (
280 aa06f8c6 Michael Hanselmann
    ListOS, ARGS_NONE, [NOHDR_OPT, PRIORITY_OPT],
281 aa06f8c6 Michael Hanselmann
    "", "Lists all valid operating systems on the cluster"),
282 d0c8c01d Iustin Pop
  "diagnose": (
283 aa06f8c6 Michael Hanselmann
    DiagnoseOS, ARGS_NONE, [PRIORITY_OPT],
284 aa06f8c6 Michael Hanselmann
    "", "Diagnose all operating systems"),
285 d0c8c01d Iustin Pop
  "info": (
286 aa06f8c6 Michael Hanselmann
    ShowOSInfo, [ArgOs()], [PRIORITY_OPT],
287 aa06f8c6 Michael Hanselmann
    "", "Show detailed information about "
288 ae5b1530 Iustin Pop
    "operating systems"),
289 d0c8c01d Iustin Pop
  "modify": (
290 aa06f8c6 Michael Hanselmann
    ModifyOS, ARGS_ONE_OS,
291 df5758b1 Iustin Pop
    [HVLIST_OPT, OSPARAMS_OPT, DRY_RUN_OPT, PRIORITY_OPT,
292 ed4d8889 Michael Hanselmann
     HID_OS_OPT, BLK_OS_OPT, SUBMIT_OPT],
293 aa06f8c6 Michael Hanselmann
    "", "Modify the OS parameters"),
294 a8083063 Iustin Pop
  }
295 a8083063 Iustin Pop
296 96897af7 Alexander Schreiber
#: dictionary with aliases for commands
297 96897af7 Alexander Schreiber
aliases = {
298 96897af7 Alexander Schreiber
  "show": "info",
299 96897af7 Alexander Schreiber
  }
300 96897af7 Alexander Schreiber
301 6d50f5f9 Michael Hanselmann
302 6d50f5f9 Michael Hanselmann
def Main():
303 96897af7 Alexander Schreiber
  return GenericMain(commands, aliases=aliases)