Revision bfc2002f

b/lib/rapi/client.py
45 45
REPLACE_DISK_SECONDARY = "replace_on_secondary"
46 46
REPLACE_DISK_CHG = "replace_new_secondary"
47 47
REPLACE_DISK_AUTO = "replace_auto"
48
VALID_REPLACEMENT_MODES = frozenset([
49
  REPLACE_DISK_PRI,
50
  REPLACE_DISK_SECONDARY,
51
  REPLACE_DISK_CHG,
52
  REPLACE_DISK_AUTO,
53
  ])
54 48
VALID_NODE_ROLES = frozenset([
55 49
  "drained", "master", "master-candidate", "offline", "regular",
56 50
  ])
......
79 73
    self.code = code
80 74

  
81 75

  
82
class InvalidReplacementMode(Error):
83
  """Raised when an invalid disk replacement mode is attempted.
84

  
85
  """
86
  pass
87

  
88

  
89 76
class InvalidNodeRole(Error):
90 77
  """Raised when an invalid node role is used.
91 78

  
......
721 708
                             ("/%s/instances/%s/reinstall" %
722 709
                              (GANETI_RAPI_VERSION, instance)), query, None)
723 710

  
724
  def ReplaceInstanceDisks(self, instance, disks, mode=REPLACE_DISK_AUTO,
711
  def ReplaceInstanceDisks(self, instance, disks=None, mode=REPLACE_DISK_AUTO,
725 712
                           remote_node=None, iallocator=None, dry_run=False):
726 713
    """Replaces disks on an instance.
727 714

  
728 715
    @type instance: str
729 716
    @param instance: instance whose disks to replace
730
    @type disks: list of str
731
    @param disks: disks to replace
717
    @type disks: list of ints
718
    @param disks: Indexes of disks to replace
732 719
    @type mode: str
733 720
    @param mode: replacement mode to use (defaults to replace_auto)
734 721
    @type remote_node: str or None
......
743 730
    @rtype: int
744 731
    @return: job id
745 732

  
746
    @raises InvalidReplacementMode: If an invalid disk replacement mode is given
747
    @raises GanetiApiError: If no secondary node is given with a non-auto
748
        replacement mode is requested.
749

  
750 733
    """
751
    if mode not in VALID_REPLACEMENT_MODES:
752
      raise InvalidReplacementMode("%s is not a valid disk replacement mode" %
753
                                   mode)
754

  
755 734
    query = [
756 735
      ("mode", mode),
757
      ("disks", ",".join(disks)),
758 736
      ]
759 737

  
760
    if mode == REPLACE_DISK_AUTO:
761
      query.append(("iallocator", iallocator))
762
    elif mode == REPLACE_DISK_SECONDARY:
763
      if remote_node is None:
764
        raise GanetiApiError("Missing secondary node")
738
    if disks:
739
      query.append(("disks", ",".join(str(idx) for idx in disks)))
740

  
741
    if remote_node:
765 742
      query.append(("remote_node", remote_node))
766 743

  
744
    if iallocator:
745
      query.append(("iallocator", iallocator))
746

  
767 747
    if dry_run:
768 748
      query.append(("dry-run", 1))
769 749

  
b/test/ganeti.rapi.client_unittest.py
309 309
  def testReplaceInstanceDisks(self):
310 310
    self.rapi.AddResponse("999")
311 311
    job_id = self.client.ReplaceInstanceDisks("instance-name",
312
        ["hda", "hdc"], dry_run=True, iallocator="hail")
312
        disks=[0, 1], dry_run=True, iallocator="hail")
313 313
    self.assertEqual(999, job_id)
314 314
    self.assertHandler(rlib2.R_2_instances_name_replace_disks)
315 315
    self.assertItems(["instance-name"])
316
    self.assertQuery("disks", ["hda,hdc"])
316
    self.assertQuery("disks", ["0,1"])
317 317
    self.assertQuery("mode", ["replace_auto"])
318 318
    self.assertQuery("iallocator", ["hail"])
319 319
    self.assertDryRun()
320 320

  
321
    self.assertRaises(client.InvalidReplacementMode,
322
                      self.client.ReplaceInstanceDisks,
323
                      "instance_a", ["hda"], mode="invalid_mode")
324
    self.assertRaises(client.GanetiApiError,
325
                      self.client.ReplaceInstanceDisks,
326
                      "instance-foo", ["hda"], mode="replace_on_secondary")
327

  
328 321
    self.rapi.AddResponse("1000")
329 322
    job_id = self.client.ReplaceInstanceDisks("instance-bar",
330
        ["hda"], mode="replace_on_secondary", remote_node="foo-node",
323
        disks=[1], mode="replace_on_secondary", remote_node="foo-node",
331 324
        dry_run=True)
332 325
    self.assertEqual(1000, job_id)
333 326
    self.assertItems(["instance-bar"])
334
    self.assertQuery("disks", ["hda"])
327
    self.assertQuery("disks", ["1"])
335 328
    self.assertQuery("remote_node", ["foo-node"])
336 329
    self.assertDryRun()
337 330

  
331
    self.rapi.AddResponse("5175")
332
    self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo"))
333
    self.assertItems(["instance-moo"])
334
    self.assertQuery("disks", None)
335

  
338 336
  def testGetJobs(self):
339 337
    self.rapi.AddResponse('[ { "id": "123", "uri": "\\/2\\/jobs\\/123" },'
340 338
                          '  { "id": "124", "uri": "\\/2\\/jobs\\/124" } ]')

Also available in: Unified diff