Statistics
| Branch: | Tag: | Revision:

root / qa / qa_instance.py @ f346a7d9

History | View | Annotate | Download (18.5 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007, 2011, 2012 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
"""Instance related QA tests.
23

24
"""
25

    
26
import re
27
import time
28

    
29
from ganeti import utils
30
from ganeti import constants
31
from ganeti import query
32

    
33
import qa_config
34
import qa_utils
35
import qa_error
36

    
37
from qa_utils import AssertIn, AssertCommand, AssertEqual
38
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE
39

    
40

    
41
def _GetDiskStatePath(disk):
42
  return "/sys/block/%s/device/state" % disk
43

    
44

    
45
def _GetGenericAddParameters(inst):
46
  params = ["-B"]
47
  params.append("%s=%s,%s=%s" % (constants.BE_MINMEM,
48
                                 qa_config.get(constants.BE_MINMEM),
49
                                 constants.BE_MAXMEM,
50
                                 qa_config.get(constants.BE_MAXMEM)))
51
  for idx, size in enumerate(qa_config.get("disk")):
52
    params.extend(["--disk", "%s:size=%s" % (idx, size)])
53

    
54
  # Set static MAC address if configured
55
  nic0_mac = qa_config.GetInstanceNicMac(inst)
56
  if nic0_mac:
57
    params.extend(["--net", "0:mac=%s" % nic0_mac])
58

    
59
  return params
60

    
61

    
62
def _DiskTest(node, disk_template):
63
  instance = qa_config.AcquireInstance()
64
  try:
65
    cmd = (["gnt-instance", "add",
66
            "--os-type=%s" % qa_config.get("os"),
67
            "--disk-template=%s" % disk_template,
68
            "--node=%s" % node] +
69
           _GetGenericAddParameters(instance))
70
    cmd.append(instance["name"])
71

    
72
    AssertCommand(cmd)
73

    
74
    _CheckSsconfInstanceList(instance["name"])
75

    
76
    return instance
77
  except:
78
    qa_config.ReleaseInstance(instance)
79
    raise
80

    
81

    
82
@InstanceCheck(None, INST_UP, RETURN_VALUE)
83
def TestInstanceAddWithPlainDisk(node):
84
  """gnt-instance add -t plain"""
85
  return _DiskTest(node["primary"], "plain")
86

    
87

    
88
@InstanceCheck(None, INST_UP, RETURN_VALUE)
89
def TestInstanceAddWithDrbdDisk(node, node2):
90
  """gnt-instance add -t drbd"""
91
  return _DiskTest("%s:%s" % (node["primary"], node2["primary"]),
92
                   "drbd")
93

    
94

    
95
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
96
def TestInstanceRemove(instance):
97
  """gnt-instance remove"""
98
  AssertCommand(["gnt-instance", "remove", "-f", instance["name"]])
99

    
100
  qa_config.ReleaseInstance(instance)
101

    
102

    
103
@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
104
def TestInstanceStartup(instance):
105
  """gnt-instance startup"""
106
  AssertCommand(["gnt-instance", "startup", instance["name"]])
107

    
108

    
109
@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
110
def TestInstanceShutdown(instance):
111
  """gnt-instance shutdown"""
112
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
113

    
114

    
115
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
116
def TestInstanceReboot(instance):
117
  """gnt-instance reboot"""
118
  options = qa_config.get("options", {})
119
  reboot_types = options.get("reboot-types", constants.REBOOT_TYPES)
120
  name = instance["name"]
121
  for rtype in reboot_types:
122
    AssertCommand(["gnt-instance", "reboot", "--type=%s" % rtype, name])
123

    
124
  AssertCommand(["gnt-instance", "shutdown", name])
125
  qa_utils.RunInstanceCheck(instance, False)
126
  AssertCommand(["gnt-instance", "reboot", name])
127

    
128
  master = qa_config.GetMasterNode()
129
  cmd = ["gnt-instance", "list", "--no-headers", "-o", "status", name]
130
  result_output = qa_utils.GetCommandOutput(master["primary"],
131
                                            utils.ShellQuoteArgs(cmd))
132
  AssertEqual(result_output.strip(), constants.INSTST_RUNNING)
133

    
134

    
135
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
136
def TestInstanceReinstall(instance):
137
  """gnt-instance reinstall"""
138
  AssertCommand(["gnt-instance", "reinstall", "-f", instance["name"]])
139

    
140

    
141
def _ReadSsconfInstanceList():
142
  """Reads ssconf_instance_list from the master node.
143

144
  """
145
  master = qa_config.GetMasterNode()
146

    
147
  cmd = ["cat", utils.PathJoin(constants.DATA_DIR,
148
                               "ssconf_%s" % constants.SS_INSTANCE_LIST)]
149

    
150
  return qa_utils.GetCommandOutput(master["primary"],
151
                                   utils.ShellQuoteArgs(cmd)).splitlines()
152

    
153

    
154
def _CheckSsconfInstanceList(instance):
155
  """Checks if a certain instance is in the ssconf instance list.
156

157
  @type instance: string
158
  @param instance: Instance name
159

160
  """
161
  AssertIn(qa_utils.ResolveInstanceName(instance),
162
           _ReadSsconfInstanceList())
163

    
164

    
165
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
166
def TestInstanceRenameAndBack(rename_source, rename_target):
167
  """gnt-instance rename
168

169
  This must leave the instance with the original name, not the target
170
  name.
171

172
  """
173
  _CheckSsconfInstanceList(rename_source)
174

    
175
  # first do a rename to a different actual name, expecting it to fail
176
  qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target])
