Revision 4a90bd4f
b/lib/backend.py | ||
---|---|---|
1451 | 1451 |
_RemoveBlockDevLinks(iname, instance.disks) |
1452 | 1452 |
|
1453 | 1453 |
|
1454 |
def InstanceReboot(instance, reboot_type, shutdown_timeout): |
|
1454 |
def InstanceReboot(instance, reboot_type, shutdown_timeout, reason):
|
|
1455 | 1455 |
"""Reboot an instance. |
1456 | 1456 |
|
1457 | 1457 |
@type instance: L{objects.Instance} |
... | ... | |
1481 | 1481 |
if reboot_type == constants.INSTANCE_REBOOT_SOFT: |
1482 | 1482 |
try: |
1483 | 1483 |
hyper.RebootInstance(instance) |
1484 |
reason.Store(instance.name) |
|
1484 | 1485 |
except errors.HypervisorError, err: |
1485 | 1486 |
_Fail("Failed to soft reboot instance %s: %s", instance.name, err) |
1486 | 1487 |
elif reboot_type == constants.INSTANCE_REBOOT_HARD: |
1487 | 1488 |
try: |
1488 | 1489 |
InstanceShutdown(instance, shutdown_timeout) |
1489 |
return StartInstance(instance, False) |
|
1490 |
result = StartInstance(instance, False) |
|
1491 |
reason.Store(instance.name) |
|
1492 |
return result |
|
1490 | 1493 |
except errors.HypervisorError, err: |
1491 | 1494 |
_Fail("Failed to hard reboot instance %s: %s", instance.name, err) |
1492 | 1495 |
else: |
b/lib/client/gnt_instance.py | ||
---|---|---|
1552 | 1552 |
[m_force_multi, REBOOT_TYPE_OPT, IGNORE_SECONDARIES_OPT, m_node_opt, |
1553 | 1553 |
m_pri_node_opt, m_sec_node_opt, m_clust_opt, m_inst_opt, SUBMIT_OPT, |
1554 | 1554 |
m_node_tags_opt, m_pri_node_tags_opt, m_sec_node_tags_opt, |
1555 |
m_inst_tags_opt, SHUTDOWN_TIMEOUT_OPT, DRY_RUN_OPT, PRIORITY_OPT], |
|
1555 |
m_inst_tags_opt, SHUTDOWN_TIMEOUT_OPT, DRY_RUN_OPT, PRIORITY_OPT, |
|
1556 |
REASON_OPT], |
|
1556 | 1557 |
"<instance>", "Reboots an instance"), |
1557 | 1558 |
"activate-disks": ( |
1558 | 1559 |
ActivateDisks, ARGS_ONE_INSTANCE, |
b/lib/cmdlib.py | ||
---|---|---|
7361 | 7361 |
instance = self.instance |
7362 | 7362 |
ignore_secondaries = self.op.ignore_secondaries |
7363 | 7363 |
reboot_type = self.op.reboot_type |
7364 |
reason = self.op.reason |
|
7364 | 7365 |
|
7365 | 7366 |
remote_info = self.rpc.call_instance_info(instance.primary_node, |
7366 | 7367 |
instance.name, |
... | ... | |
7376 | 7377 |
self.cfg.SetDiskID(disk, node_current) |
7377 | 7378 |
result = self.rpc.call_instance_reboot(node_current, instance, |
7378 | 7379 |
reboot_type, |
7379 |
self.op.shutdown_timeout) |
|
7380 |
self.op.shutdown_timeout, |
|
7381 |
reason) |
|
7380 | 7382 |
result.Raise("Could not reboot instance") |
7381 | 7383 |
else: |
7382 | 7384 |
if instance_running: |
b/lib/constants.py | ||
---|---|---|
2343 | 2343 |
INSTANCE_REASON_SOURCE_UNKNOWN, |
2344 | 2344 |
]) |
2345 | 2345 |
|
2346 |
# The default reasons for the change of state of an instance |
|
2347 |
INSTANCE_REASON_REBOOT = "reboot" |
|
2348 |
|
|
2346 | 2349 |
# Do not re-export imported modules |
2347 | 2350 |
del re, _vcsversion, _autoconf, socket, pathutils, compat |
b/lib/opcodes.py | ||
---|---|---|
1451 | 1451 |
"Whether to start the instance even if secondary disks are failing"), |
1452 | 1452 |
("reboot_type", ht.NoDefault, ht.TElemOf(constants.REBOOT_TYPES), |
1453 | 1453 |
"How to reboot instance"), |
1454 |
("reason", (constants.INSTANCE_REASON_SOURCE_UNKNOWN, None), |
|
1455 |
ht.TAnd(ht.TOr(ht.TList, ht.TTuple), |
|
1456 |
ht.TIsLength(2), |
|
1457 |
ht.TItems([ |
|
1458 |
ht.TElemOf(constants.INSTANCE_REASON_SOURCES), |
|
1459 |
ht.TMaybeString, |
|
1460 |
]) |
|
1461 |
), |
|
1462 |
"The reason why the reboot is happening"), |
|
1454 | 1463 |
] |
1455 | 1464 |
OP_RESULT = ht.TNone |
1456 | 1465 |
|
b/lib/rapi/client.py | ||
---|---|---|
1001 | 1001 |
(GANETI_RAPI_VERSION, instance)), query, None) |
1002 | 1002 |
|
1003 | 1003 |
def RebootInstance(self, instance, reboot_type=None, ignore_secondaries=None, |
1004 |
dry_run=False): |
|
1004 |
dry_run=False, reason_text=None):
|
|
1005 | 1005 |
"""Reboots an instance. |
1006 | 1006 |
|
1007 | 1007 |
@type instance: str |
1008 |
@param instance: instance to rebot |
|
1008 |
@param instance: instance to reboot
|
|
1009 | 1009 |
@type reboot_type: str |
1010 | 1010 |
@param reboot_type: one of: hard, soft, full |
1011 | 1011 |
@type ignore_secondaries: bool |
... | ... | |
1013 | 1013 |
while re-assembling disks (in hard-reboot mode only) |
1014 | 1014 |
@type dry_run: bool |
1015 | 1015 |
@param dry_run: whether to perform a dry run |
1016 |
@type reason_text: string |
|
1017 |
@param reason_text: the reason for the reboot |
|
1016 | 1018 |
@rtype: string |
1017 | 1019 |
@return: job id |
1018 | 1020 |
|
... | ... | |
1022 | 1024 |
_AppendIf(query, reboot_type, ("type", reboot_type)) |
1023 | 1025 |
_AppendIf(query, ignore_secondaries is not None, |
1024 | 1026 |
("ignore_secondaries", ignore_secondaries)) |
1027 |
_AppendIf(query, reason_text, ("reason_text", reason_text)) |
|
1025 | 1028 |
|
1026 | 1029 |
return self._SendRequest(HTTP_POST, |
1027 | 1030 |
("/%s/instances/%s/reboot" % |
b/lib/rapi/rlib2.py | ||
---|---|---|
1040 | 1040 |
self.queryargs.get("type", [constants.INSTANCE_REBOOT_HARD])[0], |
1041 | 1041 |
"ignore_secondaries": bool(self._checkIntVariable("ignore_secondaries")), |
1042 | 1042 |
"dry_run": self.dryRun(), |
1043 |
"reason": ( |
|
1044 |
constants.INSTANCE_REASON_SOURCE_RAPI, |
|
1045 |
self._checkStringVariable("reason_text", |
|
1046 |
default=constants.INSTANCE_REASON_REBOOT), |
|
1047 |
) |
|
1043 | 1048 |
}) |
1044 | 1049 |
|
1045 | 1050 |
|
b/lib/rpc_defs.py | ||
---|---|---|
230 | 230 |
("inst", ED_INST_DICT, "Instance object"), |
231 | 231 |
("reboot_type", None, None), |
232 | 232 |
("shutdown_timeout", None, None), |
233 |
("reason_text", None, "Reason for the reboot"), |
|
233 | 234 |
], None, None, "Returns the list of running instances on the given nodes"), |
234 | 235 |
("instance_shutdown", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
235 | 236 |
("instance", ED_INST_DICT, "Instance object"), |
b/lib/server/noded.py | ||
---|---|---|
112 | 112 |
return ieioargs |
113 | 113 |
|
114 | 114 |
|
115 |
def _DefaultAlternative(value, default): |
|
116 |
"""Returns the given value, unless it is None. In that case, returns a |
|
117 |
default alternative. |
|
118 |
|
|
119 |
@param value: The value to return if it is not None. |
|
120 |
@param default: The value to return as a default alternative. |
|
121 |
@return: The given value or the default alternative.\ |
|
122 |
|
|
123 |
""" |
|
124 |
if value: |
|
125 |
return value |
|
126 |
|
|
127 |
return default |
|
128 |
|
|
129 |
|
|
115 | 130 |
class MlockallRequestExecutor(http.server.HttpServerRequestExecutor): |
116 | 131 |
"""Subclass ensuring request handlers are locked in RAM. |
117 | 132 |
|
... | ... | |
633 | 648 |
instance = objects.Instance.FromDict(params[0]) |
634 | 649 |
reboot_type = params[1] |
635 | 650 |
shutdown_timeout = params[2] |
636 |
return backend.InstanceReboot(instance, reboot_type, shutdown_timeout) |
|
651 |
(reason_source, reason_text) = params[3] |
|
652 |
reason_text = _DefaultAlternative(reason_text, |
|
653 |
constants.INSTANCE_REASON_REBOOT) |
|
654 |
reason = backend.InstReason(reason_source, reason_text) |
|
655 |
return backend.InstanceReboot(instance, reboot_type, shutdown_timeout, |
|
656 |
reason) |
|
637 | 657 |
|
638 | 658 |
@staticmethod |
639 | 659 |
def perspective_instance_balloon_memory(params): |
b/src/Ganeti/OpCodes.hs | ||
---|---|---|
344 | 344 |
, pShutdownTimeout |
345 | 345 |
, pIgnoreSecondaries |
346 | 346 |
, pRebootType |
347 |
, pReason |
|
347 | 348 |
]) |
348 | 349 |
, ("OpInstanceMove", |
349 | 350 |
[ pInstanceName |
b/test/hs/Test/Ganeti/OpCodes.hs | ||
---|---|---|
241 | 241 |
arbitrary <*> arbitrary |
242 | 242 |
"OP_INSTANCE_REBOOT" -> |
243 | 243 |
OpCodes.OpInstanceReboot <$> genFQDN <*> arbitrary <*> |
244 |
arbitrary <*> arbitrary |
|
244 |
arbitrary <*> arbitrary <*> ((,) <$> arbitrary <*> genStringNE)
|
|
245 | 245 |
"OP_INSTANCE_MOVE" -> |
246 | 246 |
OpCodes.OpInstanceMove <$> genFQDN <*> arbitrary <*> arbitrary <*> |
247 | 247 |
genNodeNameNE <*> arbitrary |
... | ... | |
397 | 397 |
octets <- vectorOf 3 $ choose (0::Int, 255) |
398 | 398 |
mkNonEmpty . intercalate ":" $ map (printf "%02x") octets |
399 | 399 |
|
400 |
-- | Generate a non empty string |
|
401 |
genStringNE :: Gen NonEmptyString |
|
402 |
genStringNE = genName >>= mkNonEmpty |
|
403 |
|
|
400 | 404 |
-- | Arbitrary instance for MetaOpCode, defined here due to TH ordering. |
401 | 405 |
$(genArbitrary ''OpCodes.MetaOpCode) |
402 | 406 |
|
b/test/py/ganeti.rapi.client_unittest.py | ||
---|---|---|
594 | 594 |
def testRebootInstance(self): |
595 | 595 |
self.rapi.AddResponse("6146") |
596 | 596 |
job_id = self.client.RebootInstance("i-bar", reboot_type="hard", |
597 |
ignore_secondaries=True, dry_run=True, |
|
598 |
reason_text="Updates") |
|
599 |
self.assertEqual(6146, job_id) |
|
600 |
self.assertHandler(rlib2.R_2_instances_name_reboot) |
|
601 |
self.assertItems(["i-bar"]) |
|
602 |
self.assertDryRun() |
|
603 |
self.assertQuery("type", ["hard"]) |
|
604 |
self.assertQuery("ignore_secondaries", ["1"]) |
|
605 |
self.assertQuery("reason_text", ["Updates"]) |
|
606 |
|
|
607 |
def testRebootInstanceDefaultReason(self): |
|
608 |
self.rapi.AddResponse("6146") |
|
609 |
job_id = self.client.RebootInstance("i-bar", reboot_type="hard", |
|
597 | 610 |
ignore_secondaries=True, dry_run=True) |
598 | 611 |
self.assertEqual(6146, job_id) |
599 | 612 |
self.assertHandler(rlib2.R_2_instances_name_reboot) |
... | ... | |
601 | 614 |
self.assertDryRun() |
602 | 615 |
self.assertQuery("type", ["hard"]) |
603 | 616 |
self.assertQuery("ignore_secondaries", ["1"]) |
617 |
self.assertQuery("reason_text", None) |
|
604 | 618 |
|
605 | 619 |
def testShutdownInstance(self): |
606 | 620 |
self.rapi.AddResponse("1487") |
b/test/py/ganeti.rapi.rlib2_unittest.py | ||
---|---|---|
370 | 370 |
handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], { |
371 | 371 |
"dry-run": ["1"], |
372 | 372 |
"ignore_secondaries": ["1"], |
373 |
"reason_text": ["System update"] |
|
373 | 374 |
}, {}, clfactory) |
374 | 375 |
job_id = handler.POST() |
375 | 376 |
|
... | ... | |
383 | 384 |
self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD) |
384 | 385 |
self.assertTrue(op.ignore_secondaries) |
385 | 386 |
self.assertTrue(op.dry_run) |
387 |
self.assertEqual(op.reason, |
|
388 |
(constants.INSTANCE_REASON_SOURCE_RAPI, |
|
389 |
"System update", |
|
390 |
)) |
|
386 | 391 |
|
387 | 392 |
self.assertRaises(IndexError, cl.GetNextSubmittedJob) |
388 | 393 |
|
Also available in: Unified diff