ganeti-qa.py 5.46 KB
Newer Older
Iustin Pop's avatar
Iustin Pop committed
1
2
3
#!/usr/bin/python
#

4
# Copyright (C) 2007 Google Inc.
Iustin Pop's avatar
Iustin Pop committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
# 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
"""Script for doing QA on Ganeti.
23
24
25
26
27
28

You can create the required known_hosts file using ssh-keyscan. It's mandatory
to use the full name of a node (FQDN). For security reasons, verify the keys
before using them.
Example: ssh-keyscan -t rsa node{1,2,3,4}.example.com > known_hosts
"""
Iustin Pop's avatar
Iustin Pop committed
29
30
31
32
33

import sys
from datetime import datetime
from optparse import OptionParser

34
35
36
37
38
39
40
import qa_cluster
import qa_config
import qa_daemon
import qa_env
import qa_instance
import qa_node
import qa_other
Iustin Pop's avatar
Iustin Pop committed
41
42


43
def RunTest(fn, *args):
Iustin Pop's avatar
Iustin Pop committed
44
45
46
  """Runs a test after printing a header.

  """
47
48
  if fn.__doc__:
    desc = fn.__doc__.splitlines()[0].strip()
Iustin Pop's avatar
Iustin Pop committed
49
  else:
50
    desc = '%r' % fn
Iustin Pop's avatar
Iustin Pop committed
51
52
53
54
55
56
57
58

  now = str(datetime.now())

  print
  print '---', now, ('-' * (55 - len(now)))
  print desc
  print '-' * 60

59
  return fn(*args)
Iustin Pop's avatar
Iustin Pop committed
60
61


62
63
def main():
  """Main program.
Iustin Pop's avatar
Iustin Pop committed
64
65

  """
66
67
  parser = OptionParser(usage="%prog [options] <config-file> "
                              "<known-hosts-file>")
Iustin Pop's avatar
Iustin Pop committed
68
69
70
71
72
73
  parser.add_option('--dry-run', dest='dry_run',
      action="store_true",
      help="Show what would be done")
  parser.add_option('--yes-do-it', dest='yes_do_it',
      action="store_true",
      help="Really execute the tests")
74
  (qa_config.options, args) = parser.parse_args()
Iustin Pop's avatar
Iustin Pop committed
75

76
77
  if len(args) == 2:
    (config_file, known_hosts_file) = args
Iustin Pop's avatar
Iustin Pop committed
78
  else:
79
    parser.error("Not enough arguments.")
Iustin Pop's avatar
Iustin Pop committed
80

81
  if not qa_config.options.yes_do_it:
Iustin Pop's avatar
Iustin Pop committed
82
83
84
85
86
    print ("Executing this script irreversibly destroys any Ganeti\n"
           "configuration on all nodes involved. If you really want\n"
           "to start testing, supply the --yes-do-it option.")
    sys.exit(1)

87
  qa_config.Load(config_file)
Iustin Pop's avatar
Iustin Pop committed
88

89
  RunTest(qa_other.TestUploadKnownHostsFile, known_hosts_file)
90

91
92
93
94
  if qa_config.TestEnabled('env'):
    RunTest(qa_env.TestSshConnection)
    RunTest(qa_env.TestIcmpPing)
    RunTest(qa_env.TestGanetiCommands)
Iustin Pop's avatar
Iustin Pop committed
95

96
  RunTest(qa_cluster.TestClusterInit)
Iustin Pop's avatar
Iustin Pop committed
97

98
  RunTest(qa_node.TestNodeAddAll)
99

100
101
  if qa_config.TestEnabled('cluster-verify'):
    RunTest(qa_cluster.TestClusterVerify)
102

103
104
  if qa_config.TestEnabled('cluster-info'):
    RunTest(qa_cluster.TestClusterInfo)
Iustin Pop's avatar
Iustin Pop committed
105

106
107
  if qa_config.TestEnabled('cluster-copyfile'):
    RunTest(qa_cluster.TestClusterCopyfile)
