diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py index cc6d4704ea36b389ec7abc97674cb6c10c5f3f5b..3bc81998f04fcc3ea796b9768b3805938505595a 100755 --- a/qa/ganeti-qa.py +++ b/qa/ganeti-qa.py @@ -208,6 +208,19 @@ def RunExportImportTests(instance, pnode): finally: qa_config.ReleaseNode(expnode) + if (qa_rapi.Enabled() and + qa_config.TestEnabled("inter-cluster-instance-move")): + newinst = qa_config.AcquireInstance() + try: + pnode2 = qa_config.AcquireNode(exclude=pnode) + try: + RunTest(qa_rapi.TestInterClusterInstanceMove, instance, newinst, + pnode2, pnode) + finally: + qa_config.ReleaseNode(pnode2) + finally: + qa_config.ReleaseInstance(newinst) + def RunDaemonTests(instance, pnode): """Test the ganeti-watcher script. diff --git a/qa/qa-sample.json b/qa/qa-sample.json index ae09588c02ce7a3c481d03e64d64d8ad816f1400..193f51ee0e1e5d1676e23bb85b8da55480f9406b 100644 --- a/qa/qa-sample.json +++ b/qa/qa-sample.json @@ -87,6 +87,9 @@ "# Disabled by default because it takes rather long": null, "instance-replace-disks": false, + "# Whether to test the tools/move-instance utility": null, + "inter-cluster-instance-move": false, + "# Make sure not to include the disk(s) required for Dom0 to be": null, "# included in the volume group used for instances. Otherwise": null, "# whole system may stop working until restarted.": null, diff --git a/qa/qa_rapi.py b/qa/qa_rapi.py index eb35adbf2577b5b2ba77cef1e38decc5ac7a3e6b..a171121193b7f7c0cc75a160f78db48dd5766fce 100644 --- a/qa/qa_rapi.py +++ b/qa/qa_rapi.py @@ -39,11 +39,13 @@ import qa_utils import qa_error from qa_utils import (AssertEqual, AssertNotEqual, AssertIn, AssertMatch, - StartSSH) + StartLocalCommand) _rapi_ca = None _rapi_client = None +_rapi_username = None +_rapi_password = None def Setup(username, password): @@ -52,6 +54,11 @@ def Setup(username, password): """ global _rapi_ca global _rapi_client + global _rapi_username + global _rapi_password + + _rapi_username = username + _rapi_password = password master = qa_config.GetMasterNode() @@ -332,3 +339,32 @@ def TestRapiInstanceRemove(instance, use_client): _WaitForRapiJob(job_id) qa_config.ReleaseInstance(instance) + + +def TestInterClusterInstanceMove(src_instance, dest_instance, pnode, snode): + """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 + for srcname, destname in [(src_instance["name"], dest_instance["name"]), + (dest_instance["name"], src_instance["name"])]: + 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" % destname, + "--dest-primary-node=%s" % pnode["primary"], + "--dest-secondary-node=%s" % snode["primary"], + + master["primary"], + master["primary"], + srcname, + ] + + AssertEqual(StartLocalCommand(cmd).wait(), 0) diff --git a/qa/qa_utils.py b/qa/qa_utils.py index 5a2c4e7d6be64d6fd27d0f0894c802bb426af7c9..afcc19101e66f71ab1fd7b5c4fb42ea932698515 100644 --- a/qa/qa_utils.py +++ b/qa/qa_utils.py @@ -122,25 +122,29 @@ def GetSSHCommand(node, cmd, strict=True): args.append(node) args.append(cmd) - print 'SSH:', utils.ShellQuoteArgs(args) - return args +def StartLocalCommand(cmd, **kwargs): + """Starts a local command. + + """ + print "Command: %s" % utils.ShellQuoteArgs(cmd) + return subprocess.Popen(cmd, shell=False, **kwargs) + + def StartSSH(node, cmd, strict=True): """Starts SSH. """ - return subprocess.Popen(GetSSHCommand(node, cmd, strict=strict), - shell=False) + return StartLocalCommand(GetSSHCommand(node, cmd, strict=strict)) def GetCommandOutput(node, cmd): """Returns the output of a command executed on the given node. """ - p = subprocess.Popen(GetSSHCommand(node, cmd), - shell=False, stdout=subprocess.PIPE) + p = StartLocalCommand(GetSSHCommand(node, cmd), stdout=subprocess.PIPE) AssertEqual(p.wait(), 0) return p.stdout.read()