Statistics
| Branch: | Tag: | Revision:

root / lib / client / gnt_os.py @ f8fa4175

History | View | Annotate | Download (8.2 kB)

1 6d50f5f9 Michael Hanselmann
#
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
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 result:
49 3a24c527 Iustin Pop
    ToStderr("Can't get the OS list")
50 a8083063 Iustin Pop
    return 1
51 a8083063 Iustin Pop
52 a8083063 Iustin Pop
  if not opts.no_headers:
53 606d909d Michael Hanselmann
    headers = {"name": "Name"}
54 606d909d Michael Hanselmann
  else:
55 606d909d Michael Hanselmann
    headers = None
56 a8083063 Iustin Pop
57 e3ac208c Guido Trotter
  os_names = []
58 d22dfef7 Iustin Pop
  for (name, variants) in result:
59 d22dfef7 Iustin Pop
    os_names.extend([[n] for n in CalculateOSNames(name, variants)])
60 e3ac208c Guido Trotter
61 16be8703 Iustin Pop
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
62 e3ac208c Guido Trotter
                       data=os_names, units=None)
63 16be8703 Iustin Pop
64 16be8703 Iustin Pop
  for line in data:
65 3a24c527 Iustin Pop
    ToStdout(line)
66 a8083063 Iustin Pop
67 a8083063 Iustin Pop
  return 0
68 a8083063 Iustin Pop
69 b07a9f05 Guido Trotter
70 ae5b1530 Iustin Pop
def ShowOSInfo(opts, args):
71 ae5b1530 Iustin Pop
  """List detailed information about OSes in the cluster.
72 ae5b1530 Iustin Pop

73 ae5b1530 Iustin Pop
  @param opts: the command line options selected by the user
74 ae5b1530 Iustin Pop
  @type args: list
75 ae5b1530 Iustin Pop
  @param args: should be an empty list
76 ae5b1530 Iustin Pop
  @rtype: int
77 ae5b1530 Iustin Pop
  @return: the desired exit code
78 ae5b1530 Iustin Pop

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

125 255dcebd Iustin Pop
  @type status: boolean
126 255dcebd Iustin Pop
  @param status: is the OS valid
127 255dcebd Iustin Pop
  @type diagnose: string
128 255dcebd Iustin Pop
  @param diagnose: the error message for invalid OSes
129 255dcebd Iustin Pop
  @rtype: string
130 255dcebd Iustin Pop
  @return: a formatted status
131 255dcebd Iustin Pop

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

142 6099bfcf Iustin Pop
  @param opts: the command line options selected by the user
143 6099bfcf Iustin Pop
  @type args: list
144 6099bfcf Iustin Pop
  @param args: should be an empty list
145 6099bfcf Iustin Pop
  @rtype: int
146 6099bfcf Iustin Pop
  @return: the desired exit code
147 6099bfcf Iustin Pop

148 a8083063 Iustin Pop
  """
149 da2d02e7 Iustin Pop
  op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
150 c950e9f2 Iustin Pop
                                           "node_status", "hidden",
151 c950e9f2 Iustin Pop
                                           "blacklisted"], 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 c950e9f2 Iustin Pop
  for os_name, _, os_variants, node_data, hid, blk 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 c950e9f2 Iustin Pop
177 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V15:
178 ccadf1ff Iustin Pop
          if fo_variants:
179 ccadf1ff Iustin Pop
            fo_msg += " [variants: %s]" % utils.CommaJoin(fo_variants)
180 ccadf1ff Iustin Pop
          else:
181 ccadf1ff Iustin Pop
            fo_msg += " [no variants]"
182 ccadf1ff Iustin Pop
        if max_os_api >= constants.OS_API_V20:
183 ccadf1ff Iustin Pop
          if fo_params:
184 ccadf1ff Iustin Pop
            fo_msg += (" [parameters: %s]" %
185 ccadf1ff Iustin Pop
                       utils.CommaJoin([v[0] for v in fo_params]))
186 ccadf1ff Iustin Pop
          else:
187 ccadf1ff Iustin Pop
            fo_msg += " [no parameters]"
188 ccadf1ff Iustin Pop
        if fo_status:
189 ccadf1ff Iustin Pop
          nodes_valid[node_name] = fo_msg
190 ccadf1ff Iustin Pop
        else:
191 ccadf1ff Iustin Pop
          nodes_bad[node_name] = fo_msg
192 bad78e66 Iustin Pop
        for hpath, hstatus, hmsg, _, _, _ in node_info:
193 1f9430d6 Iustin Pop
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
194 255dcebd Iustin Pop
                                         (hpath, _OsStatus(hstatus, hmsg)))
195 a8083063 Iustin Pop
      else:
196 b07a9f05 Guido Trotter
        nodes_bad[node_name] = "OS not found"
197 a8083063 Iustin Pop
198 2932dc44 Michael Hanselmann
    # TODO: Shouldn't the global status be calculated by the LU?
199 a8083063 Iustin Pop
    if nodes_valid and not nodes_bad:
200 a8083063 Iustin Pop
      status = "valid"
201 a8083063 Iustin Pop
    elif not nodes_valid and nodes_bad:
202 a8083063 Iustin Pop
      status = "invalid"
203 a2656173 Michael Hanselmann
      has_bad = True
204 a8083063 Iustin Pop
    else:
205 a8083063 Iustin Pop
      status = "partial valid"
206 a2656173 Michael Hanselmann
      has_bad = True
207 694e2444 Guido Trotter
208 48f85f75 Guido Trotter
    def _OutputPerNodeOSStatus(msg_map):
209 48f85f75 Guido Trotter
      map_k = utils.NiceSort(msg_map.keys())
210 b07a9f05 Guido Trotter
      for node_name in map_k:
211 3a24c527 Iustin Pop
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
212 1f9430d6 Iustin Pop
        for msg in nodes_hidden[node_name]:
213 3a24c527 Iustin Pop
          ToStdout(msg)
214 b07a9f05 Guido Trotter
215 c950e9f2 Iustin Pop
    st_msg = "OS: %s [global status: %s]" % (os_name, status)
216 c950e9f2 Iustin Pop
    if hid:
217 c950e9f2 Iustin Pop
      st_msg += " [hidden]"
218 c950e9f2 Iustin Pop
    if blk:
219 c950e9f2 Iustin Pop
      st_msg += " [blacklisted]"
220 c950e9f2 Iustin Pop
    ToStdout(st_msg)
221 e16dfb5b Guido Trotter
    if os_variants:
222 1f864b60 Iustin Pop
      ToStdout("  Variants: [%s]" % utils.CommaJoin(os_variants))
223 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_valid)
224 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_bad)
225 3a24c527 Iustin Pop
    ToStdout("")
226 a8083063 Iustin Pop
227 a2656173 Michael Hanselmann
  return int(has_bad)
228 a2656173 Michael Hanselmann
229 a8083063 Iustin Pop
230 429ae766 René Nussbaumer
def ModifyOS(opts, args):
231 429ae766 René Nussbaumer
  """Modify OS parameters for one OS.
232 429ae766 René Nussbaumer

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

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