177
  try:
178
    AssertCommand(["gnt-instance", "rename", rename_source, rename_target],
179
                  fail=True)
180
    _CheckSsconfInstanceList(rename_source)
181
  finally:
182
    qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target])
183

    
184
  # and now rename instance to rename_target...
185
  AssertCommand(["gnt-instance", "rename", rename_source, rename_target])
186
  _CheckSsconfInstanceList(rename_target)
187
  qa_utils.RunInstanceCheck(rename_source, False)
188
  qa_utils.RunInstanceCheck(rename_target, False)
189

    
190
  # and back
191
  AssertCommand(["gnt-instance", "rename", rename_target, rename_source])
192
  _CheckSsconfInstanceList(rename_source)
193
  qa_utils.RunInstanceCheck(rename_target, False)
194

    
195

    
196
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
197
def TestInstanceFailover(instance):
198
  """gnt-instance failover"""
199
  cmd = ["gnt-instance", "failover", "--force", instance["name"]]
200

    
201
  # failover ...
202
  AssertCommand(cmd)
203
  qa_utils.RunInstanceCheck(instance, True)
204

    
205
  # ... and back
206
  AssertCommand(cmd)
207

    
208

    
209
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
210
def TestInstanceMigrate(instance):
211
  """gnt-instance migrate"""
212
  cmd = ["gnt-instance", "migrate", "--force", instance["name"]]
213

    
214
  # migrate ...
215
  AssertCommand(cmd)
216
  qa_utils.RunInstanceCheck(instance, True)
217

    
218
  # ... and back
219
  AssertCommand(cmd)
220

    
221
  # TODO: Split into multiple tests
222
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
223
  qa_utils.RunInstanceCheck(instance, False)
224
  AssertCommand(cmd, fail=True)
225
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
226
                 instance["name"]])
227
  AssertCommand(["gnt-instance", "start", instance["name"]])
228
  AssertCommand(cmd)
229
  qa_utils.RunInstanceCheck(instance, True)
230

    
231
  AssertCommand(["gnt-instance", "modify", "-B",
232
                 ("%s=%s" %
233
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)),
234
                 instance["name"]])
235

    
236
  AssertCommand(cmd, fail=True)
237
  qa_utils.RunInstanceCheck(instance, True)
238
  AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover",
239
                 instance["name"]])
240

    
241
  # TODO: Verify whether the default value is restored here (not hardcoded)
242
  AssertCommand(["gnt-instance", "modify", "-B",
243
                 ("%s=%s" %
244
                  (constants.BE_ALWAYS_FAILOVER, constants.VALUE_FALSE)),
245
                 instance["name"]])
246

    
247
  AssertCommand(cmd)
248
  qa_utils.RunInstanceCheck(instance, True)
249

    
250

    
251
def TestInstanceInfo(instance):
252
  """gnt-instance info"""
253
  AssertCommand(["gnt-instance", "info", instance["name"]])
254

    
255

    
256
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
257
def TestInstanceModify(instance):
258
  """gnt-instance modify"""
259
  # Assume /sbin/init exists on all systems
260
  test_kernel = "/sbin/init"
261
  test_initrd = test_kernel
262

    
263
  orig_maxmem = qa_config.get(constants.BE_MAXMEM)
264
  orig_minmem = qa_config.get(constants.BE_MINMEM)
