Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-os @ 107b0ccb

History | View | Annotate | Download (5.7 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 cc0451f3 Guido Trotter
    raise errors.ProgrammerError("unknown OS diagnose type: '%s'" % type(obj))
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 5efc50fc Guido Trotter
    return "valid"
79 fbdb07b9 Guido Trotter
  else:
80 5efc50fc Guido Trotter
    return obj.args[2]
81 5efc50fc Guido Trotter
82 5efc50fc Guido Trotter
83 5efc50fc Guido Trotter
def _DiagnoseOSPath(obj):
84 5efc50fc Guido Trotter
  """Get the path out of an OS diagnose object.
85 5efc50fc Guido Trotter
86 5efc50fc Guido Trotter
    Args:
87 5efc50fc Guido Trotter
      obj: an diagnostic object as returned by OpDiagnoseOS
88 5efc50fc Guido Trotter
89 5efc50fc Guido Trotter
    Returns:
90 5efc50fc Guido Trotter
      string: the OS path
91 5efc50fc Guido Trotter
92 5efc50fc Guido Trotter
  """
93 5efc50fc Guido Trotter
  if _DiagnoseOSValid(obj):
94 5efc50fc Guido Trotter
    return obj.path
95 5efc50fc Guido Trotter
  else:
96 5efc50fc Guido Trotter
    return obj.args[1]
97 fbdb07b9 Guido Trotter
98 fbdb07b9 Guido Trotter
99 fbdb07b9 Guido Trotter
def _DiagnoseByOS(rlist):
100 216fe2f3 Guido Trotter
  """Remap an OpDiagnoseOS() return list into an a per-os per-node dictionary
101 216fe2f3 Guido Trotter
102 216fe2f3 Guido Trotter
    Args:
103 216fe2f3 Guido Trotter
      rlist: a map with nodes as keys and diagnoseobjects as values
104 216fe2f3 Guido Trotter
105 216fe2f3 Guido Trotter
    Returns:
106 216fe2f3 Guido Trotter
      map: a map with osnames as keys and as value another map, with nodes as
107 216fe2f3 Guido Trotter
           keys and diagnoseobjects as values
108 216fe2f3 Guido Trotter
           e.g. {"debian-etch": {"node1": <object>, "node2": <object>}}
109 216fe2f3 Guido Trotter
  """
110 216fe2f3 Guido Trotter
111 216fe2f3 Guido Trotter
  all_os = {}
112 216fe2f3 Guido Trotter
  for node_name, nr in rlist.iteritems():
113 216fe2f3 Guido Trotter
    if not nr:
114 216fe2f3 Guido Trotter
      continue
115 216fe2f3 Guido Trotter
    for obj in nr:
116 fbdb07b9 Guido Trotter
      os_name = _DiagnoseOSName(obj)
117 216fe2f3 Guido Trotter
      if os_name not in all_os:
118 216fe2f3 Guido Trotter
        all_os[os_name] = {}
119 216fe2f3 Guido Trotter
      if node_name not in all_os[os_name]:
120 216fe2f3 Guido Trotter
        all_os[os_name][node_name] = []
121 216fe2f3 Guido Trotter
      all_os[os_name][node_name].append(obj)
122 216fe2f3 Guido Trotter
123 216fe2f3 Guido Trotter
  return all_os
124 216fe2f3 Guido Trotter
125 fbdb07b9 Guido Trotter
126 a8083063 Iustin Pop
def ListOS(opts, args):
127 a8083063 Iustin Pop
  """List the OSes existing on this node.
128 a8083063 Iustin Pop
129 a8083063 Iustin Pop
  """
130 a8083063 Iustin Pop
  op = opcodes.OpDiagnoseOS()
131 a8083063 Iustin Pop
  result = SubmitOpCode(op)
132 a8083063 Iustin Pop
133 a8083063 Iustin Pop
  if not result:
134 a8083063 Iustin Pop
    logger.ToStdout("Can't get the OS list")
135 a8083063 Iustin Pop
    return 1
136 a8083063 Iustin Pop
137 216fe2f3 Guido Trotter
  node_data = result
138 216fe2f3 Guido Trotter
  num_nodes = len(node_data)
139 fbdb07b9 Guido Trotter
  all_os = _DiagnoseByOS(node_data)
140 216fe2f3 Guido Trotter
141 216fe2f3 Guido Trotter
  valid_os = []
142 216fe2f3 Guido Trotter
  for os_name, os_node_data in all_os.iteritems():
143 216fe2f3 Guido Trotter
    if len(os_node_data) != num_nodes:
144 216fe2f3 Guido Trotter
      continue
145 cc0451f3 Guido Trotter
146 cc0451f3 Guido Trotter
    if utils.all(os_node_data.values(), lambda l: _DiagnoseOSValid(l[0])):
147 216fe2f3 Guido Trotter
      valid_os.append(os_name)
148 a8083063 Iustin Pop
149 a8083063 Iustin Pop
  if not opts.no_headers:
150 606d909d Michael Hanselmann
    headers = {"name": "Name"}
151 606d909d Michael Hanselmann
  else:
152 606d909d Michael Hanselmann
    headers = None
153 a8083063 Iustin Pop
154 16be8703 Iustin Pop
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
155 216fe2f3 Guido Trotter
                       data=[[os] for os in valid_os])
