Commit 1fa6fcba authored by Michele Tartara's avatar Michele Tartara

Reason trail implementation for "start"

Opcode-specific implementation of the reason trail for the instance
startup operation.
Signed-off-by: default avatarMichele Tartara <mtartara@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 1f350e0f
......@@ -1328,13 +1328,17 @@ def _GatherAndLinkBlockDevs(instance):
return block_devices
def StartInstance(instance, startup_paused):
def StartInstance(instance, startup_paused, reason, store_reason=True):
"""Start an instance.
@type instance: L{objects.Instance}
@param instance: the instance object
@type startup_paused: bool
@param instance: pause instance at startup?
@type reason: list of reasons
@param reason: the reason trail for this startup
@type store_reason: boolean
@param store_reason: whether to store the shutdown reason trail on file
@rtype: None
"""
......@@ -1348,6 +1352,8 @@ def StartInstance(instance, startup_paused):
block_devices = _GatherAndLinkBlockDevs(instance)
hyper = hypervisor.GetHypervisor(instance.hypervisor)
hyper.StartInstance(instance, block_devices, startup_paused)
if store_reason:
_StoreInstReasonTrail(instance.name, reason)
except errors.BlockDeviceError, err:
_Fail("Block device error: %s", err, exc=True)
except errors.HypervisorError, err:
......@@ -1467,7 +1473,7 @@ def InstanceReboot(instance, reboot_type, shutdown_timeout, reason):
elif reboot_type == constants.INSTANCE_REBOOT_HARD:
try:
InstanceShutdown(instance, shutdown_timeout, reason, store_reason=False)
result = StartInstance(instance, False)
result = StartInstance(instance, False, reason, store_reason=False)
_StoreInstReasonTrail(instance.name, reason)
return result
except errors.HypervisorError, err:
......
......@@ -7349,6 +7349,7 @@ class LUInstanceStartup(LogicalUnit):
"""
instance = self.instance
force = self.op.force
reason = self.op.reason
if not self.op.no_remember:
self.cfg.MarkInstanceUp(instance.name)
......@@ -7365,7 +7366,7 @@ class LUInstanceStartup(LogicalUnit):
self.rpc.call_instance_start(node_current,
(instance, self.op.hvparams,
self.op.beparams),
self.op.startup_paused)
self.op.startup_paused, reason)
msg = result.fail_msg
if msg:
_ShutdownInstanceDisks(self, instance)
......@@ -7458,7 +7459,8 @@ class LUInstanceReboot(LogicalUnit):
instance.name)
_StartInstanceDisks(self, instance, ignore_secondaries)
result = self.rpc.call_instance_start(node_current,
(instance, None, None), False)
(instance, None, None), False,
reason)
msg = result.fail_msg
if msg:
_ShutdownInstanceDisks(self, instance)
......@@ -8557,7 +8559,8 @@ class LUInstanceMove(LogicalUnit):
raise errors.OpExecError("Can't activate the instance's disks")
result = self.rpc.call_instance_start(target_node,
(instance, None, None), False)
(instance, None, None), False,
self.op.reason)
msg = result.fail_msg
if msg:
_ShutdownInstanceDisks(self, instance)
......@@ -9297,7 +9300,7 @@ class TLMigrateInstance(Tasklet):
self.feedback_fn("* starting the instance on the target node %s" %
target_node)
result = self.rpc.call_instance_start(target_node, (instance, None, None),
False)
False, self.lu.op.reason)
msg = result.fail_msg
if msg:
_ShutdownInstanceDisks(self.lu, instance)
......@@ -11229,7 +11232,7 @@ class LUInstanceCreate(LogicalUnit):
logging.info("Starting instance %s on node %s", instance, pnode_name)
feedback_fn("* starting instance...")
result = self.rpc.call_instance_start(pnode_name, (iobj, None, None),
False)
False, self.op.reason)
result.Raise("Could not start instance")
return list(iobj.all_nodes)
......@@ -14963,7 +14966,8 @@ class LUBackupExport(LogicalUnit):
assert not activate_disks
feedback_fn("Starting instance %s" % instance.name)
result = self.rpc.call_instance_start(src_node,
(instance, None, None), False)
(instance, None, None), False,
self.op.reason)
msg = result.fail_msg
if msg:
feedback_fn("Failed to start instance: %s" % msg)
......
......@@ -1057,7 +1057,8 @@ class GanetiRapiClient(object): # pylint: disable=R0904
("/%s/instances/%s/shutdown" %
(GANETI_RAPI_VERSION, instance)), query, body)
def StartupInstance(self, instance, dry_run=False, no_remember=False):
def StartupInstance(self, instance, dry_run=False, no_remember=False,
reason=None):
"""Starts up an instance.
@type instance: str
......@@ -1066,6 +1067,8 @@ class GanetiRapiClient(object): # pylint: disable=R0904
@param dry_run: whether to perform a dry run
@type no_remember: bool
@param no_remember: if true, will not record the state change
@type reason: string
@param reason: the reason for the startup
@rtype: string
@return: job id
......@@ -1073,6 +1076,7 @@ class GanetiRapiClient(object): # pylint: disable=R0904
query = []
_AppendDryRunIf(query, dry_run)
_AppendIf(query, no_remember, ("no_remember", 1))
_AppendIf(query, reason, ("reason", reason))
return self._SendRequest(HTTP_PUT,
("/%s/instances/%s/startup" %
......
......@@ -279,6 +279,7 @@ _INSTANCE_CALLS = [
("instance_start", SINGLE, None, constants.RPC_TMO_NORMAL, [
("instance_hvp_bep", ED_INST_DICT_HVP_BEP_DP, None),
("startup_paused", None, None),
("reason", None, "The reason for the startup"),
], None, None, "Starts an instance"),
("instance_os_add", SINGLE, None, constants.RPC_TMO_1DAY, [
("instance_osp", ED_INST_DICT_OSP_DP, None),
......
......@@ -598,9 +598,10 @@ class NodeRequestHandler(http.server.HttpServerHandler):
"""Start an instance.
"""
(instance_name, startup_paused) = params
(instance_name, startup_paused, trail) = params
instance = objects.Instance.FromDict(instance_name)
return backend.StartInstance(instance, startup_paused)
_extendReasonTrail(trail, "start")
return backend.StartInstance(instance, startup_paused, trail)
@staticmethod
def perspective_migration_info(params):
......
......@@ -636,12 +636,23 @@ class GanetiRapiClientTests(testutils.GanetiTestCase):
self.assertQuery("reason", None)
def testStartupInstance(self):
self.rapi.AddResponse("27149")
self.assertEqual(27149, self.client.StartupInstance("bar-instance",
dry_run=True,
reason="New"))
self.assertHandler(rlib2.R_2_instances_name_startup)
self.assertItems(["bar-instance"])
self.assertDryRun()
self.assertQuery("reason", ["New"])
def testStartupInstanceDefaultReason(self):
self.rapi.AddResponse("27149")
self.assertEqual(27149, self.client.StartupInstance("bar-instance",
dry_run=True))
self.assertHandler(rlib2.R_2_instances_name_startup)
self.assertItems(["bar-instance"])
self.assertDryRun()
self.assertQuery("reason", None)
def testReinstallInstance(self):
self.rapi.AddResponse(serializer.DumpJson([]))
......
......@@ -400,6 +400,7 @@ class TestInstanceStartup(unittest.TestCase):
handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
"force": ["1"],
"no_remember": ["1"],
"reason": ["Newly created instance"],
}, {}, clfactory)
job_id = handler.PUT()
......@@ -413,6 +414,12 @@ class TestInstanceStartup(unittest.TestCase):
self.assertTrue(op.no_remember)
self.assertTrue(op.force)
self.assertFalse(op.dry_run)
self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
self.assertEqual(op.reason[0][1], "Newly created instance")
self.assertEqual(op.reason[1][0],
"%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
"instances_name_startup"))
self.assertEqual(op.reason[1][1], "")
self.assertRaises(IndexError, cl.GetNextSubmittedJob)
......
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