Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-os @ a2656173

History | View | Annotate | Download (5.9 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 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 a8083063 Iustin Pop
22 a8083063 Iustin Pop
import sys
23 a8083063 Iustin Pop
from optparse import make_option
24 a8083063 Iustin Pop
25 a8083063 Iustin Pop
from ganeti.cli import *
26 a8083063 Iustin Pop
from ganeti import opcodes
27 a8083063 Iustin Pop
from ganeti import logger
28 a8083063 Iustin Pop
from ganeti import objects
29 a8083063 Iustin Pop
from ganeti import utils
30 a8083063 Iustin Pop
from ganeti import errors
31 a8083063 Iustin Pop
32 fbdb07b9 Guido Trotter
33 fbdb07b9 Guido Trotter
def _DiagnoseOSValid(obj):
34 fbdb07b9 Guido Trotter
  """Verify whether an OS diagnose object represents a valid OS
35 fbdb07b9 Guido Trotter
36 fbdb07b9 Guido Trotter
    Args:
37 fbdb07b9 Guido Trotter
      obj: an diagnostic object as returned by OpDiagnoseOS
38 fbdb07b9 Guido Trotter
39 fbdb07b9 Guido Trotter
    Returns:
40 fbdb07b9 Guido Trotter
      bool: OS validity status
41 fbdb07b9 Guido Trotter
  """
42 fbdb07b9 Guido Trotter
43 fbdb07b9 Guido Trotter
  if isinstance(obj, objects.OS):
44 fbdb07b9 Guido Trotter
    return True
45 fbdb07b9 Guido Trotter
  elif isinstance(obj, errors.InvalidOS):
46 fbdb07b9 Guido Trotter
    return False
47 fbdb07b9 Guido Trotter
  else:
48 fbdb07b9 Guido Trotter
    raise errors.ProgrammerError('unknown OS diagnose type')
49 fbdb07b9 Guido Trotter
50 fbdb07b9 Guido Trotter
51 fbdb07b9 Guido Trotter
def _DiagnoseOSName(obj):
52 fbdb07b9 Guido Trotter
  """Generate a status message for an OS diagnose object.
53 fbdb07b9 Guido Trotter
54 fbdb07b9 Guido Trotter
    Args:
55 fbdb07b9 Guido Trotter
      obj: an diagnostic object as returned by OpDiagnoseOS
56 fbdb07b9 Guido Trotter
57 fbdb07b9 Guido Trotter
    Returns:
58 fbdb07b9 Guido Trotter
      string: the name of the OS in question
59 fbdb07b9 Guido Trotter
  """
60 fbdb07b9 Guido Trotter
61 fbdb07b9 Guido Trotter
  if _DiagnoseOSValid(obj):
62 fbdb07b9 Guido Trotter
    return obj.name
63 fbdb07b9 Guido Trotter
  else:
64 fbdb07b9 Guido Trotter
    return obj.args[0]
65 fbdb07b9 Guido Trotter
66 fbdb07b9 Guido Trotter
67 fbdb07b9 Guido Trotter
def _DiagnoseOSStatus(obj):
68 fbdb07b9 Guido Trotter
  """Generate a status message for an OS diagnose object.
69 fbdb07b9 Guido Trotter
70 fbdb07b9 Guido Trotter
    Args:
71 fbdb07b9 Guido Trotter
      obj: an diagnostic object as returned by OpDiagnoseOS
72 fbdb07b9 Guido Trotter
73 fbdb07b9 Guido Trotter
    Returns:
74 fbdb07b9 Guido Trotter
      string: a description of the OS status
75 fbdb07b9 Guido Trotter
  """
76 fbdb07b9 Guido Trotter
77 fbdb07b9 Guido Trotter
  if _DiagnoseOSValid(obj):
78 fbdb07b9 Guido Trotter
    return "valid (path: %s)" % obj.path
79 fbdb07b9 Guido Trotter
  else:
80 fbdb07b9 Guido Trotter
    return "%s (path: %s)" % (obj.args[2], obj.args[1])
81 fbdb07b9 Guido Trotter
82 fbdb07b9 Guido Trotter
83 fbdb07b9 Guido Trotter
def _DiagnoseByOS(rlist):
84 216fe2f3 Guido Trotter
  """Remap an OpDiagnoseOS() return list into an a per-os per-node dictionary
85 216fe2f3 Guido Trotter
86 216fe2f3 Guido Trotter
    Args:
87 216fe2f3 Guido Trotter
      rlist: a map with nodes as keys and diagnoseobjects as values
88 216fe2f3 Guido Trotter
89 216fe2f3 Guido Trotter
    Returns:
90 216fe2f3 Guido Trotter
      map: a map with osnames as keys and as value another map, with nodes as
91 216fe2f3 Guido Trotter
           keys and diagnoseobjects as values
92 216fe2f3 Guido Trotter
           e.g. {"debian-etch": {"node1": <object>, "node2": <object>}}
93 216fe2f3 Guido Trotter
  """
94 216fe2f3 Guido Trotter
95 216fe2f3 Guido Trotter
  all_os = {}
96 216fe2f3 Guido Trotter
  for node_name, nr in rlist.iteritems():
97 216fe2f3 Guido Trotter
    if not nr:
98 216fe2f3 Guido Trotter
      continue
99 216fe2f3 Guido Trotter
    for obj in nr:
100 fbdb07b9 Guido Trotter
      os_name = _DiagnoseOSName(obj)
101 216fe2f3 Guido Trotter
      if os_name not in all_os:
102 216fe2f3 Guido Trotter
        all_os[os_name] = {}
103 216fe2f3 Guido Trotter
      if node_name not in all_os[os_name]:
104 216fe2f3 Guido Trotter
        all_os[os_name][node_name] = []
105 216fe2f3 Guido Trotter
      all_os[os_name][node_name].append(obj)
106 216fe2f3 Guido Trotter
107 216fe2f3 Guido Trotter
  return all_os
108 216fe2f3 Guido Trotter
109 fbdb07b9 Guido Trotter
110 a8083063 Iustin Pop
def ListOS(opts, args):
111 a8083063 Iustin Pop
  """List the OSes existing on this node.
112 a8083063 Iustin Pop
113 a8083063 Iustin Pop
  """
114 a8083063 Iustin Pop
  op = opcodes.OpDiagnoseOS()
115 a8083063 Iustin Pop
  result = SubmitOpCode(op)
116 a8083063 Iustin Pop
117 a8083063 Iustin Pop
  if not result:
118 a8083063 Iustin Pop
    logger.ToStdout("Can't get the OS list")
119 a8083063 Iustin Pop
    return 1
120 a8083063 Iustin Pop
121 216fe2f3 Guido Trotter
  node_data = result
122 216fe2f3 Guido Trotter
  num_nodes = len(node_data)
123 fbdb07b9 Guido Trotter
  all_os = _DiagnoseByOS(node_data)
124 216fe2f3 Guido Trotter
125 216fe2f3 Guido Trotter
  valid_os = []
126 216fe2f3 Guido Trotter
  for os_name, os_node_data in all_os.iteritems():
127 216fe2f3 Guido Trotter
    if len(os_node_data) != num_nodes:
128 216fe2f3 Guido Trotter
      continue
129 216fe2f3 Guido Trotter
    valid = True
130 216fe2f3 Guido Trotter
    for l in os_node_data.values():
131 216fe2f3 Guido Trotter
      if not _DiagnoseOSValid(l[0]):
132 216fe2f3 Guido Trotter
        valid = False
133 216fe2f3 Guido Trotter
        break
134 216fe2f3 Guido Trotter
    if valid:
135 216fe2f3 Guido Trotter
      valid_os.append(os_name)
136 a8083063 Iustin Pop
137 a8083063 Iustin Pop
  if not opts.no_headers:
138 606d909d Michael Hanselmann
    headers = {"name": "Name"}
139 606d909d Michael Hanselmann
  else:
140 606d909d Michael Hanselmann
    headers = None
141 a8083063 Iustin Pop
142 16be8703 Iustin Pop
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
143 216fe2f3 Guido Trotter
                       data=[[os] for os in valid_os])
