Commit 07923a3c authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Copy debug level, priority and set comment for LU-generated opcodes



Before this patch, a node evacuation submitted with high priority would
only compute the solution at that priority, but the actual evacuation
ran at normal priority.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 6d1e4845
......@@ -82,7 +82,7 @@ class ResultWithJobs:
"""Data container for LU results with jobs.
 
Instances of this class returned from L{LogicalUnit.Exec} will be recognized
by L{mcpu.Processor._ProcessResult}. The latter will then submit the jobs
by L{mcpu._ProcessResult}. The latter will then submit the jobs
contained in the C{jobs} attribute and include the job IDs in the opcode
result.
 
......
......@@ -31,6 +31,7 @@ are two kinds of classes defined:
import logging
import random
import time
import itertools
from ganeti import opcodes
from ganeti import constants
......@@ -171,6 +172,54 @@ def _ComputeDispatchTable():
if op.WITH_LU)
def _SetBaseOpParams(src, defcomment, dst):
"""Copies basic opcode parameters.
@type src: L{opcodes.OpCode}
@param src: Source opcode
@type defcomment: string
@param defcomment: Comment to specify if not already given
@type dst: L{opcodes.OpCode}
@param dst: Destination opcode
"""
if hasattr(src, "debug_level"):
dst.debug_level = src.debug_level
if (getattr(dst, "priority", None) is None and
hasattr(src, "priority")):
dst.priority = src.priority
if not getattr(dst, opcodes.COMMENT_ATTR, None):
dst.comment = defcomment
def _ProcessResult(submit_fn, op, result):
"""Examines opcode result.
If necessary, additional processing on the result is done.
"""
if isinstance(result, cmdlib.ResultWithJobs):
# Copy basic parameters (e.g. priority)
map(compat.partial(_SetBaseOpParams, op,
"Submitted by %s" % op.OP_ID),
itertools.chain(*result.jobs))
# Submit jobs
job_submission = submit_fn(result.jobs)
# Build dictionary
result = result.other
assert constants.JOB_IDS_KEY not in result, \
"Key '%s' found in additional return values" % constants.JOB_IDS_KEY
result[constants.JOB_IDS_KEY] = job_submission
return result
def _RpcResultsToHooksResults(rpc_results):
"""Function to convert RPC results to the format expected by HooksMaster.
......@@ -230,26 +279,6 @@ class Processor(object):
return acquired
def _ProcessResult(self, result):
"""Examines opcode result.
If necessary, additional processing on the result is done.
"""
if isinstance(result, cmdlib.ResultWithJobs):
# Submit jobs
job_submission = self._cbs.SubmitManyJobs(result.jobs)
# Build dictionary
result = result.other
assert constants.JOB_IDS_KEY not in result, \
"Key '%s' found in additional return values" % constants.JOB_IDS_KEY
result[constants.JOB_IDS_KEY] = job_submission
return result
def _ExecLU(self, lu):
"""Logical Unit execution sequence.
......@@ -271,7 +300,8 @@ class Processor(object):
return lu.dry_run_result
try:
result = self._ProcessResult(lu.Exec(self.Log))
result = _ProcessResult(self._cbs.SubmitManyJobs, lu.op,
lu.Exec(self.Log))
h_results = hm.RunPhase(constants.HOOKS_PHASE_POST)
result = lu.HooksCallBack(constants.HOOKS_PHASE_POST, h_results,
self.Log, result)
......
......@@ -23,9 +23,12 @@
import unittest
import itertools
from ganeti import mcpu
from ganeti import opcodes
from ganeti import cmdlib
from ganeti import constants
from ganeti.constants import \
LOCK_ATTEMPTS_TIMEOUT, \
LOCK_ATTEMPTS_MAXWAIT, \
......@@ -96,5 +99,72 @@ class TestDispatchTable(unittest.TestCase):
opcls.OP_ID))
class TestProcessResult(unittest.TestCase):
def setUp(self):
self._submitted = []
self._count = itertools.count(200)
def _Submit(self, jobs):
job_ids = [self._count.next() for _ in jobs]
self._submitted.extend(zip(job_ids, jobs))
return job_ids
def testNoJobs(self):
for i in [object(), [], False, True, None, 1, 929, {}]:
self.assertEqual(mcpu._ProcessResult(NotImplemented, NotImplemented, i),
i)
def testDefaults(self):
src = opcodes.OpTestDummy()
res = mcpu._ProcessResult(self._Submit, src, cmdlib.ResultWithJobs([[
opcodes.OpTestDelay(),
opcodes.OpTestDelay(),
], [
opcodes.OpTestDelay(),
]]))
self.assertEqual(res, {
constants.JOB_IDS_KEY: [200, 201],
})
(_, (op1, op2)) = self._submitted.pop(0)
(_, (op3, )) = self._submitted.pop(0)
self.assertRaises(IndexError, self._submitted.pop)
for op in [op1, op2, op3]:
self.assertTrue("OP_TEST_DUMMY" in op.comment)
self.assertFalse(hasattr(op, "priority"))
self.assertFalse(hasattr(op, "debug_level"))
def testParams(self):
src = opcodes.OpTestDummy(priority=constants.OP_PRIO_HIGH,
debug_level=3)
res = mcpu._ProcessResult(self._Submit, src, cmdlib.ResultWithJobs([[
opcodes.OpTestDelay(priority=constants.OP_PRIO_LOW),
], [
opcodes.OpTestDelay(comment="foobar", debug_level=10),
]], other=True, value=range(10)))
self.assertEqual(res, {
constants.JOB_IDS_KEY: [200, 201],
"other": True,
"value": range(10),
})
(_, (op1, )) = self._submitted.pop(0)
(_, (op2, )) = self._submitted.pop(0)
self.assertRaises(IndexError, self._submitted.pop)
self.assertEqual(op1.priority, constants.OP_PRIO_LOW)
self.assertTrue("OP_TEST_DUMMY" in op1.comment)
self.assertEqual(op1.debug_level, 3)
self.assertEqual(op2.priority, constants.OP_PRIO_HIGH)
self.assertEqual(op2.comment, "foobar")
self.assertEqual(op2.debug_level, 3)
if __name__ == "__main__":
testutils.GanetiTestProgram()
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