156 16be8703 Iustin Pop
157 16be8703 Iustin Pop
  for line in data:
158 16be8703 Iustin Pop
    logger.ToStdout(line)
159 a8083063 Iustin Pop
160 a8083063 Iustin Pop
  return 0
161 a8083063 Iustin Pop
162 b07a9f05 Guido Trotter
163 a8083063 Iustin Pop
def DiagnoseOS(opts, args):
164 a8083063 Iustin Pop
  """Analyse all OSes on this cluster.
165 a8083063 Iustin Pop
166 a8083063 Iustin Pop
  """
167 a8083063 Iustin Pop
  op = opcodes.OpDiagnoseOS()
168 a8083063 Iustin Pop
  result = SubmitOpCode(op)
169 a8083063 Iustin Pop
170 a8083063 Iustin Pop
  if not result:
171 a8083063 Iustin Pop
    logger.ToStdout("Can't get the OS list")
172 a8083063 Iustin Pop
    return 1
173 a8083063 Iustin Pop
174 a8083063 Iustin Pop
  node_data = result
175 fbdb07b9 Guido Trotter
  all_os = _DiagnoseByOS(node_data)
176 216fe2f3 Guido Trotter
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 48f85f75 Guido Trotter
        first_os_msg = ("%s (path: %s)" %
186 48f85f75 Guido Trotter
                        (_DiagnoseOSStatus(first_os),
187 48f85f75 Guido Trotter
                         _DiagnoseOSPath(first_os)))
188 b07a9f05 Guido Trotter
        if _DiagnoseOSValid(first_os):
189 48f85f75 Guido Trotter
          nodes_valid[node_name] = first_os_msg
190 b07a9f05 Guido Trotter
        else:
191 48f85f75 Guido Trotter
          nodes_bad[node_name] = first_os_msg
192 a8083063 Iustin Pop
      else:
193 b07a9f05 Guido Trotter
        nodes_bad[node_name] = "OS not found"
194 a8083063 Iustin Pop
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 b07a9f05 Guido Trotter
    def _OutputNodeHiddenOSStatus(dobj_list):
205 b07a9f05 Guido Trotter
      for dobj in dobj_list:
206 107b0ccb Guido Trotter
        logger.ToStdout("    [hidden] path: %s, status: %s" % 
207 107b0ccb Guido Trotter
                        (_DiagnoseOSPath(dobj), _DiagnoseOSStatus(dobj)))
208 b07a9f05 Guido Trotter
209 48f85f75 Guido Trotter
    def _OutputPerNodeOSStatus(msg_map):
210 48f85f75 Guido Trotter
      map_k = utils.NiceSort(msg_map.keys())
211 b07a9f05 Guido Trotter
      for node_name in map_k:
212 107b0ccb Guido Trotter
        logger.ToStdout("  Node: %s, status: %s" % 
213 107b0ccb Guido Trotter
                        (node_name, msg_map[node_name]))
214 b07a9f05 Guido Trotter
        if node_name in all_os[os_name]:
215 b07a9f05 Guido Trotter
          _OutputNodeHiddenOSStatus(all_os[os_name][node_name])
216 b07a9f05 Guido Trotter
217 107b0ccb Guido Trotter
    logger.ToStdout("OS: %s [global status: %s]" % (os_name, status))
218 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_valid)
219 b07a9f05 Guido Trotter
    _OutputPerNodeOSStatus(nodes_bad)
220 a8083063 Iustin Pop
221 a2656173 Michael Hanselmann
  return int(has_bad)
222 a2656173 Michael Hanselmann
223 a8083063 Iustin Pop
224 a8083063 Iustin Pop
commands = {
225 a8083063 Iustin Pop
  'list': (ListOS, ARGS_NONE, [DEBUG_OPT, NOHDR_OPT], "",
226 a8083063 Iustin Pop
           "Lists all valid OSes on the master"),
227 a8083063 Iustin Pop
  'diagnose': (DiagnoseOS, ARGS_NONE, [DEBUG_OPT], "",
228 a8083063 Iustin Pop
               "Diagnose all OSes"),
229 a8083063 Iustin Pop
  }
230 a8083063 Iustin Pop
231 a8083063 Iustin Pop
if __name__ == '__main__':
232 3ecf6786 Iustin Pop
  sys.exit(GenericMain(commands))