Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
...@@ -82,7 +82,7 @@ class ResultWithJobs: ...@@ -82,7 +82,7 @@ class ResultWithJobs:
"""Data container for LU results with jobs. """Data container for LU results with jobs.
   
Instances of this class returned from L{LogicalUnit.Exec} will be recognized 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 contained in the C{jobs} attribute and include the job IDs in the opcode
result. result.
   
......
...@@ -31,6 +31,7 @@ are two kinds of classes defined: ...@@ -31,6 +31,7 @@ are two kinds of classes defined:
import logging import logging
import random import random
import time import time
import itertools
from ganeti import opcodes from ganeti import opcodes
from ganeti import constants from ganeti import constants
...@@ -171,6 +172,54 @@ def _ComputeDispatchTable(): ...@@ -171,6 +172,54 @@ def _ComputeDispatchTable():
if op.WITH_LU) 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): def _RpcResultsToHooksResults(rpc_results):
"""Function to convert RPC results to the format expected by HooksMaster. """Function to convert RPC results to the format expected by HooksMaster.
...@@ -230,26 +279,6 @@ class Processor(object): ...@@ -230,26 +279,6 @@ class Processor(object):
return acquired 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): def _ExecLU(self, lu):
"""Logical Unit execution sequence. """Logical Unit execution sequence.
...@@ -271,7 +300,8 @@ class Processor(object): ...@@ -271,7 +300,8 @@ class Processor(object):
return lu.dry_run_result return lu.dry_run_result
try: 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) h_results = hm.RunPhase(constants.HOOKS_PHASE_POST)
result = lu.HooksCallBack(constants.HOOKS_PHASE_POST, h_results, result = lu.HooksCallBack(constants.HOOKS_PHASE_POST, h_results,
self.Log, result) self.Log, result)
......
...@@ -23,9 +23,12 @@ ...@@ -23,9 +23,12 @@
import unittest import unittest
import itertools
from ganeti import mcpu from ganeti import mcpu
from ganeti import opcodes from ganeti import opcodes
from ganeti import cmdlib
from ganeti import constants
from ganeti.constants import \ from ganeti.constants import \
LOCK_ATTEMPTS_TIMEOUT, \ LOCK_ATTEMPTS_TIMEOUT, \
LOCK_ATTEMPTS_MAXWAIT, \ LOCK_ATTEMPTS_MAXWAIT, \
...@@ -96,5 +99,72 @@ class TestDispatchTable(unittest.TestCase): ...@@ -96,5 +99,72 @@ class TestDispatchTable(unittest.TestCase):
opcls.OP_ID)) 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__": if __name__ == "__main__":
testutils.GanetiTestProgram() testutils.GanetiTestProgram()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment