Verify disks should not run on clusters or nodegroups with only ext storage, as it requires an unnecessary amount of locks for its jobs. This commit performs additional checks when submitting a gnt-cluster verify-disks job or during a watcher run to prevent this.
Signed-off-by: Federico Morg Pareschi <[email protected]> --- lib/cmdlib/cluster/verify.py | 14 +++++++++++--- lib/watcher/__init__.py | 15 ++++++++++----- test/py/cmdlib/cluster_unittest.py | 23 +++++++++++++++++++++++ test/py/testutils/config_mock.py | 6 ++++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/lib/cmdlib/cluster/verify.py b/lib/cmdlib/cluster/verify.py index 868f7a6..4e6a031 100644 --- a/lib/cmdlib/cluster/verify.py +++ b/lib/cmdlib/cluster/verify.py @@ -239,10 +239,18 @@ class LUClusterVerifyDisks(NoHooksLU): def Exec(self, feedback_fn): group_names = self.owned_locks(locking.LEVEL_NODEGROUP) + instances = self.cfg.GetInstanceList() - # Submit one instance of L{opcodes.OpGroupVerifyDisks} per node group - return ResultWithJobs([[opcodes.OpGroupVerifyDisks(group_name=group)] - for group in group_names]) + only_ext = not [i for i in instances if + self.cfg.GetInstanceDiskTemplate(i) != constants.DT_EXT] + + if only_ext: + logging.info("All instances have ext storage, skipping verify disks.") + return ResultWithJobs([]) + else: + # Submit one instance of L{opcodes.OpGroupVerifyDisks} per node group + return ResultWithJobs([[opcodes.OpGroupVerifyDisks(group_name=group)] + for group in group_names]) class LUClusterVerifyConfig(NoHooksLU, _VerifyErrors): diff --git a/lib/watcher/__init__.py b/lib/watcher/__init__.py index 9c2a272..1cc17db 100644 --- a/lib/watcher/__init__.py +++ b/lib/watcher/__init__.py @@ -148,13 +148,14 @@ class Instance(object): """ def __init__(self, name, status, config_state, config_state_source, - disks_active, snodes): + disks_active, snodes, disk_template): self.name = name self.status = status self.config_state = config_state self.config_state_source = config_state_source self.disks_active = disks_active self.snodes = snodes + self.disk_template = disk_template def Restart(self, cl): """Encapsulates the start of an instance. @@ -753,7 +754,7 @@ def _GetGroupData(qcl, uuid): queries = [ (constants.QR_INSTANCE, ["name", "status", "admin_state", "admin_state_source", "disks_active", - "snodes", "pnode.group.uuid", "snodes.group.uuid"], + "snodes", "pnode.group.uuid", "snodes.group.uuid", "disk_template"], [qlang.OP_EQUAL, "pnode.group.uuid", uuid]), (constants.QR_NODE, ["name", "bootid", "offline"], @@ -779,14 +780,14 @@ def _GetGroupData(qcl, uuid): # Load all instances for (name, status, config_state, config_state_source, disks_active, snodes, - pnode_group_uuid, snodes_group_uuid) in raw_instances: + pnode_group_uuid, snodes_group_uuid, disk_template) in raw_instances: if snodes and set([pnode_group_uuid]) != set(snodes_group_uuid): logging.error("Ignoring split instance '%s', primary group %s, secondary" " groups %s", name, pnode_group_uuid, utils.CommaJoin(snodes_group_uuid)) else: instances.append(Instance(name, status, config_state, config_state_source, - disks_active, snodes)) + disks_active, snodes, disk_template)) for node in snodes: secondaries.setdefault(node, set()).add(name) @@ -865,7 +866,11 @@ def _GroupWatcher(opts): started = _CheckInstances(client, notepad, instances, locks) _CheckDisks(client, notepad, nodes, instances, started) - if not opts.no_verify_disks: + + # Check if the nodegroup only has ext storage type + only_ext = not [i for i in instances.values() + if i.disk_template != constants.DT_EXT] + if not opts.no_verify_disks and not only_ext: _VerifyDisks(client, group_uuid, nodes, instances) except Exception, err: logging.info("Not updating status file due to failure: %s", err) diff --git a/test/py/cmdlib/cluster_unittest.py b/test/py/cmdlib/cluster_unittest.py index 90099a0..d8f3185 100644 --- a/test/py/cmdlib/cluster_unittest.py +++ b/test/py/cmdlib/cluster_unittest.py @@ -2326,7 +2326,30 @@ class TestLUClusterVerifyGroupHooksCallBack(TestLUClusterVerifyGroupMethods): class TestLUClusterVerifyDisks(CmdlibTestCase): + def testVerifyDisks(self): + self.cfg.AddNewInstance(uuid="tst1.inst.corp.google.com", + disk_template=constants.DT_PLAIN) + op = opcodes.OpClusterVerifyDisks() + result = self.ExecOpCode(op) + + self.assertEqual(1, len(result["jobs"])) + + def testVerifyDisksExt(self): + self.cfg.AddNewInstance(uuid="tst1.inst.corp.google.com", + disk_template=constants.DT_EXT) + self.cfg.AddNewInstance(uuid="tst2.inst.corp.google.com", + disk_template=constants.DT_EXT) + op = opcodes.OpClusterVerifyDisks() + result = self.ExecOpCode(op) + + self.assertEqual(0, len(result["jobs"])) + + def testVerifyDisksMixed(self): + self.cfg.AddNewInstance(uuid="tst1.inst.corp.google.com", + disk_template=constants.DT_EXT) + self.cfg.AddNewInstance(uuid="tst2.inst.corp.google.com", + disk_template=constants.DT_PLAIN) op = opcodes.OpClusterVerifyDisks() result = self.ExecOpCode(op) diff --git a/test/py/testutils/config_mock.py b/test/py/testutils/config_mock.py index 7ae27bc..1d70798 100644 --- a/test/py/testutils/config_mock.py +++ b/test/py/testutils/config_mock.py @@ -274,6 +274,12 @@ class ConfigMock(config.ConfigWriter): if disks is None: if disk_template == constants.DT_DISKLESS: disks = [] + elif disk_template == constants.DT_EXT: + provider = "mock_provider" + disks = [self.CreateDisk(dev_type=disk_template, + primary_node=primary_node, + secondary_node=secondary_node, + params={constants.IDISK_PROVIDER: provider})] else: disks = [self.CreateDisk(dev_type=disk_template, primary_node=primary_node, -- 2.8.0.rc3.226.g39d4020
