gnt-os 4.63 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
#!/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.


22
23
24
25
# pylint: disable-msg=W0401,W0614
# W0401: Wildcard import ganeti.cli
# W0614: Unused import %s from wildcard import (since we need cli)

Iustin Pop's avatar
Iustin Pop committed
26
27
28
29
30
import sys

from ganeti.cli import *
from ganeti import opcodes
from ganeti import utils
31
from ganeti import constants
Guido Trotter's avatar
Guido Trotter committed
32

33

Iustin Pop's avatar
Iustin Pop committed
34
def ListOS(opts, args):
35
36
37
38
39
40
41
  """List the valid OSes in the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code
Iustin Pop's avatar
Iustin Pop committed
42
43

  """
44
45
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "variants"],
                            names=[])
Iustin Pop's avatar
Iustin Pop committed
46
47
48
  result = SubmitOpCode(op)

  if not result:
49
    ToStderr("Can't get the OS list")
Iustin Pop's avatar
Iustin Pop committed
50
51
52
    return 1

  if not opts.no_headers:
53
54
55
    headers = {"name": "Name"}
  else:
    headers = None
Iustin Pop's avatar
Iustin Pop committed
56

57
58
59
60
61
  os_names = []
  for (name, valid, variants) in result:
    if valid:
      os_names.extend([[n] for n in CalculateOSNames(name, variants)])

62
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
63
                       data=os_names, units=None)
64
65

  for line in data:
66
    ToStdout(line)
Iustin Pop's avatar
Iustin Pop committed
67
68
69

  return 0

Guido Trotter's avatar
Guido Trotter committed
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def _OsStatus(status, diagnose):
  """Beautifier function for OS status.

  @type status: boolean
  @param status: is the OS valid
  @type diagnose: string
  @param diagnose: the error message for invalid OSes
  @rtype: string
  @return: a formatted status

  """
  if status:
    return "valid"
  else:
    return "invalid - %s" % diagnose

Iustin Pop's avatar
Iustin Pop committed
87
88
89
def DiagnoseOS(opts, args):
  """Analyse all OSes on this cluster.

90
91
92
93
94
95
  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

Iustin Pop's avatar
Iustin Pop committed
96
  """
97
98
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "variants",
                                           "node_status"], names=[])
Iustin Pop's avatar
Iustin Pop committed
99
100
101
  result = SubmitOpCode(op)

  if not result:
102
    ToStderr("Can't get the OS list")
Iustin Pop's avatar
Iustin Pop committed
103
104
    return 1

105
106
  has_bad = False

107
  for os_name, os_valid, os_variants, node_data in result:
Guido Trotter's avatar
Guido Trotter committed
108
    nodes_valid = {}
Iustin Pop's avatar
Iustin Pop committed
109
    nodes_bad = {}
110
111
112
113
    nodes_hidden = {}
    for node_name, node_info in node_data.iteritems():
      nodes_hidden[node_name] = []
      if node_info: # at least one entry in the per-node list
114
115
116
117
118
119
        (first_os_path, first_os_status, first_os_msg,
         first_os_variants) = node_info.pop(0)
        if not first_os_variants:
          first_os_variants = []
        first_os_msg = ("%s (path: %s) [variants: %s]" %
                        (_OsStatus(first_os_status, first_os_msg),
120
                         first_os_path, utils.CommaJoin(first_os_variants)))
121
        if first_os_status:
122
          nodes_valid[node_name] = first_os_msg
Guido Trotter's avatar
Guido Trotter committed
123
        else:
124
          nodes_bad[node_name] = first_os_msg
125
        for hpath, hstatus, hmsg in node_info:
126
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
127
                                         (hpath, _OsStatus(hstatus, hmsg)))
Iustin Pop's avatar
Iustin Pop committed
128
      else:
Guido Trotter's avatar
Guido Trotter committed
129
        nodes_bad[node_name] = "OS not found"
Iustin Pop's avatar
Iustin Pop committed
130
131
132
133
134

    if nodes_valid and not nodes_bad:
      status = "valid"
    elif not nodes_valid and nodes_bad:
      status = "invalid"
135
      has_bad = True
Iustin Pop's avatar
Iustin Pop committed
136
137
    else:
      status = "partial valid"
138
      has_bad = True
139

140
141
    def _OutputPerNodeOSStatus(msg_map):
      map_k = utils.NiceSort(msg_map.keys())
Guido Trotter's avatar
Guido Trotter committed
142
      for node_name in map_k:
143
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
144
        for msg in nodes_hidden[node_name]:
145
          ToStdout(msg)
Guido Trotter's avatar
Guido Trotter committed
146

147
    ToStdout("OS: %s [global status: %s]", os_name, status)
148
    if os_variants:
149
      ToStdout("  Variants: [%s]" % utils.CommaJoin(os_variants))
Guido Trotter's avatar
Guido Trotter committed
150
151
    _OutputPerNodeOSStatus(nodes_valid)
    _OutputPerNodeOSStatus(nodes_bad)
152
    ToStdout("")
Iustin Pop's avatar
Iustin Pop committed
153

154
155
  return int(has_bad)

Iustin Pop's avatar
Iustin Pop committed
156
157

commands = {
158
  'list': (
159
    ListOS, ARGS_NONE, [NOHDR_OPT], "", "Lists all valid OSes on the master"),
160
  'diagnose': (
161
    DiagnoseOS, ARGS_NONE, [], "", "Diagnose all OSes"),
Iustin Pop's avatar
Iustin Pop committed
162
163
164
  }

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