+
+ return rapi.client_utils.PollJob(_rapi_client, job_id,
+ cli.StdioJobPollReportCb())
+
+
+def TestRapiNodeGroups():
+ """Test several node group operations using RAPI.
+
+ """
+ groups = qa_config.get("groups", {})
+ group1, group2, group3 = groups.get("inexistent-groups",
+ ["group1", "group2", "group3"])[:3]
+
+ # Create a group with no attributes
+ body = {
+ "name": group1,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/groups", _VerifyReturnsJob, "POST", body),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ # Create a group specifying alloc_policy
+ body = {
+ "name": group2,
+ "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/groups", _VerifyReturnsJob, "POST", body),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ # Modify alloc_policy
+ body = {
+ "alloc_policy": constants.ALLOC_POLICY_UNALLOCABLE,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/groups/%s/modify" % group1, _VerifyReturnsJob, "PUT", body),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ # Rename a group
+ body = {
+ "new_name": group3,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/groups/%s/rename" % group2, _VerifyReturnsJob, "PUT", body),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ # Delete groups
+ for group in [group1, group3]:
+ (job_id, ) = _DoTests([
+ ("/2/groups/%s" % group, _VerifyReturnsJob, "DELETE", None),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+
+def TestRapiInstanceAdd(node, use_client):
+ """Test adding a new instance via RAPI"""
+ instance = qa_config.AcquireInstance()
+ try:
+ disk_sizes = [utils.ParseUnit(size) for size in qa_config.get("disk")]
+ disks = [{"size": size} for size in disk_sizes]
+ nic0_mac = qa_config.GetInstanceNicMac(instance,
+ default=constants.VALUE_GENERATE)
+ nics = [{
+ constants.INIC_MAC: nic0_mac,
+ }]
+
+ beparams = {
+ constants.BE_MAXMEM: utils.ParseUnit(qa_config.get(constants.BE_MAXMEM)),
+ constants.BE_MINMEM: utils.ParseUnit(qa_config.get(constants.BE_MINMEM)),
+ }
+
+ if use_client:
+ job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
+ instance["name"],
+ constants.DT_PLAIN,
+ disks, nics,
+ os=qa_config.get("os"),
+ pnode=node["primary"],
+ beparams=beparams)
+ else:
+ body = {
+ "__version__": 1,
+ "mode": constants.INSTANCE_CREATE,
+ "name": instance["name"],
+ "os_type": qa_config.get("os"),
+ "disk_template": constants.DT_PLAIN,
+ "pnode": node["primary"],
+ "beparams": beparams,
+ "disks": disks,
+ "nics": nics,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/instances", _VerifyReturnsJob, "POST", body),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ return instance
+ except:
+ qa_config.ReleaseInstance(instance)
+ raise
+
+
+@InstanceCheck(None, INST_DOWN, FIRST_ARG)
+def TestRapiInstanceRemove(instance, use_client):
+ """Test removing instance via RAPI"""
+ if use_client:
+ job_id = _rapi_client.DeleteInstance(instance["name"])
+ else:
+ (job_id, ) = _DoTests([
+ ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
+ ])
+
+ _WaitForRapiJob(job_id)
+
+ qa_config.ReleaseInstance(instance)
+
+
+@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
+def TestRapiInstanceMigrate(instance):
+ """Test migrating instance via RAPI"""
+ # Move to secondary node
+ _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
+ qa_utils.RunInstanceCheck(instance, True)
+ # And back to previous primary
+ _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
+
+
+@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
+def TestRapiInstanceFailover(instance):
+ """Test failing over instance via RAPI"""
+ # Move to secondary node
+ _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
+ qa_utils.RunInstanceCheck(instance, True)
+ # And back to previous primary
+ _WaitForRapiJob(_rapi_client.FailoverInstance(instance["name"]))
+
+
+@InstanceCheck(INST_UP, INST_DOWN, FIRST_ARG)
+def TestRapiInstanceShutdown(instance):
+ """Test stopping an instance via RAPI"""
+ _WaitForRapiJob(_rapi_client.ShutdownInstance(instance["name"]))
+
+
+@InstanceCheck(INST_DOWN, INST_UP, FIRST_ARG)
+def TestRapiInstanceStartup(instance):
+ """Test starting an instance via RAPI"""
+ _WaitForRapiJob(_rapi_client.StartupInstance(instance["name"]))
+
+
+@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
+def TestRapiInstanceRenameAndBack(rename_source, rename_target):
+ """Test renaming instance via RAPI
+
+ This must leave the instance with the original name (in the
+ non-failure case).
+
+ """
+ _WaitForRapiJob(_rapi_client.RenameInstance(rename_source, rename_target))
+ qa_utils.RunInstanceCheck(rename_source, False)
+ qa_utils.RunInstanceCheck(rename_target, False)
+ _WaitForRapiJob(_rapi_client.RenameInstance(rename_target, rename_source))
+ qa_utils.RunInstanceCheck(rename_target, False)
+
+
+@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
+def TestRapiInstanceReinstall(instance):
+ """Test reinstalling an instance via RAPI"""
+ _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"]))
+ # By default, the instance is started again
+ qa_utils.RunInstanceCheck(instance, True)
+
+ # Reinstall again without starting
+ _WaitForRapiJob(_rapi_client.ReinstallInstance(instance["name"],
+ no_startup=True))
+
+
+@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
+def TestRapiInstanceReplaceDisks(instance):
+ """Test replacing instance disks via RAPI"""
+ _WaitForRapiJob(_rapi_client.ReplaceInstanceDisks(instance["name"],
+ mode=constants.REPLACE_DISK_AUTO, disks=[]))
+ _WaitForRapiJob(_rapi_client.ReplaceInstanceDisks(instance["name"],
+ mode=constants.REPLACE_DISK_SEC, disks="0"))
+
+
+@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
+def TestRapiInstanceModify(instance):
+ """Test modifying instance via RAPI"""
+ def _ModifyInstance(**kwargs):
+ _WaitForRapiJob(_rapi_client.ModifyInstance(instance["name"], **kwargs))
+
+ _ModifyInstance(hvparams={
+ constants.HV_KERNEL_ARGS: "single",
+ })
+
+ _ModifyInstance(beparams={
+ constants.BE_VCPUS: 3,
+ })
+
+ _ModifyInstance(beparams={
+ constants.BE_VCPUS: constants.VALUE_DEFAULT,
+ })
+
+ _ModifyInstance(hvparams={
+ constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
+ })
+
+
+@InstanceCheck(INST_UP, INST_UP, FIRST_ARG)
+def TestRapiInstanceConsole(instance):
+ """Test getting instance console information via RAPI"""
+ result = _rapi_client.GetInstanceConsole(instance["name"])
+ console = objects.InstanceConsole.FromDict(result)
+ AssertEqual(console.Validate(), True)
+ AssertEqual(console.instance, qa_utils.ResolveInstanceName(instance["name"]))
+
+
+@InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG)
+def TestRapiStoppedInstanceConsole(instance):
+ """Test getting stopped instance's console information via RAPI"""
+ try:
+ _rapi_client.GetInstanceConsole(instance["name"])
+ except rapi.client.GanetiApiError, err:
+ AssertEqual(err.code, 503)
+ else:
+ raise qa_error.Error("Getting console for stopped instance didn't"
+ " return HTTP 503")
+
+
+def GetOperatingSystems():
+ """Retrieves a list of all available operating systems.
+
+ """
+ return _rapi_client.GetOperatingSystems()
+
+
+def TestInterClusterInstanceMove(src_instance, dest_instance,
+ pnode, snode, tnode):
+ """Test tools/move-instance"""
+ master = qa_config.GetMasterNode()
+
+ rapi_pw_file = tempfile.NamedTemporaryFile()
+ rapi_pw_file.write(_rapi_password)
+ rapi_pw_file.flush()
+
+ # TODO: Run some instance tests before moving back
+
+ if snode is None:
+ # instance is not redundant, but we still need to pass a node
+ # (which will be ignored)
+ fsec = tnode
+ else:
+ fsec = snode
+ # note: pnode:snode are the *current* nodes, so we move it first to
+ # tnode:pnode, then back to pnode:snode
+ for si, di, pn, sn in [(src_instance["name"], dest_instance["name"],
+ tnode["primary"], pnode["primary"]),
+ (dest_instance["name"], src_instance["name"],
+ pnode["primary"], fsec["primary"])]:
+ cmd = [
+ "../tools/move-instance",
+ "--verbose",
+ "--src-ca-file=%s" % _rapi_ca.name,
+ "--src-username=%s" % _rapi_username,
+ "--src-password-file=%s" % rapi_pw_file.name,
+ "--dest-instance-name=%s" % di,
+ "--dest-primary-node=%s" % pn,
+ "--dest-secondary-node=%s" % sn,
+ "--net=0:mac=%s" % constants.VALUE_GENERATE,
+ master["primary"],
+ master["primary"],
+ si,
+ ]
+
+ qa_utils.RunInstanceCheck(di, False)
+ AssertEqual(StartLocalCommand(cmd).wait(), 0)
+ qa_utils.RunInstanceCheck(si, False)
+ qa_utils.RunInstanceCheck(di, True)