144 16be8703 Iustin Pop
145 16be8703 Iustin Pop
  for line in data:
146 16be8703 Iustin Pop
    logger.ToStdout(line)
147 a8083063 Iustin Pop
148 a8083063 Iustin Pop
  return 0
149 a8083063 Iustin Pop
150 b07a9f05 Guido Trotter
151 a8083063 Iustin Pop
def DiagnoseOS(opts, args):
152 a8083063 Iustin Pop
  """Analyse all OSes on this cluster.
153 a8083063 Iustin Pop
154 a8083063 Iustin Pop
  """
155 a8083063 Iustin Pop
  op = opcodes.OpDiagnoseOS()
156 a8083063 Iustin Pop
  result = SubmitOpCode(op)
157 a8083063 Iustin Pop
158 a8083063 Iustin Pop
  if not result:
159 a8083063 Iustin Pop
    logger.ToStdout("Can't get the OS list")
160 a8083063 Iustin Pop
    return 1
161 a8083063 Iustin Pop
162 a8083063 Iustin Pop
  node_data = result
163 fbdb07b9 Guido Trotter
  all_os = _DiagnoseByOS(node_data)
164 216fe2f3 Guido Trotter
165 216fe2f3 Guido Trotter
  format = "%-*s %-*s %s"
166 a8083063 Iustin Pop
167 a8083063 Iustin Pop
  max_name = len('Name')
