Statistics
| Branch: | Tag: | Revision:

root / qa / qa_cluster.py @ 502f5236

History | View | Annotate | Download (10.1 kB)

1
#
2
#
3

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

    
21

    
22
"""Cluster related QA tests.
23

24
"""
25

    
26
import tempfile
27

    
28
from ganeti import constants
29
from ganeti import bootstrap
30
from ganeti import utils
31

    
32
import qa_config
33
import qa_utils
34
import qa_error
35

    
36
from qa_utils import AssertEqual, AssertNotEqual, StartSSH
37

    
38

    
39
def _RemoveFileFromAllNodes(filename):
40
  """Removes a file from all nodes.
41

42
  """
43
  for node in qa_config.get('nodes'):
44
    cmd = ['rm', '-f', filename]
45
    AssertEqual(StartSSH(node['primary'],
46
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
47

    
48

    
49
def _CheckFileOnAllNodes(filename, content):
50
  """Verifies the content of the given file on all nodes.
51

52
  """
53
  cmd = utils.ShellQuoteArgs(["cat", filename])
54
  for node in qa_config.get('nodes'):
55
    AssertEqual(qa_utils.GetCommandOutput(node['primary'], cmd),
56
                content)
57

    
58

    
59
def TestClusterInit(rapi_user, rapi_secret):
60
  """gnt-cluster init"""
61
  master = qa_config.GetMasterNode()
62

    
63
  # First create the RAPI credentials
64
  fh = tempfile.NamedTemporaryFile()
65
  try:
66
    fh.write("%s %s write\n" % (rapi_user, rapi_secret))
67
    fh.flush()
68

    
69
    tmpru = qa_utils.UploadFile(master["primary"], fh.name)
70
    try:
71
      cmd = ["mv", tmpru, constants.RAPI_USERS_FILE]
72
      AssertEqual(StartSSH(master["primary"],
73
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
74
    finally:
75
      cmd = ["rm", "-f", tmpru]
76
      AssertEqual(StartSSH(master["primary"],
77
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
78
  finally:
79
    fh.close()
80

    
81
  # Initialize cluster
82
  cmd = ['gnt-cluster', 'init']
83

    
84
  if master.get('secondary', None):
85
    cmd.append('--secondary-ip=%s' % master['secondary'])
86

    
87
  bridge = qa_config.get('bridge', None)
88
  if bridge:
89
    cmd.append('--bridge=%s' % bridge)
90
    cmd.append('--master-netdev=%s' % bridge)
91

    
92
  htype = qa_config.get('enabled-hypervisors', None)
93
  if htype:
94
    cmd.append('--enabled-hypervisors=%s' % htype)
95

    
96
  cmd.append(qa_config.get('name'))
97

    
98
  AssertEqual(StartSSH(master['primary'],
99
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
100

    
101

    
102
def TestClusterRename():
103
  """gnt-cluster rename"""
104
  master = qa_config.GetMasterNode()
105

    
106
  cmd = ['gnt-cluster', 'rename', '-f']
107

    
108
  original_name = qa_config.get('name')
109
  rename_target = qa_config.get('rename', None)
110
  if rename_target is None:
111
    print qa_utils.FormatError('"rename" entry is missing')
112
    return
113

    
114
  cmd_1 = cmd + [rename_target]
115
  cmd_2 = cmd + [original_name]
116

    
117
  cmd_verify = ['gnt-cluster', 'verify']
118

    
119
  AssertEqual(StartSSH(master['primary'],
120
                       utils.ShellQuoteArgs(cmd_1)).wait(), 0)
121

    
122
  AssertEqual(StartSSH(master['primary'],
123
                       utils.ShellQuoteArgs(cmd_verify)).wait(), 0)
124

    
125
  AssertEqual(StartSSH(master['primary'],
126
                       utils.ShellQuoteArgs(cmd_2)).wait(), 0)
127

    
128
  AssertEqual(StartSSH(master['primary'],
129
                       utils.ShellQuoteArgs(cmd_verify)).wait(), 0)
130

    
131

    
132
def TestClusterVerify():
133
  """gnt-cluster verify"""
134
  master = qa_config.GetMasterNode()
135

    
136
  cmd = ['gnt-cluster', 'verify']
137
  AssertEqual(StartSSH(master['primary'],
138
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
139

    
140

    
141
def TestClusterInfo():
142
  """gnt-cluster info"""
143
  master = qa_config.GetMasterNode()
144

    
145
  cmd = ['gnt-cluster', 'info']
146
  AssertEqual(StartSSH(master['primary'],
147
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
148

    
149

    
150
def TestClusterGetmaster():
151
  """gnt-cluster getmaster"""
152
  master = qa_config.GetMasterNode()
153

    
154
  cmd = ['gnt-cluster', 'getmaster']
155
  AssertEqual(StartSSH(master['primary'],
156
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
157

    
158

    
159
def TestClusterVersion():
160
  """gnt-cluster version"""
161
  master = qa_config.GetMasterNode()
162

    
163
  cmd = ['gnt-cluster', 'version']
164
  AssertEqual(StartSSH(master['primary'],
165
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
166

    
167

    
168
def TestClusterRenewCrypto():
169
  """gnt-cluster renew-crypto"""
170
  master = qa_config.GetMasterNode()
171

    
172
  # Conflicting options
173
  cmd = ["gnt-cluster", "renew-crypto", "--force",
174
         "--new-cluster-certificate", "--new-confd-hmac-key",
175
         "--new-rapi-certificate", "--rapi-certificate=/dev/null"]
176
  AssertNotEqual(StartSSH(master["primary"],
177
                          utils.ShellQuoteArgs(cmd)).wait(), 0)
178

    
179
  # Invalid RAPI certificate
180
  cmd = ["gnt-cluster", "renew-crypto", "--force",
181
         "--rapi-certificate=/dev/null"]
182
  AssertNotEqual(StartSSH(master["primary"],
183
                          utils.ShellQuoteArgs(cmd)).wait(), 0)
184

    
185
  rapi_cert_backup = qa_utils.BackupFile(master["primary"],
186
                                         constants.RAPI_CERT_FILE)
187
  try:
188
    # Custom RAPI certificate
189
    fh = tempfile.NamedTemporaryFile()
190

    
191
    # Ensure certificate doesn't cause "gnt-cluster verify" to complain
192
    validity = constants.SSL_CERT_EXPIRATION_WARN * 3
193

    
194
    bootstrap.GenerateSelfSignedSslCert(fh.name, validity=validity)
195

    
196
    tmpcert = qa_utils.UploadFile(master["primary"], fh.name)
197
    try:
198
      cmd = ["gnt-cluster", "renew-crypto", "--force",
199
             "--rapi-certificate=%s" % tmpcert]
200
      AssertEqual(StartSSH(master["primary"],
201
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
202
    finally:
203
      cmd = ["rm", "-f", tmpcert]
204
      AssertEqual(StartSSH(master["primary"],
205
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
206

    
207
    # Normal case
208
    cmd = ["gnt-cluster", "renew-crypto", "--force",
209
           "--new-cluster-certificate", "--new-confd-hmac-key",
210
           "--new-rapi-certificate"]
211
    AssertEqual(StartSSH(master["primary"],
212
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
213

    
214
    # Restore RAPI certificate
215
    cmd = ["gnt-cluster", "renew-crypto", "--force",
216
           "--rapi-certificate=%s" % rapi_cert_backup]
217
    AssertEqual(StartSSH(master["primary"],
218
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
219
  finally:
220
    cmd = ["rm", "-f", rapi_cert_backup]
221
    AssertEqual(StartSSH(master["primary"],
222
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
223

    
224

    
225
def TestClusterBurnin():
226
  """Burnin"""
227
  master = qa_config.GetMasterNode()
228

    
229
  options = qa_config.get('options', {})
230
  disk_template = options.get('burnin-disk-template', 'drbd')
231
  parallel = options.get('burnin-in-parallel', False)
232
  check_inst = options.get('burnin-check-instances', False)
233
  do_rename = options.get('burnin-rename', '')
234

    
235
  # Get as many instances as we need
236
  instances = []
237
  try:
238
    try:
239
      num = qa_config.get('options', {}).get('burnin-instances', 1)
240
      for _ in range(0, num):
241
        instances.append(qa_config.AcquireInstance())
242
    except qa_error.OutOfInstancesError:
243
      print "Not enough instances, continuing anyway."
244

    
245
    if len(instances) < 1:
246
      raise qa_error.Error("Burnin needs at least one instance")
247

    
248
    script = qa_utils.UploadFile(master['primary'], '../tools/burnin')
249
    try:
250
      # Run burnin
251
      cmd = [script,
252
             '--os=%s' % qa_config.get('os'),
253
             '--disk-size=%s' % ",".join(qa_config.get('disk')),
254
             '--disk-growth=%s' % ",".join(qa_config.get('disk-growth')),
255
             '--disk-template=%s' % disk_template]
256
      if parallel:
257
        cmd.append('--parallel')
258
        cmd.append('--early-release')
259
      if check_inst:
260
        cmd.append('--http-check')
261
      if do_rename:
262
        cmd.append('--rename=%s' % do_rename)
263
      cmd += [inst['name'] for inst in instances]
264
      AssertEqual(StartSSH(master['primary'],
265
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
266
    finally:
267
      cmd = ['rm', '-f', script]
268
      AssertEqual(StartSSH(master['primary'],
269
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
270
  finally:
271
    for inst in instances:
272
      qa_config.ReleaseInstance(inst)
273

    
274

    
275
def TestClusterMasterFailover():
276
  """gnt-cluster masterfailover"""
277
  master = qa_config.GetMasterNode()
278

    
279
  failovermaster = qa_config.AcquireNode(exclude=master)
280
  try:
281
    cmd = ['gnt-cluster', 'masterfailover']
282
    AssertEqual(StartSSH(failovermaster['primary'],
283
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
284

    
285
    cmd = ['gnt-cluster', 'masterfailover']
286
    AssertEqual(StartSSH(master['primary'],
287
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
288
  finally:
289
    qa_config.ReleaseNode(failovermaster)
290

    
291

    
292
def TestClusterCopyfile():
293
  """gnt-cluster copyfile"""
294
  master = qa_config.GetMasterNode()
295

    
296
  uniqueid = utils.NewUUID()
297

    
298
  # Create temporary file
299
  f = tempfile.NamedTemporaryFile()
300
  f.write(uniqueid)
301
  f.flush()
302
  f.seek(0)
303

    
304
  # Upload file to master node
305
  testname = qa_utils.UploadFile(master['primary'], f.name)
306
  try:
307
    # Copy file to all nodes
308
    cmd = ['gnt-cluster', 'copyfile', testname]
309
    AssertEqual(StartSSH(master['primary'],
310
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
311
    _CheckFileOnAllNodes(testname, uniqueid)
312
  finally:
313
    _RemoveFileFromAllNodes(testname)
314

    
315

    
316
def TestClusterCommand():
317
  """gnt-cluster command"""
318
  master = qa_config.GetMasterNode()
319

    
320
  uniqueid = utils.NewUUID()
321
  rfile = "/tmp/gnt%s" % utils.NewUUID()
322
  rcmd = utils.ShellQuoteArgs(['echo', '-n', uniqueid])
323
  cmd = utils.ShellQuoteArgs(['gnt-cluster', 'command',
324
                              "%s >%s" % (rcmd, rfile)])
325

    
326
  try:
327
    AssertEqual(StartSSH(master['primary'], cmd).wait(), 0)
328
    _CheckFileOnAllNodes(rfile, uniqueid)
329
  finally:
330
    _RemoveFileFromAllNodes(rfile)
331

    
332

    
333
def TestClusterDestroy():
334
  """gnt-cluster destroy"""
335
  master = qa_config.GetMasterNode()
336

    
337
  cmd = ['gnt-cluster', 'destroy', '--yes-do-it']
338
  AssertEqual(StartSSH(master['primary'],
339
                       utils.ShellQuoteArgs(cmd)).wait(), 0)