Revision e23881ed

b/doc/rapi.rst
824 824
Takes no parameters.
825 825

  
826 826

  
827
``/2/instances/[instance_name]/disk/[disk_index]/grow``
828
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
829

  
830
Grows one disk of an instance.
831

  
832
Supports the following commands: ``POST``.
833

  
834
``POST``
835
~~~~~~~~
836

  
837
Returns a job ID.
838

  
839
Body parameters:
840

  
841
``amount`` (int, required)
842
  Amount of disk space to add.
843
``wait_for_sync`` (bool)
844
  Whether to wait for the disk to synchronize.
845

  
846

  
827 847
``/2/instances/[instance_name]/prepare-export``
828 848
+++++++++++++++++++++++++++++++++++++++++++++++++
829 849

  
b/lib/rapi/client.py
757 757
                             ("/%s/instances/%s/modify" %
758 758
                              (GANETI_RAPI_VERSION, instance)), None, body)
759 759

  
760
  def GrowInstanceDisk(self, instance, disk, amount, wait_for_sync=None):
761
    """Grows a disk of an instance.
762

  
763
    More details for parameters can be found in the RAPI documentation.
764

  
765
    @type instance: string
766
    @param instance: Instance name
767
    @type disk: integer
768
    @param disk: Disk index
769
    @type amount: integer
770
    @param amount: Grow disk by this amount (MiB)
771
    @type wait_for_sync: bool
772
    @param wait_for_sync: Wait for disk to synchronize
773
    @rtype: int
774
    @return: job id
775

  
776
    """
777
    body = {
778
      "amount": amount,
779
      }
780

  
781
    if wait_for_sync is not None:
782
      body["wait_for_sync"] = wait_for_sync
783

  
784
    return self._SendRequest(HTTP_POST,
785
                             ("/%s/instances/%s/disk/%s/grow" %
786
                              (GANETI_RAPI_VERSION, instance, disk)),
787
                             None, body)
788

  
760 789
  def GetInstanceTags(self, instance):
761 790
    """Gets tags for an instance.
762 791

  
b/lib/rapi/connector.py
38 38

  
39 39

  
40 40
_NAME_PATTERN = r"[\w\._-]+"
41
_DISK_PATTERN = r"\d+"
41 42

  
42 43
# the connection map is created at the end of this file
43 44
CONNECTOR = {}
......
147 148

  
148 149

  
149 150
def GetHandlers(node_name_pattern, instance_name_pattern,
150
                group_name_pattern, job_id_pattern):
151
                group_name_pattern, job_id_pattern, disk_pattern):
151 152
  """Returns all supported resources and their handlers.
152 153

  
153 154
  """
......
211 212
      rlib2.R_2_instances_name_rename,
212 213
    re.compile(r'^/2/instances/(%s)/modify$' % instance_name_pattern):
213 214
      rlib2.R_2_instances_name_modify,
215
    re.compile(r"^/2/instances/(%s)/disk/(%s)/grow$" %
216
               (instance_name_pattern, disk_pattern)):
217
      rlib2.R_2_instances_name_disk_grow,
214 218

  
215 219
    "/2/groups": rlib2.R_2_groups,
216 220
    re.compile(r'^/2/groups/(%s)$' % group_name_pattern):
......
236 240

  
237 241

  
238 242
CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN,
239
                             constants.JOB_ID_TEMPLATE))
243
                             constants.JOB_ID_TEMPLATE, _DISK_PATTERN))
b/lib/rapi/rlib2.py
1299 1299
    return baserlib.SubmitJob([op])
1300 1300

  
1301 1301

  
1302
class R_2_instances_name_disk_grow(baserlib.R_Generic):
1303
  """/2/instances/[instance_name]/disk/[index]/grow resource.
1304

  
1305
  """
1306
  def POST(self):
1307
    """Increases the size of an instance disk.
1308

  
1309
    @return: a job id
1310

  
1311
    """
1312
    op = baserlib.FillOpcode(opcodes.OpGrowDisk, self.request_body, {
1313
      "instance_name": self.items[0],
1314
      "disk": int(self.items[1]),
1315
      })
1316

  
1317
    return baserlib.SubmitJob([op])
1318

  
1319

  
1302 1320
class _R_Tags(baserlib.R_Generic):
1303 1321
  """ Quasiclass for tagging resources
1304 1322

  
b/test/docs_unittest.py
79 79
    instance_name = "[instance_name]"
80 80
    group_name = "[group_name]"
81 81
    job_id = "[job_id]"
82
    disk_index = "[disk_index]"
82 83

  
83 84
    resources = connector.GetHandlers(re.escape(node_name),
84 85
                                      re.escape(instance_name),
85 86
                                      re.escape(group_name),
86
                                      re.escape(job_id))
87
                                      re.escape(job_id),
88
                                      re.escape(disk_index))
87 89

  
88 90
    titles = []
89 91

  
b/test/ganeti.rapi.client_unittest.py
1051 1051
      self.assertEqual(data["maintain_node_health"], mnh)
1052 1052
      self.assertEqual(self.rapi.CountPending(), 0)
1053 1053

  
1054
  def testGrowInstanceDisk(self):
1055
    for idx, wait_for_sync in enumerate([None, False, True]):
1056
      amount = 128 + (512 * idx)
1057
      self.assertEqual(self.rapi.CountPending(), 0)
1058
      self.rapi.AddResponse("30783")
1059
      self.assertEqual(30783,
1060
        self.client.GrowInstanceDisk("eze8ch", idx, amount,
1061
                                     wait_for_sync=wait_for_sync))
1062
      self.assertHandler(rlib2.R_2_instances_name_disk_grow)
1063
      self.assertItems(["eze8ch", str(idx)])
1064
      data = serializer.LoadJson(self.rapi.GetLastRequestData())
1065
      if wait_for_sync is None:
1066
        self.assertEqual(len(data), 1)
1067
        self.assert_("wait_for_sync" not in data)
1068
      else:
1069
        self.assertEqual(len(data), 2)
1070
        self.assertEqual(data["wait_for_sync"], wait_for_sync)
1071
      self.assertEqual(data["amount"], amount)
1072
      self.assertEqual(self.rapi.CountPending(), 0)
1073

  
1054 1074

  
1055 1075
if __name__ == '__main__':
1056 1076
  client.UsesRapiClient(testutils.GanetiTestProgram)()

Also available in: Unified diff