ganeti-qa.py 7 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

Michael Hanselmann's avatar
Michael Hanselmann committed
106
107
108
109
110
111
  if qa_config.TestEnabled('cluster-getmaster'):
    RunTest(qa_cluster.TestClusterGetmaster)

  if qa_config.TestEnabled('cluster-version'):
    RunTest(qa_cluster.TestClusterVersion)

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

115
116
  if qa_config.TestEnabled('node-info'):
    RunTest(qa_node.TestNodeInfo)
117

118
119
  if qa_config.TestEnabled('cluster-burnin'):
    RunTest(qa_cluster.TestClusterBurnin)
Iustin Pop's avatar
Iustin Pop committed
120

121
122
  if qa_config.TestEnabled('cluster-master-failover'):
    RunTest(qa_cluster.TestClusterMasterFailover)
Iustin Pop's avatar
Iustin Pop committed
123

124
  node = qa_config.AcquireNode()
Iustin Pop's avatar
Iustin Pop committed
125
  try:
126
127
    if qa_config.TestEnabled('instance-add-plain-disk'):
      instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, node)
Michael Hanselmann's avatar
Michael Hanselmann committed
128
129
130
131

      if qa_config.TestEnabled('instance-shutdown'):
        RunTest(qa_instance.TestInstanceShutdown, instance)
        RunTest(qa_instance.TestInstanceStartup, instance)
Iustin Pop's avatar
Iustin Pop committed
132

Michael Hanselmann's avatar
Michael Hanselmann committed
133
134
135
      if qa_config.TestEnabled('instance-list'):
        RunTest(qa_instance.TestInstanceList)

136
137
      if qa_config.TestEnabled('instance-info'):
        RunTest(qa_instance.TestInstanceInfo, instance)
138

Michael Hanselmann's avatar
Michael Hanselmann committed
139
140
141
142
      automatic_restart = \
        qa_config.TestEnabled('instance-automatic-restart')
      consecutive_failures = \
        qa_config.TestEnabled('instance-consecutive-failures')
Iustin Pop's avatar
Iustin Pop committed
143

Michael Hanselmann's avatar
Michael Hanselmann committed
144
145
146
147
148
149
150
151
      if automatic_restart or consecutive_failures:
        qa_daemon.PrintCronWarning()

        if automatic_restart:
          RunTest(qa_daemon.TestInstanceAutomaticRestart, node, instance)

        if consecutive_failures:
          RunTest(qa_daemon.TestInstanceConsecutiveFailures, node, instance)
Iustin Pop's avatar
Iustin Pop committed
152

Michael Hanselmann's avatar
Michael Hanselmann committed
153
154
155
156
157
      if qa_config.TestEnabled('instance-export'):
        expnode = qa_config.AcquireNode(exclude=node)
        try:
          name = RunTest(qa_instance.TestInstanceExport, instance, expnode)

Michael Hanselmann's avatar
Michael Hanselmann committed
158
159
          RunTest(qa_instance.TestBackupList, expnode)

Michael Hanselmann's avatar
Michael Hanselmann committed
160
161
162
163
164
165
166
167
168
169
170
          if qa_config.TestEnabled('instance-import'):
            newinst = qa_config.AcquireInstance()
            try:
              RunTest(qa_instance.TestInstanceImport, node, newinst,
                      expnode, name)
              RunTest(qa_instance.TestInstanceRemove, newinst)
            finally:
              qa_config.ReleaseInstance(newinst)
        finally:
          qa_config.ReleaseNode(expnode)

Michael Hanselmann's avatar
Michael Hanselmann committed
171
172
173
174
175
      if qa_config.TestEnabled('instance-reinstall'):
        RunTest(qa_instance.TestInstanceShutdown, instance)
        RunTest(qa_instance.TestInstanceReinstall, instance)
        RunTest(qa_instance.TestInstanceStartup, instance)

176
177
      if qa_config.TestEnabled('node-volumes'):
        RunTest(qa_node.TestNodeVolumes)
178

179
      RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
180
181
      del instance

182
183
    if qa_config.TestEnabled('instance-add-local-mirror-disk'):
      instance = RunTest(qa_instance.TestInstanceAddWithLocalMirrorDisk, node)
Michael Hanselmann's avatar
Michael Hanselmann committed
184
185
186
187

      if qa_config.TestEnabled('instance-shutdown'):
        RunTest(qa_instance.TestInstanceShutdown, instance)
        RunTest(qa_instance.TestInstanceStartup, instance)
188

189
190
      if qa_config.TestEnabled('instance-info'):
        RunTest(qa_instance.TestInstanceInfo, instance)
191

192
193
      if qa_config.TestEnabled('node-volumes'):
        RunTest(qa_node.TestNodeVolumes)
194

195
      RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
196
197
      del instance

198
199
    if qa_config.TestEnabled('instance-add-remote-raid-disk'):
      node2 = qa_config.AcquireNode(exclude=node)
Iustin Pop's avatar
Iustin Pop committed
200
      try:
201
202
        instance = RunTest(qa_instance.TestInstanceAddWithRemoteRaidDisk,
                           node, node2)
Michael Hanselmann's avatar
Michael Hanselmann committed
203
204
205
206

        if qa_config.TestEnabled('instance-shutdown'):
          RunTest(qa_instance.TestInstanceShutdown, instance)
          RunTest(qa_instance.TestInstanceStartup, instance)
Iustin Pop's avatar
Iustin Pop committed
207

208
209
        if qa_config.TestEnabled('instance-info'):
          RunTest(qa_instance.TestInstanceInfo, instance)
210

211
212
        if qa_config.TestEnabled('instance-failover'):
          RunTest(qa_instance.TestInstanceFailover, instance)
Iustin Pop's avatar
Iustin Pop committed
213

214
215
        if qa_config.TestEnabled('node-volumes'):
          RunTest(qa_node.TestNodeVolumes)
216

217
        RunTest(qa_instance.TestInstanceRemove, instance)
Iustin Pop's avatar
Iustin Pop committed
218
219
        del instance
      finally:
220
        qa_config.ReleaseNode(node2)
Iustin Pop's avatar
Iustin Pop committed
221
222

  finally:
223
    qa_config.ReleaseNode(node)
Iustin Pop's avatar
Iustin Pop committed
224

225
  RunTest(qa_node.TestNodeRemoveAll)
Iustin Pop's avatar
Iustin Pop committed
226

227
228
  if qa_config.TestEnabled('cluster-destroy'):
    RunTest(qa_cluster.TestClusterDestroy)
Iustin Pop's avatar
Iustin Pop committed
229

230
231
232

if __name__ == '__main__':
  main()