265
  #orig_bridge = qa_config.get("bridge", "xen-br0")
266
  args = [
267
    ["-B", "%s=128" % constants.BE_MINMEM],
268
    ["-B", "%s=128" % constants.BE_MAXMEM],
269
    ["-B", "%s=%s,%s=%s" % (constants.BE_MINMEM, orig_minmem,
270
                            constants.BE_MAXMEM, orig_maxmem)],
271
    ["-B", "%s=2" % constants.BE_VCPUS],
272
    ["-B", "%s=1" % constants.BE_VCPUS],
273
    ["-B", "%s=%s" % (constants.BE_VCPUS, constants.VALUE_DEFAULT)],
274
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_TRUE)],
275
    ["-B", "%s=%s" % (constants.BE_ALWAYS_FAILOVER, constants.VALUE_DEFAULT)],
276

    
277
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
278
    ["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
279
    ["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
280
    ["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
281
    ["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
282

    
283
    # TODO: bridge tests
284
    #["--bridge", "xen-br1"],
285
    #["--bridge", orig_bridge],
286

    
287
    # TODO: Do these tests only with xen-hvm
288
    #["-H", "%s=acn" % constants.HV_BOOT_ORDER],
289
    #["-H", "%s=%s" % (constants.HV_BOOT_ORDER, constants.VALUE_DEFAULT)],
290
    ]
291
  for alist in args:
292
    AssertCommand(["gnt-instance", "modify"] + alist + [instance["name"]])
293

    
294
  # check no-modify
295
  AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True)
296

    
297
  # Marking offline/online while instance is running must fail
298
  for arg in ["--online", "--offline"]:
299
    AssertCommand(["gnt-instance", "modify", arg, instance["name"]], fail=True)
300

    
301

    
302
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
303
def TestInstanceStoppedModify(instance):
304
  """gnt-instance modify (stopped instance)"""
305
  name = instance["name"]
306

    
307
  # Instance was not marked offline; try marking it online once more
308
  AssertCommand(["gnt-instance", "modify", "--online", name])
309

    
310
  # Mark instance as offline
311
  AssertCommand(["gnt-instance", "modify", "--offline", name])
312

    
313
  # And online again
314
  AssertCommand(["gnt-instance", "modify", "--online", name])
315

    
316

    
317
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
318
def TestInstanceConvertDisk(instance, snode):
319
  """gnt-instance modify -t"""
320
  name = instance["name"]
321
  AssertCommand(["gnt-instance", "modify", "-t", "plain", name])
322
  AssertCommand(["gnt-instance", "modify", "-t", "drbd",
323
                 "-n", snode["primary"], name])
324

    
325

    
326
@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
327
def TestInstanceGrowDisk(instance):
328
  """gnt-instance grow-disk"""
329
  name = instance["name"]
330
  all_size = qa_config.get("disk")
331
  all_grow = qa_config.get("disk-growth")
332
  if not all_grow:
333
    # missing disk sizes but instance grow disk has been enabled,
334
    # let's set fixed/nomimal growth
335
    all_grow = ["128M" for _ in all_size]
336
  for idx, (size, grow) in enumerate(zip(all_size, all_grow)):
337
    # succeed in grow by amount
338
    AssertCommand(["gnt-instance", "grow-disk", name, str(idx), grow])
339
    # fail in grow to the old size
340
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
341
                   size], fail=True)
342
    # succeed to grow to old size + 2 * growth
343
    int_size = utils.ParseUnit(size)
344
    int_grow = utils.ParseUnit(grow)
345
    AssertCommand(["gnt-instance", "grow-disk", "--absolute", name, str(idx),
346
                   str(int_size + 2 * int_grow)])
347

    
348

    
349
def TestInstanceList():
350
  """gnt-instance list"""
351
  qa_utils.GenericQueryTest("gnt-instance", query.INSTANCE_FIELDS.keys())
352

    
353

    
354
def TestInstanceListFields():
355
  """gnt-instance list-fields"""
356
  qa_utils.GenericQueryFieldsTest("gnt-instance", query.INSTANCE_FIELDS.keys())
357

    
358

    
359
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
360
def TestInstanceConsole(instance):
361
  """gnt-instance console"""
362
  AssertCommand(["gnt-instance", "console", "--show-cmd", instance["name"]])
363

    
364

    
365
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
366
def TestReplaceDisks(instance, pnode, snode, othernode):
367
  """gnt-instance replace-disks"""
