X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/a365b47f0c37967df687989c9c56ce496ce63183..1bb99a338f3cafc5cf77201f938421c89a72069f:/qa/qa_instance.py diff --git a/qa/qa_instance.py b/qa/qa_instance.py index 59a86e4..b88b4d6 100644 --- a/qa/qa_instance.py +++ b/qa/qa_instance.py @@ -23,7 +23,6 @@ """ -import operator import os import re @@ -36,146 +35,19 @@ import qa_config import qa_utils import qa_error -from qa_utils import AssertIn, AssertCommand, AssertEqual +from qa_utils import AssertCommand, AssertEqual from qa_utils import InstanceCheck, INST_DOWN, INST_UP, FIRST_ARG, RETURN_VALUE +from qa_instance_utils import CheckSsconfInstanceList, \ + CreateInstanceDrbd8, \ + CreateInstanceByDiskTemplate, \ + CreateInstanceByDiskTemplateOneNode, \ + GetGenericAddParameters def _GetDiskStatePath(disk): return "/sys/block/%s/device/state" % disk -def _GetGenericAddParameters(inst, disk_template, force_mac=None): - params = ["-B"] - params.append("%s=%s,%s=%s" % (constants.BE_MINMEM, - qa_config.get(constants.BE_MINMEM), - constants.BE_MAXMEM, - qa_config.get(constants.BE_MAXMEM))) - - if disk_template != constants.DT_DISKLESS: - for idx, disk in enumerate(qa_config.GetDiskOptions()): - size = disk.get("size") - name = disk.get("name") - diskparams = "%s:size=%s" % (idx, size) - if name: - diskparams += ",name=%s" % name - params.extend(["--disk", diskparams]) - - # Set static MAC address if configured - if force_mac: - nic0_mac = force_mac - else: - nic0_mac = inst.GetNicMacAddr(0, None) - - if nic0_mac: - params.extend(["--net", "0:mac=%s" % nic0_mac]) - - return params - - -def _CreateInstanceByDiskTemplateRaw(nodes_spec, disk_template, fail=False): - """Creates an instance with the given disk template on the given nodes(s). - Note that this function does not check if enough nodes are given for - the respective disk template. - - @type nodes_spec: string - @param nodes_spec: string specification of one node (by node name) or several - nodes according to the requirements of the disk template - @type disk_template: string - @param disk_template: the disk template to be used by the instance - @return: the created instance - - """ - instance = qa_config.AcquireInstance() - try: - cmd = (["gnt-instance", "add", - "--os-type=%s" % qa_config.get("os"), - "--disk-template=%s" % disk_template, - "--node=%s" % nodes_spec] + - _GetGenericAddParameters(instance, disk_template)) - cmd.append(instance.name) - - AssertCommand(cmd, fail=fail) - - if not fail: - _CheckSsconfInstanceList(instance.name) - instance.SetDiskTemplate(disk_template) - - return instance - except: - instance.Release() - raise - - # Handle the case where creation is expected to fail - assert fail - instance.Release() - return None - - -def _CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=False): - """Creates an instance using the given disk template for disk templates - for which one given node is sufficient. These templates are for example: - plain, diskless, file, sharedfile, blockdev, rados. - - @type nodes: list of nodes - @param nodes: a list of nodes, whose first element is used to create the - instance - @type disk_template: string - @param disk_template: the disk template to be used by the instance - @return: the created instance - - """ - assert len(nodes) > 0 - return _CreateInstanceByDiskTemplateRaw(nodes[0].primary, disk_template, - fail=fail) - - -def _CreateInstanceDrbd8(nodes, fail=False): - """Creates an instance using disk template 'drbd' on the given nodes. - - @type nodes: list of nodes - @param nodes: nodes to be used by the instance - @return: the created instance - - """ - assert len(nodes) > 1 - return _CreateInstanceByDiskTemplateRaw( - ":".join(map(operator.attrgetter("primary"), nodes)), - constants.DT_DRBD8, fail=fail) - - -def CreateInstanceByDiskTemplate(nodes, disk_template, fail=False): - """Given a disk template, this function creates an instance using - the template. It uses the required number of nodes depending on - the disk template. This function is intended to be used by tests - that don't care about the specifics of the instance other than - that it uses the given disk template. - - Note: If you use this function, make sure to call - 'TestInstanceRemove' at the end of your tests to avoid orphaned - instances hanging around and interfering with the following tests. - - @type nodes: list of nodes - @param nodes: the list of the nodes on which the instance will be placed; - it needs to have sufficiently many elements for the given - disk template - @type disk_template: string - @param disk_template: the disk template to be used by the instance - @return: the created instance - - """ - if disk_template == constants.DT_DRBD8: - return _CreateInstanceDrbd8(nodes, fail=fail) - elif disk_template in [constants.DT_DISKLESS, constants.DT_PLAIN, - constants.DT_FILE]: - return _CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=fail) - else: - # FIXME: This assumes that for all other disk templates, we only need one - # node and no disk template specific parameters. This else-branch is - # currently only used in cases where we expect failure. Extend it when - # QA needs for these templates change. - return _CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=fail) - - def _GetInstanceInfo(instance): """Return information about the actual state of an instance. @@ -382,7 +254,7 @@ def IsDiskSupported(instance): def TestInstanceAddWithPlainDisk(nodes, fail=False): """gnt-instance add -t plain""" if constants.DT_PLAIN in qa_config.GetEnabledDiskTemplates(): - instance = _CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_PLAIN, + instance = CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_PLAIN, fail=fail) if not fail: qa_utils.RunInstanceCheck(instance, True) @@ -393,7 +265,7 @@ def TestInstanceAddWithPlainDisk(nodes, fail=False): def TestInstanceAddWithDrbdDisk(nodes): """gnt-instance add -t drbd""" if constants.DT_DRBD8 in qa_config.GetEnabledDiskTemplates(): - return _CreateInstanceDrbd8(nodes) + return CreateInstanceDrbd8(nodes) @InstanceCheck(None, INST_UP, RETURN_VALUE) @@ -401,7 +273,7 @@ def TestInstanceAddFile(nodes): """gnt-instance add -t file""" assert len(nodes) == 1 if constants.DT_FILE in qa_config.GetEnabledDiskTemplates(): - return _CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_FILE) + return CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_FILE) @InstanceCheck(None, INST_UP, RETURN_VALUE) @@ -409,7 +281,7 @@ def TestInstanceAddDiskless(nodes): """gnt-instance add -t diskless""" assert len(nodes) == 1 if constants.DT_FILE in qa_config.GetEnabledDiskTemplates(): - return _CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_DISKLESS) + return CreateInstanceByDiskTemplateOneNode(nodes, constants.DT_DISKLESS) @InstanceCheck(None, INST_DOWN, FIRST_ARG) @@ -466,32 +338,6 @@ def TestInstanceReinstall(instance): fail=True) -def _ReadSsconfInstanceList(): - """Reads ssconf_instance_list from the master node. - - """ - master = qa_config.GetMasterNode() - - ssconf_path = utils.PathJoin(pathutils.DATA_DIR, - "ssconf_%s" % constants.SS_INSTANCE_LIST) - - cmd = ["cat", qa_utils.MakeNodePath(master, ssconf_path)] - - return qa_utils.GetCommandOutput(master.primary, - utils.ShellQuoteArgs(cmd)).splitlines() - - -def _CheckSsconfInstanceList(instance): - """Checks if a certain instance is in the ssconf instance list. - - @type instance: string - @param instance: Instance name - - """ - AssertIn(qa_utils.ResolveInstanceName(instance), - _ReadSsconfInstanceList()) - - @InstanceCheck(INST_DOWN, INST_DOWN, FIRST_ARG) def TestInstanceRenameAndBack(rename_source, rename_target): """gnt-instance rename @@ -500,14 +346,14 @@ def TestInstanceRenameAndBack(rename_source, rename_target): name. """ - _CheckSsconfInstanceList(rename_source) + CheckSsconfInstanceList(rename_source) # first do a rename to a different actual name, expecting it to fail qa_utils.AddToEtcHosts(["meeeeh-not-exists", rename_target]) try: AssertCommand(["gnt-instance", "rename", rename_source, rename_target], fail=True) - _CheckSsconfInstanceList(rename_source) + CheckSsconfInstanceList(rename_source) finally: qa_utils.RemoveFromEtcHosts(["meeeeh-not-exists", rename_target]) @@ -530,7 +376,7 @@ def TestInstanceRenameAndBack(rename_source, rename_target): # and now rename instance to rename_target... AssertCommand(["gnt-instance", "rename", rename_source, rename_target]) - _CheckSsconfInstanceList(rename_target) + CheckSsconfInstanceList(rename_target) qa_utils.RunInstanceCheck(rename_source, False) qa_utils.RunInstanceCheck(rename_target, False) @@ -544,7 +390,7 @@ def TestInstanceRenameAndBack(rename_source, rename_target): # and back AssertCommand(["gnt-instance", "rename", rename_target, rename_source]) - _CheckSsconfInstanceList(rename_source) + CheckSsconfInstanceList(rename_source) qa_utils.RunInstanceCheck(rename_target, False) if (rename_source != rename_target and @@ -1036,7 +882,7 @@ def TestInstanceImport(newinst, node, expnode, name): "--src-node=%s" % expnode.primary, "--src-dir=%s/%s" % (pathutils.EXPORT_DIR, name), "--node=%s" % node.primary] + - _GetGenericAddParameters(newinst, templ, + GetGenericAddParameters(newinst, templ, force_mac=constants.VALUE_GENERATE)) cmd.append(newinst.name) AssertCommand(cmd) @@ -1077,7 +923,16 @@ def TestRemoveInstanceOfflineNode(instance, snode, set_offline, set_online): # FIXME: abstract the cleanup inside the disks if info["storage-type"] == constants.ST_LVM_VG: for minor in info["drbd-minors"][snode.primary]: - AssertCommand(["drbdsetup", str(minor), "down"], node=snode) + # DRBD 8.3 syntax comes first, then DRBD 8.4 syntax. The 8.4 syntax + # relies on the fact that we always create a resources for each minor, + # and that this resources is always named resource{minor}. + # As 'drbdsetup 0 down' does return success (even though that's invalid + # syntax), we always have to perform both commands and ignore the + # output. + drbd_shutdown_cmd = \ + "(drbdsetup %d down && drbdsetup down resource%d) || /bin/true" % \ + (minor, minor) + AssertCommand(drbd_shutdown_cmd, node=snode) AssertCommand(["lvremove", "-f"] + info["volumes"], node=snode) elif info["storage-type"] == constants.ST_FILE: filestorage = pathutils.DEFAULT_FILE_STORAGE_DIR