Revision c0a146a1

b/doc/rapi.rst
876 876
   :exclude: instance_name, live
877 877

  
878 878

  
879
``/2/instances/[instance_name]/failover``
880
+++++++++++++++++++++++++++++++++++++++++
881

  
882
Does a failover of an instance.
883

  
884
Supports the following commands: ``PUT``.
885

  
886
``PUT``
887
~~~~~~~
888

  
889
Returns a job ID.
890

  
891
Body parameters:
892

  
893
.. opcode_params:: OP_INSTANCE_FAILOVER
894
   :exclude: instance_name
895

  
896

  
879 897
``/2/instances/[instance_name]/rename``
880 898
++++++++++++++++++++++++++++++++++++++++
881 899

  
b/lib/rapi/client.py
1073 1073
                             ("/%s/instances/%s/migrate" %
1074 1074
                              (GANETI_RAPI_VERSION, instance)), None, body)
1075 1075

  
1076
  def FailoverInstance(self, instance, iallocator=None,
1077
                       ignore_consistency=None, target_node=None):
1078
    """Does a failover of an instance.
1079

  
1080
    @type instance: string
1081
    @param instance: Instance name
1082
    @type iallocator: string
1083
    @param iallocator: Iallocator for deciding the target node for
1084
      shared-storage instances
1085
    @type ignore_consistency: bool
1086
    @param ignore_consistency: Whether to ignore disk consistency
1087
    @type target_node: string
1088
    @param target_node: Target node for shared-storage instances
1089
    @rtype: string
1090
    @return: job id
1091

  
1092
    """
1093
    body = {}
1094

  
1095
    if iallocator is not None:
1096
      body["iallocator"] = iallocator
1097

  
1098
    if ignore_consistency is not None:
1099
      body["ignore_consistency"] = ignore_consistency
1100

  
1101
    if target_node is not None:
1102
      body["target_node"] = target_node
1103

  
1104
    return self._SendRequest(HTTP_PUT,
1105
                             ("/%s/instances/%s/failover" %
1106
                              (GANETI_RAPI_VERSION, instance)), None, body)
1107

  
1076 1108
  def RenameInstance(self, instance, new_name, ip_check=None, name_check=None):
1077 1109
    """Changes the name of an instance.
1078 1110

  
b/lib/rapi/connector.py
211 211
      rlib2.R_2_instances_name_export,
212 212
    re.compile(r'^/2/instances/(%s)/migrate$' % instance_name_pattern):
213 213
      rlib2.R_2_instances_name_migrate,
214
    re.compile(r'^/2/instances/(%s)/failover$' % instance_name_pattern):
215
      rlib2.R_2_instances_name_failover,
214 216
    re.compile(r'^/2/instances/(%s)/rename$' % instance_name_pattern):
215 217
      rlib2.R_2_instances_name_rename,
216 218
    re.compile(r'^/2/instances/(%s)/modify$' % instance_name_pattern):
b/lib/rapi/rlib2.py
1122 1122
    return baserlib.SubmitJob([op])
1123 1123

  
1124 1124

  
1125
class R_2_instances_name_failover(baserlib.R_Generic):
1126
  """/2/instances/[instance_name]/failover resource.
1127

  
1128
  """
1129
  def PUT(self):
1130
    """Does a failover of an instance.
1131

  
1132
    @return: a job id
1133

  
1134
    """
1135
    baserlib.CheckType(self.request_body, dict, "Body contents")
1136

  
1137
    op = baserlib.FillOpcode(opcodes.OpInstanceFailover, self.request_body, {
1138
      "instance_name": self.items[0],
1139
      })
1140

  
1141
    return baserlib.SubmitJob([op])
1142

  
1143

  
1125 1144
def _ParseRenameInstanceRequest(name, data):
1126 1145
  """Parses a request for renaming an instance.
1127 1146

  
b/qa/ganeti-qa.py
366 366

  
367 367
  """
368 368
  RunTestIf("instance-failover", qa_instance.TestInstanceFailover, instance)
369
  RunTestIf(["instance-failover", "rapi"],
370
            qa_rapi.TestRapiInstanceFailover, instance)
369 371

  
370 372
  RunTestIf("instance-migrate", qa_instance.TestInstanceMigrate, instance)
371 373
  RunTestIf(["instance-migrate", "rapi"],
b/qa/qa_rapi.py
590 590
  _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
591 591

  
592 592

  
593
def TestRapiInstanceFailover(instance):
594
  """Test failing over instance via RAPI"""
595
  # Move to secondary node
596
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
597
  # And back to previous primary
598
  _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
599

  
600

  
593 601
def TestRapiInstanceRename(rename_source, rename_target):
594 602
  """Test renaming instance via RAPI"""
595 603
  _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
b/test/ganeti.rapi.client_unittest.py
738 738
        self.assertEqual(data["mode"], mode)
739 739
        self.assertEqual(data["cleanup"], cleanup)
740 740

  
741
  def testFailoverInstanceDefaults(self):
742
    self.rapi.AddResponse("7639")
743
    job_id = self.client.FailoverInstance("inst13579")
744
    self.assertEqual(job_id, 7639)
745
    self.assertHandler(rlib2.R_2_instances_name_failover)
746
    self.assertItems(["inst13579"])
747

  
748
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
749
    self.assertFalse(data)
750

  
751
  def testFailoverInstance(self):
752
    for iallocator in ["dumb", "hail"]:
753
      for ignore_consistency in [False, True]:
754
        for target_node in ["node-a", "node2"]:
755
          self.rapi.AddResponse("19161")
756
          job_id = \
757
            self.client.FailoverInstance("inst251", iallocator=iallocator,
758
                                         ignore_consistency=ignore_consistency,
759
                                         target_node=target_node)
760
          self.assertEqual(job_id, 19161)
761
          self.assertHandler(rlib2.R_2_instances_name_failover)
762
          self.assertItems(["inst251"])
763

  
764
          data = serializer.LoadJson(self.rapi.GetLastRequestData())
765
          self.assertEqual(len(data), 3)
766
          self.assertEqual(data["iallocator"], iallocator)
767
          self.assertEqual(data["ignore_consistency"], ignore_consistency)
768
          self.assertEqual(data["target_node"], target_node)
769
          self.assertEqual(self.rapi.CountPending(), 0)
770

  
741 771
  def testRenameInstanceDefaults(self):
742 772
    new_name = "newnametha7euqu"
743 773
    self.rapi.AddResponse("8791")

Also available in: Unified diff