168 a8083063 Iustin Pop
  if all_os:
169 a8083063 Iustin Pop
    max_name = max(max_name, max([len(name) for name in all_os]))
170 a8083063 Iustin Pop
171 a8083063 Iustin Pop
  max_node = len('Status/Node')
172 a8083063 Iustin Pop
  max_node = max(max_node, max([len(name) for name in node_data]))
173 a8083063 Iustin Pop
174 a8083063 Iustin Pop
  logger.ToStdout(format % (max_name, 'Name', max_node, 'Status/Node',
175 a8083063 Iustin Pop
                            'Details'))
176 a8083063 Iustin Pop
177 a2656173 Michael Hanselmann
  has_bad = False
178 a2656173 Michael Hanselmann
179 a8083063 Iustin Pop
  for os_name in all_os:
180 b07a9f05 Guido Trotter
    nodes_valid = {}
181 a8083063 Iustin Pop
    nodes_bad = {}
182 a8083063 Iustin Pop
    for node_name in node_data:
183 694e2444 Guido Trotter
      if node_name in all_os[os_name]:
184 b07a9f05 Guido Trotter
        first_os = all_os[os_name][node_name].pop(0)
185 b07a9f05 Guido Trotter
        first_os_status = _DiagnoseOSStatus(first_os)
186 b07a9f05 Guido Trotter
        if _DiagnoseOSValid(first_os):
187 b07a9f05 Guido Trotter
          nodes_valid[node_name] = first_os_status
188 b07a9f05 Guido Trotter
        else:
189 b07a9f05 Guido Trotter
          nodes_bad[node_name] = first_os_status
190 a8083063 Iustin Pop
      else:
191 b07a9f05 Guido Trotter
        nodes_bad[node_name] = "OS not found"
192 a8083063 Iustin Pop
193 a8083063 Iustin Pop
    if nodes_valid and not nodes_bad:
194 a8083063 Iustin Pop
      status = "valid"
195 a8083063 Iustin Pop
    elif not nodes_valid and nodes_bad:
196 a8083063 Iustin Pop
      status = "invalid"
197 a2656173 Michael Hanselmann
      has_bad = True
198 a8083063 Iustin Pop
    else:
199 a8083063 Iustin Pop
      status = "partial valid"
200 a2656173 Michael Hanselmann
      has_bad = True
201 694e2444 Guido Trotter
202 b07a9f05 Guido Trotter
    def _OutputNodeHiddenOSStatus(dobj_list):
203 b07a9f05 Guido Trotter
      for dobj in dobj_list:
204 b07a9f05 Guido Trotter
        logger.ToStdout(format % (max_name, "", max_node, "",
205 b07a9f05 Guido Trotter
                                  "[hidden] %s" %
206 b07a9f05 Guido Trotter
                                  _DiagnoseOSStatus(dobj)))
207 b07a9f05 Guido Trotter
208 b07a9f05 Guido Trotter
    def _OutputPerNodeOSStatus(status_map):
209 b07a9f05 Guido Trotter
      map_k = utils.NiceSort(status_map.keys())
210 b07a9f05 Guido Trotter
      for node_name in map_k:
211 b07a9f05 Guido Trotter
        logger.ToStdout(format % (max_name, "", max_node,
212 b07a9f05 Guido Trotter
                                  node_name, status_map[node_name]))
213 b07a9f05 Guido Trotter
        if node_name in all_os[os_name]:
214 b07a9f05 Guido Trotter
          _OutputNodeHiddenOSStatus(all_os[os_name][node_name])
215 b07a9f05 Guido Trotter
216 a8083063 Iustin Pop
    logger.ToStdout(format % (max_name, os_name, max_node, status, ""))
217 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_valid)
218 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_bad)
219 a8083063 Iustin Pop
220 a2656173 Michael Hanselmann
  return int(has_bad)
221 a2656173 Michael Hanselmann
222 a8083063 Iustin Pop
223 a8083063 Iustin Pop
commands = {
224 a8083063 Iustin Pop
  'list': (ListOS, ARGS_NONE, [DEBUG_OPT, NOHDR_OPT], "",
225 a8083063 Iustin Pop
           "Lists all valid OSes on the master"),
226 a8083063 Iustin Pop
  'diagnose': (DiagnoseOS, ARGS_NONE, [DEBUG_OPT], "",
227 a8083063 Iustin Pop
               "Diagnose all OSes"),
228 a8083063 Iustin Pop
  }
229 a8083063 Iustin Pop
230 a8083063 Iustin Pop
if __name__ == '__main__':
231 3ecf6786 Iustin Pop
  sys.exit(GenericMain(commands))