Iustin Pop's avatar
Iustin Pop committed
108

109
110
  if qa_config.TestEnabled('node-info'):
    RunTest(qa_node.TestNodeInfo)
111

112
113
  if qa_config.TestEnabled('cluster-burnin'):
    RunTest(qa_cluster.TestClusterBurnin)
Iustin Pop's avatar
Iustin Pop committed
114

115
116
  if qa_config.TestEnabled('cluster-master-failover'):
    RunTest(qa_cluster.TestClusterMasterFailover)
Iustin Pop's avatar
Iustin Pop committed
117

118
  node = qa_config.AcquireNode()
Iustin Pop's avatar
Iustin Pop committed
119
  try:
120
121
122
123
    if qa_config.TestEnabled('instance-add-plain-disk'):
      instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, node)
      RunTest(qa_instance.TestInstanceShutdown, instance)
      RunTest(qa_instance.TestInstanceStartup, instance)
Iustin Pop's avatar
Iustin Pop committed
124

125
126
      if qa_config.TestEnabled('instance-info'):
        RunTest(qa_instance.TestInstanceInfo, instance)
127

128
129
      if qa_config.TestEnabled('instance-automatic-restart'):
        RunTest(qa_daemon.TestInstanceAutomaticRestart, node, instance)
Iustin Pop's avatar
Iustin Pop committed
130

131
132
      if qa_config.TestEnabled('instance-consecutive-failures'):
        RunTest(qa_daemon.TestInstanceConsecutiveFailures, node, instance)
Iustin Pop's avatar
Iustin Pop committed
133

134
135
      if qa_config.TestEnabled('node-volumes'):
        RunTest(qa_node.TestNodeVolumes)
136

137
      RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
138
139
      del instance

140
141
142
143
    if qa_config.TestEnabled('instance-add-local-mirror-disk'):
      instance = RunTest(qa_instance.TestInstanceAddWithLocalMirrorDisk, node)
      RunTest(qa_instance.TestInstanceShutdown, instance)
      RunTest(qa_instance.TestInstanceStartup, instance)
144

145
146
      if qa_config.TestEnabled('instance-info'):
        RunTest(qa_instance.TestInstanceInfo, instance)
147

148
149
      if qa_config.TestEnabled('node-volumes'):
        RunTest(qa_node.TestNodeVolumes)
150

151
      RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
152
153
      del instance

154
155
    if qa_config.TestEnabled('instance-add-remote-raid-disk'):
      node2 = qa_config.AcquireNode(exclude=node)
Iustin Pop's avatar
Iustin Pop committed
156
      try:
157
158
159
160
        instance = RunTest(qa_instance.TestInstanceAddWithRemoteRaidDisk,
                           node, node2)
        RunTest(qa_instance.TestInstanceShutdown, instance)
        RunTest(qa_instance.TestInstanceStartup, instance)
Iustin Pop's avatar
Iustin Pop committed
161

162
163
        if qa_config.TestEnabled('instance-info'):
          RunTest(qa_instance.TestInstanceInfo, instance)
164

165
166
        if qa_config.TestEnabled('instance-failover'):
          RunTest(qa_instance.TestInstanceFailover, instance)
Iustin Pop's avatar
Iustin Pop committed
167

168
169
        if qa_config.TestEnabled('node-volumes'):
          RunTest(qa_node.TestNodeVolumes)
170

171
        RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
172
173
        del instance
      finally:
174
        qa_config.ReleaseNode(node2)
Iustin Pop's avatar
Iustin Pop committed
175
176

  finally:
177
    qa_config.ReleaseNode(node)
Iustin Pop's avatar
Iustin Pop committed
178

179
  RunTest(qa_node.TestNodeRemoveAll)
Iustin Pop's avatar
Iustin Pop committed
180

181
182
  if qa_config.TestEnabled('cluster-destroy'):
    RunTest(qa_cluster.TestClusterDestroy)
Iustin Pop's avatar
Iustin Pop committed
183

184
185
186

if __name__ == '__main__':
  main()