368
  # pylint: disable=W0613
369
  # due to unused pnode arg
370
  # FIXME: should be removed from the function completely
371
  def buildcmd(args):
372
    cmd = ["gnt-instance", "replace-disks"]
373
    cmd.extend(args)
374
    cmd.append(instance["name"])
375
    return cmd
376

    
377
  for data in [
378
    ["-p"],
379
    ["-s"],
380
    ["--new-secondary=%s" % othernode["primary"]],
381
    # and restore
382
    ["--new-secondary=%s" % snode["primary"]],
383
    ]:
384
    AssertCommand(buildcmd(data))
385

    
386
  AssertCommand(buildcmd(["-a"]))
387
  AssertCommand(["gnt-instance", "stop", instance["name"]])
388
  AssertCommand(buildcmd(["-a"]), fail=True)
389
  AssertCommand(["gnt-instance", "activate-disks", instance["name"]])
390
  AssertCommand(buildcmd(["-a"]))
391
  AssertCommand(["gnt-instance", "start", instance["name"]])
392

    
393

    
394
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
395
def TestInstanceExport(instance, node):
396
  """gnt-backup export -n ..."""
397
  name = instance["name"]
398
  AssertCommand(["gnt-backup", "export", "-n", node["primary"], name])
399
  return qa_utils.ResolveInstanceName(name)
400

    
401

    
402
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
403
def TestInstanceExportWithRemove(instance, node):
404
  """gnt-backup export --remove-instance"""
405
  AssertCommand(["gnt-backup", "export", "-n", node["primary"],
406
                 "--remove-instance", instance["name"]])
407

    
408

    
409
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
410
def TestInstanceExportNoTarget(instance):
411
  """gnt-backup export (without target node, should fail)"""
412
  AssertCommand(["gnt-backup", "export", instance["name"]], fail=True)
413

    
414

    
415
@InstanceCheck(None, INST_DOWN, FIRST_ARG)
416
def TestInstanceImport(newinst, node, expnode, name):
417
  """gnt-backup import"""
418
  cmd = (["gnt-backup", "import",
419
          "--disk-template=plain",
420
          "--no-ip-check",
421
          "--src-node=%s" % expnode["primary"],
422
          "--src-dir=%s/%s" % (constants.EXPORT_DIR, name),
423
          "--node=%s" % node["primary"]] +
424
         _GetGenericAddParameters(newinst))
425
  cmd.append(newinst["name"])
426
  AssertCommand(cmd)
427

    
428

    
429
def TestBackupList(expnode):
430
  """gnt-backup list"""
431
  AssertCommand(["gnt-backup", "list", "--node=%s" % expnode["primary"]])
432

    
433
  qa_utils.GenericQueryTest("gnt-backup", query.EXPORT_FIELDS.keys(),
434
                            namefield=None, test_unknown=False)
435

    
436

    
437
def TestBackupListFields():
438
  """gnt-backup list-fields"""
439
  qa_utils.GenericQueryFieldsTest("gnt-backup", query.EXPORT_FIELDS.keys())
440

    
441

    
442
def _TestInstanceDiskFailure(instance, node, node2, onmaster):
443
  """Testing disk failure."""
444
  master = qa_config.GetMasterNode()
445
  sq = utils.ShellQuoteArgs
446

    
447
  instance_full = qa_utils.ResolveInstanceName(instance["name"])
448
  node_full = qa_utils.ResolveNodeName(node)
449
  node2_full = qa_utils.ResolveNodeName(node2)
450

    
451
  print qa_utils.FormatInfo("Getting physical disk names")
452
  cmd = ["gnt-node", "volumes", "--separator=|", "--no-headers",
453
         "--output=node,phys,instance",
454
         node["primary"], node2["primary"]]
455
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
456

    
457
  # Get physical disk names
458
  re_disk = re.compile(r"^/dev/([a-z]+)\d+$")
459
  node2disk = {}
460
  for line in output.splitlines():
461
    (node_name, phys, inst) = line.split("|")
462
    if inst == instance_full:
463
      if node_name not in node2disk:
464
        node2disk[node_name] = []
465

    
466
      m = re_disk.match(phys)
467
      if not m:
468
        raise qa_error.Error("Unknown disk name format: %s" % phys)
469

    
470
      name = m.group(1)
471
      if name not in node2disk[node_name]:
472
        node2disk[node_name].append(name)
473

    
474
  if [node2_full, node_full][int(onmaster)] not in node2disk:
