import qa_logging
import qa_utils
+ from qa_instance import GetInstanceInfo
+from qa_instance import IsDiskReplacingSupported
from qa_instance import IsFailoverSupported
from qa_instance import IsMigrationSupported
-from qa_instance import IsDiskReplacingSupported
-from qa_utils import (AssertEqual, AssertIn, AssertMatch, StartLocalCommand)
+from qa_job_utils import RunWithLocks
+from qa_utils import (AssertEqual, AssertIn, AssertMatch, AssertCommand,
+ StartLocalCommand)
from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG
# (which will be ignored)
snode = tnode
pnode = inodes[0]
- # note: pnode:snode are the *current* nodes, so we move it first to
- # tnode:pnode, then back to pnode:snode
- for current_src_inst, current_dest_inst, target_pnode, target_snode in \
- [(src_instance.name, dest_instance.name, tnode.primary, pnode.primary),
- (dest_instance.name, src_instance.name, pnode.primary, snode.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" % current_dest_inst,
- "--dest-primary-node=%s" % target_pnode,
- "--dest-secondary-node=%s" % target_snode,
- "--net=0:mac=%s" % constants.VALUE_GENERATE,
- master.primary,
- master.primary,
- current_src_inst,
- ]
-
- # Some uses of this test might require that RAPI-only commands are used,
- # and the checks are command-line based.
-
- if perform_checks:
- qa_utils.RunInstanceCheck(current_dest_inst, False)
-
- AssertEqual(StartLocalCommand(cmd).wait(), 0)
- if perform_checks:
- qa_utils.RunInstanceCheck(current_src_inst, False)
- qa_utils.RunInstanceCheck(current_dest_inst, True)
+ # pnode:snode are the *current* nodes, and the first move is an
+ # iallocator-guided move outside of pnode. The node lock for the pnode
+ # assures that this happens, and while we cannot be sure where the instance
+ # will land, it is a real move.
+ locks = {locking.LEVEL_NODE: [pnode.primary]}
+ RunWithLocks(_InvokeMoveInstance, locks, 600.0, False,
+ dest_instance.name, src_instance.name, rapi_pw_file.name,
+ master.primary, perform_checks)
+
+ # And then back to pnode:snode
+ _InvokeMoveInstance(src_instance.name, dest_instance.name, rapi_pw_file.name,
+ master.primary, perform_checks,
+ target_nodes=(pnode.primary, snode.primary))
+
+
+ _DRBD_SECRET_RE = re.compile('shared-secret.*"([0-9A-Fa-f]+)"')
+
+
+ def _RetrieveSecret(instance, pnode):
+ """Retrieves the DRBD secret given an instance object and the primary node.
+
+ @type instance: L{qa_config._QaInstance}
+ @type pnode: L{qa_config._QaNode}
+
+ @rtype: string
+
+ """
+ instance_info = GetInstanceInfo(instance.name)
+
+ # We are interested in only the first disk on the primary
+ drbd_minor = instance_info["drbd-minors"][pnode.primary][0]
+
+ # This form should work for all DRBD versions
+ drbd_command = ("drbdsetup show %d; drbdsetup %d show || true" %
+ (drbd_minor, drbd_minor))
+ instance_drbd_info = \
+ qa_utils.GetCommandOutput(pnode.primary, drbd_command)
+
+ match_obj = _DRBD_SECRET_RE.search(instance_drbd_info)
+ if match_obj is None:
+ raise qa_error.Error("Could not retrieve DRBD secret for instance %s from"
+ " node %s." % (instance.name, pnode.primary))
+
+ return match_obj.groups(0)[0]
+
+
+ def TestInstanceDataCensorship(instance, inodes):
+ """Test protection of sensitive instance data."""
+
+ if instance.disk_template != constants.DT_DRBD8:
+ print qa_utils.FormatInfo("Only the DRBD secret is a sensitive parameter"
+ " right now, skipping for non-DRBD instance.")
+ return
+
+ drbd_secret = _RetrieveSecret(instance, inodes[0])
+
+ job_id = _rapi_client.GetInstanceInfo(instance.name)
+ if not _rapi_client.WaitForJobCompletion(job_id):
+ raise qa_error.Error("Could not fetch instance info for instance %s" %
+ instance.name)
+ info_dict = _rapi_client.GetJobStatus(job_id)
+
+ if drbd_secret in str(info_dict):
+ print qa_utils.FormatInfo("DRBD secret: %s" % drbd_secret)
+ print qa_utils.FormatInfo("Retrieved data\n%s" % str(info_dict))
+ raise qa_error.Error("Found DRBD secret in contents of RAPI instance info"
+ " call; see above.")