Revision 819ca990

b/lib/locking.py
1283 1283
#   the same time.
1284 1284
LEVEL_CLUSTER = 0
1285 1285
LEVEL_INSTANCE = 1
1286
LEVEL_NODE = 2
1286
LEVEL_NODEGROUP = 2
1287
LEVEL_NODE = 3
1287 1288

  
1288 1289
LEVELS = [LEVEL_CLUSTER,
1289 1290
          LEVEL_INSTANCE,
1291
          LEVEL_NODEGROUP,
1290 1292
          LEVEL_NODE]
1291 1293

  
1292 1294
# Lock levels which are modifiable
1293
LEVELS_MOD = [LEVEL_NODE, LEVEL_INSTANCE]
1295
LEVELS_MOD = [LEVEL_NODE, LEVEL_NODEGROUP, LEVEL_INSTANCE]
1294 1296

  
1295 1297
LEVEL_NAMES = {
1296 1298
  LEVEL_CLUSTER: "cluster",
1297 1299
  LEVEL_INSTANCE: "instance",
1300
  LEVEL_NODEGROUP: "nodegroup",
1298 1301
  LEVEL_NODE: "node",
1299 1302
  }
1300 1303

  
......
1313 1316
  """
1314 1317
  _instance = None
1315 1318

  
1316
  def __init__(self, nodes, instances):
1319
  def __init__(self, nodes, nodegroups, instances):
1317 1320
    """Constructs a new GanetiLockManager object.
1318 1321

  
1319 1322
    There should be only a GanetiLockManager object at any time, so this
1320 1323
    function raises an error if this is not the case.
1321 1324

  
1322 1325
    @param nodes: list of node names
1326
    @param nodegroups: list of nodegroup uuids
1323 1327
    @param instances: list of instance names
