diff --git a/lib/cli.py b/lib/cli.py index 584f4e96b3295059675bfd03c6bf3969292622fc..5d6656739d87e03331b191965fccd62d8ffe13ff 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -137,6 +137,8 @@ __all__ = [ "NOVOTING_OPT", "NO_REMEMBER_OPT", "NWSYNC_OPT", + "OFFLINE_INST_OPT", + "ONLINE_INST_OPT", "ON_PRIMARY_OPT", "ON_SECONDARY_OPT", "OFFLINE_OPT", @@ -685,6 +687,14 @@ NWSYNC_OPT = cli_option("--no-wait-for-sync", dest="wait_for_sync", default=True, action="store_false", help="Don't wait for sync (DANGEROUS!)") +ONLINE_INST_OPT = cli_option("--online", dest="online_inst", + action="store_true", default=False, + help="Enable offline instance") + +OFFLINE_INST_OPT = cli_option("--offline", dest="offline_inst", + action="store_true", default=False, + help="Disable down instance") + DISK_TEMPLATE_OPT = cli_option("-t", "--disk-template", dest="disk_template", help=("Custom disk setup (%s)" % utils.CommaJoin(constants.DISK_TEMPLATES)), diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index 8ba787dd470c595d0f2380fb34b284cb16fff953..4cc8628726f8df2bad7b218eecfd0614afb60151 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -1248,7 +1248,8 @@ def SetInstanceParams(opts, args): """ if not (opts.nics or opts.disks or opts.disk_template or - opts.hvparams or opts.beparams or opts.os or opts.osparams): + opts.hvparams or opts.beparams or opts.os or opts.osparams or + opts.offline_inst or opts.online_inst): ToStderr("Please give at least one of the parameters.") return 1 @@ -1305,7 +1306,9 @@ def SetInstanceParams(opts, args): osparams=opts.osparams, force_variant=opts.force_variant, force=opts.force, - wait_for_sync=opts.wait_for_sync) + wait_for_sync=opts.wait_for_sync, + offline_inst=opts.offline_inst, + online_inst=opts.online_inst) # even if here we process the result, we allow submit only result = SubmitOrSend(op, opts) @@ -1487,7 +1490,8 @@ commands = { SetInstanceParams, ARGS_ONE_INSTANCE, [BACKEND_OPT, DISK_OPT, FORCE_OPT, HVOPTS_OPT, NET_OPT, SUBMIT_OPT, DISK_TEMPLATE_OPT, SINGLE_NODE_OPT, OS_OPT, FORCE_VARIANT_OPT, - OSPARAMS_OPT, DRY_RUN_OPT, PRIORITY_OPT, NWSYNC_OPT], + OSPARAMS_OPT, DRY_RUN_OPT, PRIORITY_OPT, NWSYNC_OPT, OFFLINE_INST_OPT, + ONLINE_INST_OPT], "<instance>", "Alters the parameters of an instance"), "shutdown": ( GenericManyOps("shutdown", _ShutdownInstance), [ArgInstance()], diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 1765754adfedcb6d1505d4ba3aac718b584db1af..57883c19bec93aeec6fa7b8571a95d80d2b80507 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -10982,7 +10982,8 @@ class LUInstanceSetParams(LogicalUnit): def CheckArguments(self): if not (self.op.nics or self.op.disks or self.op.disk_template or - self.op.hvparams or self.op.beparams or self.op.os_name): + self.op.hvparams or self.op.beparams or self.op.os_name or + self.op.online_inst or self.op.offline_inst): raise errors.OpPrereqError("No changes submitted", errors.ECODE_INVAL) if self.op.hvparams: @@ -11449,6 +11450,16 @@ class LUInstanceSetParams(LogicalUnit): (disk_op, len(instance.disks)), errors.ECODE_INVAL) + # disabling the instance + if self.op.offline_inst: + _CheckInstanceState(self, instance, INSTANCE_DOWN, + msg="cannot change instance state to offline") + + # enabling the instance + if self.op.online_inst: + _CheckInstanceState(self, instance, INSTANCE_OFFLINE, + msg="cannot make instance go online") + def _ConvertPlainToDrbd(self, feedback_fn): """Converts an instance from plain to drbd. @@ -11709,6 +11720,14 @@ class LUInstanceSetParams(LogicalUnit): for key, val in self.op.osparams.iteritems(): result.append(("os/%s" % key, val)) + # online/offline instance + if self.op.online_inst: + self.cfg.MarkInstanceDown(instance.name) + result.append(("admin_state", constants.ADMINST_DOWN)) + if self.op.offline_inst: + self.cfg.MarkInstanceOffline(instance.name) + result.append(("admin_state", constants.ADMINST_OFFLINE)) + self.cfg.Update(instance, feedback_fn) assert not (self.owned_locks(locking.LEVEL_NODE_RES) or diff --git a/lib/config.py b/lib/config.py index 28bb33f724837b7ffb679387c2c2d157b3e51dd5..53ff25755658ced2d2a5b33290fd7a4a5bad60b6 100644 --- a/lib/config.py +++ b/lib/config.py @@ -1193,7 +1193,14 @@ class ConfigWriter: """Mark the instance status to up in the config. """ - self._SetInstanceStatus(instance_name, True) + self._SetInstanceStatus(instance_name, constants.ADMINST_UP) + + @locking.ssynchronized(_config_lock) + def MarkInstanceOffline(self, instance_name): + """Mark the instance status to down in the config. + + """ + self._SetInstanceStatus(instance_name, constants.ADMINST_OFFLINE) @locking.ssynchronized(_config_lock) def RemoveInstance(self, instance_name): diff --git a/lib/opcodes.py b/lib/opcodes.py index 076d57830c6d093f668f7ac9160f868cab70cc17..986fb74a18596a4dae6ff1df4729ac5104699c28 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -1351,6 +1351,10 @@ class OpInstanceSetParams(OpCode): ("osparams", None, ht.TMaybeDict, "Per-instance OS parameters"), ("wait_for_sync", True, ht.TBool, "Whether to wait for the disk to synchronize, when changing template"), + ("offline_inst", False, ht.TBool, + "Whether to turn off the down instance completely"), + ("online_inst", False, ht.TBool, + "Whether to enable the offline instance"), ] OP_RESULT = _TSetParamsResult