From 12e62af51fb3f2e807a8865410f993b98f54165f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ren=C3=A9=20Nussbaumer?= Date: Thu, 13 Sep 2012 13:18:57 +0200 Subject: [PATCH] Adding the new opcode for multi-allocation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Skeleton for the multi-allocation opcode Signed-off-by: René Nussbaumer Reviewed-by: Michael Hanselmann --- lib/opcodes.py | 49 +++++++++++++++++++++++++++++++++++++++ test/ganeti.opcodes_unittest.py | 16 ++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/opcodes.py b/lib/opcodes.py index e4ad078..4c427d5 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -1208,6 +1208,55 @@ class OpInstanceCreate(OpCode): OP_RESULT = ht.Comment("instance nodes")(ht.TListOf(ht.TNonEmptyString)) +class OpInstanceMultiAlloc(OpCode): + """Allocates multiple instances. + + """ + OP_PARAMS = [ + ("iallocator", None, ht.TMaybeString, + "Iallocator used to allocate all the instances"), + ("instances", [], ht.TListOf(ht.TInstanceOf(OpInstanceCreate)), + "List of instance create opcodes describing the instances to allocate"), + ] + _JOB_LIST = ht.Comment("List of submitted jobs")(TJobIdList) + ALLOCATABLE_KEY = "allocatable" + FAILED_KEY = "allocatable" + OP_RESULT = ht.TStrictDict(True, True, { + constants.JOB_IDS_KEY: _JOB_LIST, + ALLOCATABLE_KEY: ht.TListOf(ht.TNonEmptyString), + FAILED_KEY: ht.TListOf(ht.TNonEmptyString) + }) + + def __getstate__(self): + """Generic serializer. + + """ + state = OpCode.__getstate__(self) + if hasattr(self, "instances"): + # pylint: disable=E1101 + state["instances"] = [inst.__getstate__() for inst in self.instances] + return state + + def __setstate__(self, state): + """Generic unserializer. + + This method just restores from the serialized state the attributes + of the current instance. + + @param state: the serialized opcode data + @type state: C{dict} + + """ + if not isinstance(state, dict): + raise ValueError("Invalid data to __setstate__: expected dict, got %s" % + type(state)) + + if "instances" in state: + insts = [OpCode.LoadOpCode(inst) for inst in state["instances"]] + state["instances"] = insts + return OpCode.__setstate__(self, state) + + class OpInstanceReinstall(OpCode): """Reinstall an instance's OS.""" OP_DSC_FIELD = "instance_name" diff --git a/test/ganeti.opcodes_unittest.py b/test/ganeti.opcodes_unittest.py index 9de861c..ebfeb08 100755 --- a/test/ganeti.opcodes_unittest.py +++ b/test/ganeti.opcodes_unittest.py @@ -77,7 +77,7 @@ class TestOpcodes(unittest.TestCase): {"dry_run": False, "debug_level": 0, }, # All variables - dict([(name, False) for name in cls.GetAllSlots()]) + dict([(name, []) for name in cls.GetAllSlots()]) ] for i in args: @@ -290,6 +290,20 @@ class TestOpcodes(unittest.TestCase): self.assertEqual(op.debug_level, 123) + def testOpInstanceMultiAlloc(self): + inst = dict([(name, []) for name in opcodes.OpInstanceCreate.GetAllSlots()]) + inst_op = opcodes.OpInstanceCreate(**inst) + inst_state = inst_op.__getstate__() + + multialloc = opcodes.OpInstanceMultiAlloc(instances=[inst_op]) + state = multialloc.__getstate__() + self.assertEquals(state["instances"], [inst_state]) + loaded_multialloc = opcodes.OpCode.LoadOpCode(state) + (loaded_inst,) = loaded_multialloc.instances + self.assertNotEquals(loaded_inst, inst_op) + self.assertEquals(loaded_inst.__getstate__(), inst_state) + + class TestOpcodeDepends(unittest.TestCase): def test(self): check_relative = opcodes._BuildJobDepCheck(True) -- 1.7.10.4