Commit 819ca990 authored by Guido Trotter's avatar Guido Trotter
Browse files

locking: add nodegroup lock level



This also changes masterd to initialize the ganeti's manager with the
current list of nodegroup uuids, and updates unittests
Signed-off-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 1177d70e
......@@ -1283,18 +1283,21 @@ class LockSet:
# the same time.
LEVEL_CLUSTER = 0
LEVEL_INSTANCE = 1
LEVEL_NODE = 2
LEVEL_NODEGROUP = 2
LEVEL_NODE = 3
LEVELS = [LEVEL_CLUSTER,
LEVEL_INSTANCE,
LEVEL_NODEGROUP,
LEVEL_NODE]
# Lock levels which are modifiable
LEVELS_MOD = [LEVEL_NODE, LEVEL_INSTANCE]
LEVELS_MOD = [LEVEL_NODE, LEVEL_NODEGROUP, LEVEL_INSTANCE]
LEVEL_NAMES = {
LEVEL_CLUSTER: "cluster",
LEVEL_INSTANCE: "instance",
LEVEL_NODEGROUP: "nodegroup",
LEVEL_NODE: "node",
}
......@@ -1313,13 +1316,14 @@ class GanetiLockManager:
"""
_instance = None
def __init__(self, nodes, instances):
def __init__(self, nodes, nodegroups, instances):
"""Constructs a new GanetiLockManager object.
There should be only a GanetiLockManager object at any time, so this
function raises an error if this is not the case.
@param nodes: list of node names
@param nodegroups: list of nodegroup uuids
@param instances: list of instance names
"""
......@@ -1335,6 +1339,7 @@ class GanetiLockManager:
self.__keyring = {
LEVEL_CLUSTER: LockSet([BGL], "BGL", monitor=self._monitor),
LEVEL_NODE: LockSet(nodes, "nodes", monitor=self._monitor),
LEVEL_NODEGROUP: LockSet(nodegroups, "nodegroups", monitor=self._monitor),
LEVEL_INSTANCE: LockSet(instances, "instances",
monitor=self._monitor),
}
......
......@@ -359,6 +359,7 @@ class GanetiContext(object):
# Locking manager
self.glm = locking.GanetiLockManager(
self.cfg.GetNodeList(),
self.cfg.GetNodeGroupList(),
self.cfg.GetInstanceList())
# Job queue
......
......@@ -1418,8 +1418,10 @@ class TestGanetiLockManager(_ThreadedTestCase):
def setUp(self):
_ThreadedTestCase.setUp(self)
self.nodes=['n1', 'n2']
self.nodegroups=['g1', 'g2']
self.instances=['i1', 'i2', 'i3']
self.GL = locking.GanetiLockManager(self.nodes, self.instances)
self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups,
self.instances)
def tearDown(self):
# Don't try this at home...
......@@ -1434,31 +1436,37 @@ class TestGanetiLockManager(_ThreadedTestCase):
self.assertEqual(i, locking.LEVELS[i])
def testDoubleGLFails(self):
self.assertRaises(AssertionError, locking.GanetiLockManager, [], [])
self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [])
def testLockNames(self):
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
set(self.nodegroups))
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
set(self.instances))
def testInitAndResources(self):
locking.GanetiLockManager._instance = None
self.GL = locking.GanetiLockManager([], [])
self.GL = locking.GanetiLockManager([], [], [])
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
locking.GanetiLockManager._instance = None
self.GL = locking.GanetiLockManager(self.nodes, [])
self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [])
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
set(self.nodegroups))
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
locking.GanetiLockManager._instance = None
self.GL = locking.GanetiLockManager([], self.instances)
self.GL = locking.GanetiLockManager([], [], self.instances)
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
set(self.instances))
......@@ -1466,13 +1474,17 @@ class TestGanetiLockManager(_ThreadedTestCase):
self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
self.assertEquals(self.GL._list_owned(locking.LEVEL_CLUSTER), set(['BGL']))
self.GL.acquire(locking.LEVEL_INSTANCE, ['i1'])
self.GL.acquire(locking.LEVEL_NODEGROUP, ['g2'])
self.GL.acquire(locking.LEVEL_NODE, ['n1', 'n2'], shared=1)
self.GL.release(locking.LEVEL_NODE, ['n2'])
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set(['n1']))
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
self.GL.release(locking.LEVEL_NODE)
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set())
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
self.GL.release(locking.LEVEL_NODEGROUP)
self.GL.release(locking.LEVEL_INSTANCE)
self.assertRaises(errors.LockError, self.GL.acquire,
locking.LEVEL_INSTANCE, ['i5'])
......@@ -1485,11 +1497,16 @@ class TestGanetiLockManager(_ThreadedTestCase):
set(self.instances))
self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
set(self.instances))
self.assertEquals(self.GL.acquire(locking.LEVEL_NODEGROUP, None),
set(self.nodegroups))
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP),
set(self.nodegroups))
self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
set(self.nodes))
self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
set(self.nodes))
self.GL.release(locking.LEVEL_NODE)
self.GL.release(locking.LEVEL_NODEGROUP)
self.GL.release(locking.LEVEL_INSTANCE)
self.GL.release(locking.LEVEL_CLUSTER)
......@@ -1512,6 +1529,8 @@ class TestGanetiLockManager(_ThreadedTestCase):
locking.LEVEL_NODE, ['n1', 'n2'])
self.assertRaises(AssertionError, self.GL.acquire,
locking.LEVEL_INSTANCE, ['i3'])
self.assertRaises(AssertionError, self.GL.acquire,
locking.LEVEL_NODEGROUP, ['g1'])
self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
self.GL.acquire(locking.LEVEL_NODE, ['n1'])
self.assertRaises(AssertionError, self.GL.release,
......@@ -1525,12 +1544,22 @@ class TestGanetiLockManager(_ThreadedTestCase):
self.assertRaises(AssertionError, self.GL.release,
locking.LEVEL_CLUSTER)
self.GL.release(locking.LEVEL_INSTANCE)
self.GL.acquire(locking.LEVEL_NODEGROUP, None)
self.GL.release(locking.LEVEL_NODEGROUP, ['g1'])
self.assertRaises(AssertionError, self.GL.release,
locking.LEVEL_CLUSTER, ['BGL'])
self.assertRaises(AssertionError, self.GL.release,
locking.LEVEL_CLUSTER)
self.GL.release(locking.LEVEL_NODEGROUP)
self.GL.release(locking.LEVEL_CLUSTER)
def testWrongOrder(self):
self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
self.GL.acquire(locking.LEVEL_NODE, ['n2'])
self.assertRaises(AssertionError, self.GL.acquire,
locking.LEVEL_NODE, ['n1'])
self.assertRaises(AssertionError, self.GL.acquire,
locking.LEVEL_NODEGROUP, ['g1'])
self.assertRaises(AssertionError, self.GL.acquire,
locking.LEVEL_INSTANCE, ['i2'])
......@@ -1545,6 +1574,10 @@ class TestGanetiLockManager(_ThreadedTestCase):
self.GL.add(locking.LEVEL_NODE, ['n3'])
self.GL.remove(locking.LEVEL_NODE, ['n1'])
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(['n2', 'n3']))
self.GL.add(locking.LEVEL_NODEGROUP, ['g3'])
self.GL.remove(locking.LEVEL_NODEGROUP, ['g2'])
self.GL.remove(locking.LEVEL_NODEGROUP, ['g1'])
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set(['g3']))
self.assertRaises(AssertionError, self.GL.remove, locking.LEVEL_CLUSTER,
['BGL2'])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment