gnt-os 3.91 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
31
import sys
from optparse import make_option

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

34

Iustin Pop's avatar
Iustin Pop committed
35
def ListOS(opts, args):
36
37
38
39
40
41
42
  """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
43
44

  """
45
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid"], 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
  data = GenerateTable(separator=None, headers=headers, fields=["name"],
58
59
                       data=[[row[0]] for row in result if row[1]],
                       units=None)
60
61

  for line in data:
62
    ToStdout(line)
Iustin Pop's avatar
Iustin Pop committed
63
64
65

  return 0

Guido Trotter's avatar
Guido Trotter committed
66

Iustin Pop's avatar
Iustin Pop committed
67
68
69
def DiagnoseOS(opts, args):
  """Analyse all OSes on this cluster.

70
71
72
73
74
75
  @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
76
  """
77
78
  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "node_status"],
                            names=[])
Iustin Pop's avatar
Iustin Pop committed
79
80
81
  result = SubmitOpCode(op)

  if not result:
82
    ToStderr("Can't get the OS list")
Iustin Pop's avatar
Iustin Pop committed
83
84
    return 1

85
86
  has_bad = False

87
  for os_name, os_valid, node_data in result:
Guido Trotter's avatar
Guido Trotter committed
88
    nodes_valid = {}
Iustin Pop's avatar
Iustin Pop committed
89
    nodes_bad = {}
90
91
92
93
94
    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
        first_os_status, first_os_path = node_info.pop(0)
95
        first_os_msg = ("%s (path: %s)" %
96
97
                        (first_os_status, first_os_path))
        if first_os_status == constants.OS_VALID_STATUS:
98
          nodes_valid[node_name] = first_os_msg
Guido Trotter's avatar
Guido Trotter committed
99
        else:
100
          nodes_bad[node_name] = first_os_msg
101
102
103
        for hstatus, hpath in node_info:
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
                                         (hpath, hstatus))
Iustin Pop's avatar
Iustin Pop committed
104
      else:
Guido Trotter's avatar
Guido Trotter committed
105
        nodes_bad[node_name] = "OS not found"
Iustin Pop's avatar
Iustin Pop committed
106
107
108
109
110

    if nodes_valid and not nodes_bad:
      status = "valid"
    elif not nodes_valid and nodes_bad:
      status = "invalid"
111
      has_bad = True
Iustin Pop's avatar
Iustin Pop committed
112
113
    else:
      status = "partial valid"
114
      has_bad = True
115

116
117
    def _OutputPerNodeOSStatus(msg_map):
      map_k = utils.NiceSort(msg_map.keys())
Guido Trotter's avatar
Guido Trotter committed
118
      for node_name in map_k:
119
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
120
        for msg in nodes_hidden[node_name]:
121
          ToStdout(msg)
Guido Trotter's avatar
Guido Trotter committed
122

123
    ToStdout("OS: %s [global status: %s]", os_name, status)
Guido Trotter's avatar
Guido Trotter committed
124
125
    _OutputPerNodeOSStatus(nodes_valid)
    _OutputPerNodeOSStatus(nodes_bad)
126
    ToStdout("")
Iustin Pop's avatar
Iustin Pop committed
127

128
129
  return int(has_bad)

Iustin Pop's avatar
Iustin Pop committed
130
131

commands = {
132
  'list': (ListOS, ARGS_NONE, [DEBUG_OPT, NOHDR_OPT], "",
Iustin Pop's avatar
Iustin Pop committed
133
           "Lists all valid OSes on the master"),
134
  'diagnose': (DiagnoseOS, ARGS_NONE, [DEBUG_OPT], "",
Iustin Pop's avatar
Iustin Pop committed
135
136
137
138
               "Diagnose all OSes"),
  }

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