Statistics
| Branch: | Tag: | Revision:

root / qa / qa_cluster.py @ 8201b996

History | View | Annotate | Download (12.1 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007, 2010 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 utils
30

    
31
import qa_config
32
import qa_utils
33
import qa_error
34

    
35
from qa_utils import AssertEqual, AssertNotEqual, StartSSH
36

    
37

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

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

    
47

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

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

    
57

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

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

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

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

    
83
  cmd.append("--primary-ip-version=%d" %
84
             qa_config.get("primary_ip_version", 4))
85

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

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

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

    
98
  cmd.append(qa_config.get('name'))
99

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

    
103

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

    
108
  cmd = ['gnt-cluster', 'rename', '-f']
109

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

    
116
  cmd_1 = cmd + [rename_target]
117
  cmd_2 = cmd + [original_name]
118

    
119
  cmd_verify = ['gnt-cluster', 'verify']
120

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

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

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

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

    
133

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

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

    
142

    
143
def TestJobqueue():
144
  """gnt-debug test-jobqueue"""
145
  master = qa_config.GetMasterNode()
146

    
147
  cmd = ["gnt-debug", "test-jobqueue"]
148
  AssertEqual(StartSSH(master["primary"],
149
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
150

    
151

    
152
def TestClusterReservedLvs():
153
  """gnt-cluster reserved lvs"""
154
  master = qa_config.GetMasterNode()
155
  CVERIFY = ['gnt-cluster', 'verify']
156
  for rcode, cmd in [
157
    (0, CVERIFY),
158
    (0, ['gnt-cluster', 'modify', '--reserved-lvs', '']),
159
    (0, ['lvcreate', '-L1G', '-nqa-test', 'xenvg']),
160
    (1, CVERIFY),
161
    (0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-test,other-test']),
162
    (0, CVERIFY),
163
    (0, ['gnt-cluster', 'modify', '--reserved-lvs', 'qa-.*']),
164
    (0, CVERIFY),
165
    (0, ['gnt-cluster', 'modify', '--reserved-lvs', '']),
166
    (1, CVERIFY),
167
    (0, ['lvremove', '-f', 'xenvg/qa-test']),
168
    (0, CVERIFY),
169
    ]:
170
    AssertEqual(StartSSH(master['primary'],
171
                         utils.ShellQuoteArgs(cmd)).wait(), rcode)
172

    
173

    
174
def TestClusterInfo():
175
  """gnt-cluster info"""
176
  master = qa_config.GetMasterNode()
177

    
178
  cmd = ['gnt-cluster', 'info']
179
  AssertEqual(StartSSH(master['primary'],
180
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
181

    
182

    
183
def TestClusterGetmaster():
184
  """gnt-cluster getmaster"""
185
  master = qa_config.GetMasterNode()
186

    
187
  cmd = ['gnt-cluster', 'getmaster']
188
  AssertEqual(StartSSH(master['primary'],
189
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
190

    
191

    
192
def TestClusterVersion():
193
  """gnt-cluster version"""
194
  master = qa_config.GetMasterNode()
195

    
196
  cmd = ['gnt-cluster', 'version']
197
  AssertEqual(StartSSH(master['primary'],
198
                       utils.ShellQuoteArgs(cmd)).wait(), 0)
199

    
200

    
201
def TestClusterRenewCrypto():
202
  """gnt-cluster renew-crypto"""
203
  master = qa_config.GetMasterNode()
204

    
205
  # Conflicting options
206
  cmd = ["gnt-cluster", "renew-crypto", "--force",
207
         "--new-cluster-certificate", "--new-confd-hmac-key"]
208
  conflicting = [
209
    ["--new-rapi-certificate", "--rapi-certificate=/dev/null"],
210
    ["--new-cluster-domain-secret", "--cluster-domain-secret=/dev/null"],
211
    ]
212
  for i in conflicting:
213
    AssertNotEqual(StartSSH(master["primary"],
214
                            utils.ShellQuoteArgs(cmd + i)).wait(), 0)
215

    
216
  # Invalid RAPI certificate
217
  cmd = ["gnt-cluster", "renew-crypto", "--force",
218
         "--rapi-certificate=/dev/null"]
219
  AssertNotEqual(StartSSH(master["primary"],
220
                          utils.ShellQuoteArgs(cmd)).wait(), 0)
221

    
222
  rapi_cert_backup = qa_utils.BackupFile(master["primary"],
223
                                         constants.RAPI_CERT_FILE)
224
  try:
225
    # Custom RAPI certificate
226
    fh = tempfile.NamedTemporaryFile()
227

    
228
    # Ensure certificate doesn't cause "gnt-cluster verify" to complain
229
    validity = constants.SSL_CERT_EXPIRATION_WARN * 3
230

    
231
    utils.GenerateSelfSignedSslCert(fh.name, validity=validity)
232

    
233
    tmpcert = qa_utils.UploadFile(master["primary"], fh.name)
234
    try:
235
      cmd = ["gnt-cluster", "renew-crypto", "--force",
236
             "--rapi-certificate=%s" % tmpcert]
237
      AssertEqual(StartSSH(master["primary"],
238
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
239
    finally:
240
      cmd = ["rm", "-f", tmpcert]
241
      AssertEqual(StartSSH(master["primary"],
242
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
243

    
244
    # Custom cluster domain secret
245
    cds_fh = tempfile.NamedTemporaryFile()
246
    cds_fh.write(utils.GenerateSecret())
247
    cds_fh.write("\n")
248
    cds_fh.flush()
249

    
250
    tmpcds = qa_utils.UploadFile(master["primary"], cds_fh.name)
251
    try:
252
      cmd = ["gnt-cluster", "renew-crypto", "--force",
253
             "--cluster-domain-secret=%s" % tmpcds]
254
      AssertEqual(StartSSH(master["primary"],
255
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
256
    finally:
257
      cmd = ["rm", "-f", tmpcds]
258
      AssertEqual(StartSSH(master["primary"],
259
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
260

    
261
    # Normal case
262
    cmd = ["gnt-cluster", "renew-crypto", "--force",
263
           "--new-cluster-certificate", "--new-confd-hmac-key",
264
           "--new-rapi-certificate", "--new-cluster-domain-secret"]
265
    AssertEqual(StartSSH(master["primary"],
266
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
267

    
268
    # Restore RAPI certificate
269
    cmd = ["gnt-cluster", "renew-crypto", "--force",
270
           "--rapi-certificate=%s" % rapi_cert_backup]
271
    AssertEqual(StartSSH(master["primary"],
272
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
273
  finally:
274
    cmd = ["rm", "-f", rapi_cert_backup]
275
    AssertEqual(StartSSH(master["primary"],
276
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
277

    
278

    
279
def TestClusterBurnin():
280
  """Burnin"""
281
  master = qa_config.GetMasterNode()
282

    
283
  options = qa_config.get('options', {})
284
  disk_template = options.get('burnin-disk-template', 'drbd')
285
  parallel = options.get('burnin-in-parallel', False)
286
  check_inst = options.get('burnin-check-instances', False)
287
  do_rename = options.get('burnin-rename', '')
288
  do_reboot = options.get('burnin-reboot', True)
289
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
290

    
291
  # Get as many instances as we need
292
  instances = []
293
  try:
294
    try:
295
      num = qa_config.get('options', {}).get('burnin-instances', 1)
296
      for _ in range(0, num):
297
        instances.append(qa_config.AcquireInstance())
298
    except qa_error.OutOfInstancesError:
299
      print "Not enough instances, continuing anyway."
300

    
301
    if len(instances) < 1:
302
      raise qa_error.Error("Burnin needs at least one instance")
303

    
304
    script = qa_utils.UploadFile(master['primary'], '../tools/burnin')
305
    try:
306
      # Run burnin
307
      cmd = [script,
308
             '--os=%s' % qa_config.get('os'),
309
             '--disk-size=%s' % ",".join(qa_config.get('disk')),
310
             '--disk-growth=%s' % ",".join(qa_config.get('disk-growth')),
311
             '--disk-template=%s' % disk_template]
312
      if parallel:
313
        cmd.append('--parallel')
314
        cmd.append('--early-release')
315
      if check_inst:
316
        cmd.append('--http-check')
317
      if do_rename:
318
        cmd.append('--rename=%s' % do_rename)
319
      if not do_reboot:
320
        cmd.append('--no-reboot')
321
      else:
322
        cmd.append('--reboot-types=%s' % ",".join(reboot_types))
323
      cmd += [inst['name'] for inst in instances]
324
      AssertEqual(StartSSH(master['primary'],
325
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
326
    finally:
327
      cmd = ['rm', '-f', script]
328
      AssertEqual(StartSSH(master['primary'],
329
                           utils.ShellQuoteArgs(cmd)).wait(), 0)
330
  finally:
331
    for inst in instances:
332
      qa_config.ReleaseInstance(inst)
333

    
334

    
335
def TestClusterMasterFailover():
336
  """gnt-cluster master-failover"""
337
  master = qa_config.GetMasterNode()
338

    
339
  failovermaster = qa_config.AcquireNode(exclude=master)
340
  try:
341
    cmd = ['gnt-cluster', 'master-failover']
342
    AssertEqual(StartSSH(failovermaster['primary'],
343
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
344

    
345
    cmd = ['gnt-cluster', 'master-failover']
346
    AssertEqual(StartSSH(master['primary'],
347
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
348
  finally:
349
    qa_config.ReleaseNode(failovermaster)
350

    
351

    
352
def TestClusterCopyfile():
353
  """gnt-cluster copyfile"""
354
  master = qa_config.GetMasterNode()
355

    
356
  uniqueid = utils.NewUUID()
357

    
358
  # Create temporary file
359
  f = tempfile.NamedTemporaryFile()
360
  f.write(uniqueid)
361
  f.flush()
362
  f.seek(0)
363

    
364
  # Upload file to master node
365
  testname = qa_utils.UploadFile(master['primary'], f.name)
366
  try:
367
    # Copy file to all nodes
368
    cmd = ['gnt-cluster', 'copyfile', testname]
369
    AssertEqual(StartSSH(master['primary'],
370
                         utils.ShellQuoteArgs(cmd)).wait(), 0)
371
    _CheckFileOnAllNodes(testname, uniqueid)
372
  finally:
373
    _RemoveFileFromAllNodes(testname)
374

    
375

    
376
def TestClusterCommand():
377
  """gnt-cluster command"""
378
  master = qa_config.GetMasterNode()
379

    
380
  uniqueid = utils.NewUUID()
381
  rfile = "/tmp/gnt%s" % utils.NewUUID()
382
  rcmd = utils.ShellQuoteArgs(['echo', '-n', uniqueid])
383
  cmd = utils.ShellQuoteArgs(['gnt-cluster', 'command',
384
                              "%s >%s" % (rcmd, rfile)])
385

    
386
  try:
387
    AssertEqual(StartSSH(master['primary'], cmd).wait(), 0)
388
    _CheckFileOnAllNodes(rfile, uniqueid)
389
  finally:
390
    _RemoveFileFromAllNodes(rfile)
391

    
392

    
393
def TestClusterDestroy():
394
  """gnt-cluster destroy"""
395
  master = qa_config.GetMasterNode()
396

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