475
    raise qa_error.Error("Couldn't find physical disks used on"
476
                         " %s node" % ["secondary", "master"][int(onmaster)])
477

    
478
  print qa_utils.FormatInfo("Checking whether nodes have ability to stop"
479
                            " disks")
480
  for node_name, disks in node2disk.iteritems():
481
    cmds = []
482
    for disk in disks:
483
      cmds.append(sq(["test", "-f", _GetDiskStatePath(disk)]))
484
    AssertCommand(" && ".join(cmds), node=node_name)
485

    
486
  print qa_utils.FormatInfo("Getting device paths")
487
  cmd = ["gnt-instance", "activate-disks", instance["name"]]
488
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
489
  devpath = []
490
  for line in output.splitlines():
491
    (_, _, tmpdevpath) = line.split(":")
492
    devpath.append(tmpdevpath)
493
  print devpath
494

    
495
  print qa_utils.FormatInfo("Getting drbd device paths")
496
  cmd = ["gnt-instance", "info", instance["name"]]
497
  output = qa_utils.GetCommandOutput(master["primary"], sq(cmd))
498
  pattern = (r"\s+-\s+sd[a-z]+,\s+type:\s+drbd8?,\s+.*$"
499
             r"\s+primary:\s+(/dev/drbd\d+)\s+")
500
  drbddevs = re.findall(pattern, output, re.M)
501
  print drbddevs
502

    
503
  halted_disks = []
504
  try:
505
    print qa_utils.FormatInfo("Deactivating disks")
506
    cmds = []
507
    for name in node2disk[[node2_full, node_full][int(onmaster)]]:
508
      halted_disks.append(name)
509
      cmds.append(sq(["echo", "offline"]) + " >%s" % _GetDiskStatePath(name))
510
    AssertCommand(" && ".join(cmds), node=[node2, node][int(onmaster)])
511

    
512
    print qa_utils.FormatInfo("Write to disks and give some time to notice"
513
                              " to notice the problem")
514
    cmds = []
515
    for disk in devpath:
516
      cmds.append(sq(["dd", "count=1", "bs=512", "conv=notrunc",
517
                      "if=%s" % disk, "of=%s" % disk]))
518
    for _ in (0, 1, 2):
519
      AssertCommand(" && ".join(cmds), node=node)
520
      time.sleep(3)
521

    
522
    print qa_utils.FormatInfo("Debugging info")
523
    for name in drbddevs:
524
      AssertCommand(["drbdsetup", name, "show"], node=node)
525

    
526
    AssertCommand(["gnt-instance", "info", instance["name"]])
527

    
528
  finally:
529
    print qa_utils.FormatInfo("Activating disks again")
530
    cmds = []
531
    for name in halted_disks:
532
      cmds.append(sq(["echo", "running"]) + " >%s" % _GetDiskStatePath(name))
533
    AssertCommand("; ".join(cmds), node=[node2, node][int(onmaster)])
534

    
535
  if onmaster:
536
    for name in drbddevs:
537
      AssertCommand(["drbdsetup", name, "detach"], node=node)
538
  else:
539
    for name in drbddevs:
540
      AssertCommand(["drbdsetup", name, "disconnect"], node=node2)
541

    
542
  # TODO
543
  #AssertCommand(["vgs"], [node2, node][int(onmaster)])
544

    
545
  print qa_utils.FormatInfo("Making sure disks are up again")
546
  AssertCommand(["gnt-instance", "replace-disks", instance["name"]])
547

    
548
  print qa_utils.FormatInfo("Restarting instance")
549
  AssertCommand(["gnt-instance", "shutdown", instance["name"]])
550
  AssertCommand(["gnt-instance", "startup", instance["name"]])
551

    
552
  AssertCommand(["gnt-cluster", "verify"])
553

    
554

    
555
def TestInstanceMasterDiskFailure(instance, node, node2):
556
  """Testing disk failure on master node."""
557
  # pylint: disable=W0613
558
  # due to unused args
559
  print qa_utils.FormatError("Disk failure on primary node cannot be"
560
                             " tested due to potential crashes.")
561
  # The following can cause crashes, thus it's disabled until fixed
562
  #return _TestInstanceDiskFailure(instance, node, node2, True)
563

    
564

    
565
def TestInstanceSecondaryDiskFailure(instance, node, node2):
566
  """Testing disk failure on secondary node."""
567
  return _TestInstanceDiskFailure(instance, node, node2, False)