gnt-os 4.33 KB
Newer Older
Iustin Pop's avatar
Iustin Pop committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/python
#

# Copyright (C) 2006, 2007 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.


import sys
from optparse import make_option

from ganeti.cli import *
from ganeti import opcodes
from ganeti import logger
from ganeti import objects
from ganeti import utils
from ganeti import errors

32
33

def _DiagnoseByOS(rlist):
Guido Trotter's avatar
Guido Trotter committed
34
35
36
37
38
39
40
41
42
43
  """Remap an OpDiagnoseOS() return list into an a per-os per-node dictionary

    Args:
      rlist: a map with nodes as keys and diagnoseobjects as values

    Returns:
      map: a map with osnames as keys and as value another map, with nodes as
           keys and diagnoseobjects as values
           e.g. {"debian-etch": {"node1": <object>, "node2": <object>}}

44
  """
Guido Trotter's avatar
Guido Trotter committed
45
46
47
48
  all_os = {}
  for node_name, nr in rlist.iteritems():
    if not nr:
      continue
49
50
51
52
53
54
    for os in nr:
      if os.name not in all_os:
        all_os[os.name] = {}
      if node_name not in all_os[os.name]:
        all_os[os.name][node_name] = []
      all_os[os.name][node_name].append(os)
Guido Trotter's avatar
Guido Trotter committed
55
56
57

  return all_os

58

Iustin Pop's avatar
Iustin Pop committed
59
60
61
62
63
64
65
66
67
68
69
def ListOS(opts, args):
  """List the OSes existing on this node.

  """
  op = opcodes.OpDiagnoseOS()
  result = SubmitOpCode(op)

  if not result:
    logger.ToStdout("Can't get the OS list")
    return 1

Guido Trotter's avatar
Guido Trotter committed
70
71
  node_data = result
  num_nodes = len(node_data)
72
  all_os = _DiagnoseByOS(node_data)
Guido Trotter's avatar
Guido Trotter committed
73
74
75
76
77

  valid_os = []
  for os_name, os_node_data in all_os.iteritems():
    if len(os_node_data) != num_nodes:
      continue
78

79
    if utils.all(os_node_data.values(), lambda l: l[0]):
Guido Trotter's avatar
Guido Trotter committed
80
      valid_os.append(os_name)
Iustin Pop's avatar
Iustin Pop committed
81
82

  if not opts.no_headers:
83
84
85
    headers = {"name": "Name"}
  else:
    headers = None
Iustin Pop's avatar
Iustin Pop committed
86

87
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
Guido Trotter's avatar
Guido Trotter committed
88
                       data=[[os] for os in valid_os])
89
90
91

  for line in data:
    logger.ToStdout(line)
Iustin Pop's avatar
Iustin Pop committed
92
93
94

  return 0

Guido Trotter's avatar
Guido Trotter committed
95

Iustin Pop's avatar
Iustin Pop committed
96
97
98
99
100
101
102
103
104
105
106
107
def DiagnoseOS(opts, args):
  """Analyse all OSes on this cluster.

  """
  op = opcodes.OpDiagnoseOS()
  result = SubmitOpCode(op)

  if not result:
    logger.ToStdout("Can't get the OS list")
    return 1

  node_data = result
108
  all_os = _DiagnoseByOS(node_data)
Guido Trotter's avatar
Guido Trotter committed
109

110
111
  has_bad = False

Iustin Pop's avatar
Iustin Pop committed
112
  for os_name in all_os:
Guido Trotter's avatar
Guido Trotter committed
113
    nodes_valid = {}
Iustin Pop's avatar
Iustin Pop committed
114
115
    nodes_bad = {}
    for node_name in node_data:
116
      if node_name in all_os[os_name]:
Guido Trotter's avatar
Guido Trotter committed
117
        first_os = all_os[os_name][node_name].pop(0)
118
        first_os_msg = ("%s (path: %s)" %
119
120
                        (first_os.status, first_os.path))
        if first_os:
121
          nodes_valid[node_name] = first_os_msg
Guido Trotter's avatar
Guido Trotter committed
122
        else:
123
          nodes_bad[node_name] = first_os_msg
Iustin Pop's avatar
Iustin Pop committed
124
      else:
Guido Trotter's avatar
Guido Trotter committed
125
        nodes_bad[node_name] = "OS not found"
Iustin Pop's avatar
Iustin Pop committed
126
127
128
129
130

    if nodes_valid and not nodes_bad:
      status = "valid"
    elif not nodes_valid and nodes_bad:
      status = "invalid"
131
      has_bad = True
Iustin Pop's avatar
Iustin Pop committed
132
133
    else:
      status = "partial valid"
134
      has_bad = True
135

Guido Trotter's avatar
Guido Trotter committed
136
137
    def _OutputNodeHiddenOSStatus(dobj_list):
      for dobj in dobj_list:
138
        logger.ToStdout("    [hidden] path: %s, status: %s" %
139
                        (dobj.path, dobj.status))
Guido Trotter's avatar
Guido Trotter committed
140

141
142
    def _OutputPerNodeOSStatus(msg_map):
      map_k = utils.NiceSort(msg_map.keys())
Guido Trotter's avatar
Guido Trotter committed
143
      for node_name in map_k:
144
        logger.ToStdout("  Node: %s, status: %s" %
145
                        (node_name, msg_map[node_name]))
Guido Trotter's avatar
Guido Trotter committed
146
147
148
        if node_name in all_os[os_name]:
          _OutputNodeHiddenOSStatus(all_os[os_name][node_name])

149
    logger.ToStdout("OS: %s [global status: %s]" % (os_name, status))
Guido Trotter's avatar
Guido Trotter committed
150
151
    _OutputPerNodeOSStatus(nodes_valid)
    _OutputPerNodeOSStatus(nodes_bad)
152
    logger.ToStdout("")
Iustin Pop's avatar
Iustin Pop committed
153

154
155
  return int(has_bad)

Iustin Pop's avatar
Iustin Pop committed
156
157
158
159
160
161
162
163
164

commands = {
  'list': (ListOS, ARGS_NONE, [DEBUG_OPT, NOHDR_OPT], "",
           "Lists all valid OSes on the master"),
  'diagnose': (DiagnoseOS, ARGS_NONE, [DEBUG_OPT], "",
               "Diagnose all OSes"),
  }

if __name__ == '__main__':
165
  sys.exit(GenericMain(commands))