1324 1328

  
1325 1329
    """
......
1335 1339
    self.__keyring = {
1336 1340
      LEVEL_CLUSTER: LockSet([BGL], "BGL", monitor=self._monitor),
1337 1341
      LEVEL_NODE: LockSet(nodes, "nodes", monitor=self._monitor),
1342
      LEVEL_NODEGROUP: LockSet(nodegroups, "nodegroups", monitor=self._monitor),
1338 1343
      LEVEL_INSTANCE: LockSet(instances, "instances",
1339 1344
                              monitor=self._monitor),
1340 1345
      }
b/lib/server/masterd.py
359 359
    # Locking manager
360 360
    self.glm = locking.GanetiLockManager(
361 361
                self.cfg.GetNodeList(),
362
                self.cfg.GetNodeGroupList(),
362 363
                self.cfg.GetInstanceList())
363 364

  
364 365
    # Job queue
b/test/ganeti.locking_unittest.py
1418 1418
  def setUp(self):
1419 1419
    _ThreadedTestCase.setUp(self)
1420 1420
    self.nodes=['n1', 'n2']
1421
    self.nodegroups=['g1', 'g2']
1421 1422
    self.instances=['i1', 'i2', 'i3']
1422
    self.GL = locking.GanetiLockManager(self.nodes, self.instances)
1423
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups,
1424
                                        self.instances)
1423 1425

  
1424 1426
  def tearDown(self):
1425 1427
    # Don't try this at home...
......
1434 1436
      self.assertEqual(i, locking.LEVELS[i])
1435 1437

  
1436 1438
  def testDoubleGLFails(self):
1437
    self.assertRaises(AssertionError, locking.GanetiLockManager, [], [])
1439
    self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [])
1438 1440

  
1439 1441
  def testLockNames(self):
1440 1442
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1441 1443
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1444
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1445
                     set(self.nodegroups))
1442 1446
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1443 1447
                     set(self.instances))
1444 1448

  
1445 1449
  def testInitAndResources(self):
1446 1450
    locking.GanetiLockManager._instance = None
1447
    self.GL = locking.GanetiLockManager([], [])
1451
    self.GL = locking.GanetiLockManager([], [], [])
1448 1452
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1449 1453
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1454
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1450 1455
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1451 1456

  
1452 1457
    locking.GanetiLockManager._instance = None
1453
    self.GL = locking.GanetiLockManager(self.nodes, [])
1458
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [])
1454 1459
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1455 1460
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1461
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1462
                                    set(self.nodegroups))
1456 1463
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1457 1464

  
1458 1465
    locking.GanetiLockManager._instance = None
1459
    self.GL = locking.GanetiLockManager([], self.instances)
1466
    self.GL = locking.GanetiLockManager([], [], self.instances)
1460 1467
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1461 1468
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1469
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1462 1470
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1463 1471
                     set(self.instances))
1464 1472

  
......
1466 1474
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1467 1475
    self.assertEquals(self.GL._list_owned(locking.LEVEL_CLUSTER), set(['BGL']))
1468 1476
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i1'])
1477
    self.GL.acquire(locking.LEVEL_NODEGROUP, ['g2'])
1469 1478
    self.GL.acquire(locking.LEVEL_NODE, ['n1', 'n2'], shared=1)
1470 1479
    self.GL.release(locking.LEVEL_NODE, ['n2'])
1471 1480
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set(['n1']))
1481
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
1472 1482
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1473 1483
    self.GL.release(locking.LEVEL_NODE)
1474 1484
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set())
1485
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
1475 1486
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1487
    self.GL.release(locking.LEVEL_NODEGROUP)
1476 1488
    self.GL.release(locking.LEVEL_INSTANCE)
1477 1489
    self.assertRaises(errors.LockError, self.GL.acquire,
1478 1490
                      locking.LEVEL_INSTANCE, ['i5'])
......
1485 1497
                      set(self.instances))
1486 1498
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
1487 1499
                      set(self.instances))
1500
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODEGROUP, None),
1501
                      set(self.nodegroups))
1502
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP),
1503
                      set(self.nodegroups))
1488 1504
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
1489 1505
                      set(self.nodes))
1490 1506
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
1491 1507
                      set(self.nodes))
1492 1508
    self.GL.release(locking.LEVEL_NODE)
1509
    self.GL.release(locking.LEVEL_NODEGROUP)
1493 1510
    self.GL.release(locking.LEVEL_INSTANCE)
1494 1511
    self.GL.release(locking.LEVEL_CLUSTER)
1495 1512

  
......
1512 1529
                      locking.LEVEL_NODE, ['n1', 'n2'])
1513 1530
    self.assertRaises(AssertionError, self.GL.acquire,
1514 1531
                      locking.LEVEL_INSTANCE, ['i3'])
1532
    self.assertRaises(AssertionError, self.GL.acquire,
1533
                      locking.LEVEL_NODEGROUP, ['g1'])
1515 1534
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1516 1535
    self.GL.acquire(locking.LEVEL_NODE, ['n1'])
1517 1536
    self.assertRaises(AssertionError, self.GL.release,
......
1525 1544
    self.assertRaises(AssertionError, self.GL.release,
1526 1545
                      locking.LEVEL_CLUSTER)
1527 1546
    self.GL.release(locking.LEVEL_INSTANCE)
1547
    self.GL.acquire(locking.LEVEL_NODEGROUP, None)
1548
    self.GL.release(locking.LEVEL_NODEGROUP, ['g1'])
1549
    self.assertRaises(AssertionError, self.GL.release,
1550
                      locking.LEVEL_CLUSTER, ['BGL'])
1551
    self.assertRaises(AssertionError, self.GL.release,
1552
                      locking.LEVEL_CLUSTER)
1553
    self.GL.release(locking.LEVEL_NODEGROUP)
1554
    self.GL.release(locking.LEVEL_CLUSTER)
1528 1555

  
1529 1556
  def testWrongOrder(self):
1530 1557
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
......
1532 1559
    self.assertRaises(AssertionError, self.GL.acquire,
1533 1560
                      locking.LEVEL_NODE, ['n1'])
1534 1561
    self.assertRaises(AssertionError, self.GL.acquire,
1562
                      locking.LEVEL_NODEGROUP, ['g1'])
1563
    self.assertRaises(AssertionError, self.GL.acquire,
1535 1564
                      locking.LEVEL_INSTANCE, ['i2'])
1536 1565

  
1537 1566
  def testModifiableLevels(self):
......
1545 1574
    self.GL.add(locking.LEVEL_NODE, ['n3'])
1546 1575
    self.GL.remove(locking.LEVEL_NODE, ['n1'])
1547 1576
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(['n2', 'n3']))
1577
    self.GL.add(locking.LEVEL_NODEGROUP, ['g3'])
1578
    self.GL.remove(locking.LEVEL_NODEGROUP, ['g2'])
1579
    self.GL.remove(locking.LEVEL_NODEGROUP, ['g1'])
1580
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set(['g3']))
1548 1581
    self.assertRaises(AssertionError, self.GL.remove, locking.LEVEL_CLUSTER,
1549 1582
                      ['BGL2'])
1550 1583

  

Also available in: Unified diff