This patch extends 'gnt-instance modify' by allowing a user to remove a list of public/private OS parameters from an instance. This can be useful before performing a reinstall to a new OS provider. Example usage:
$ gnt-instance modify --remove-os-parameters parm1,parm2 <instance_name> or $ gnt-instance modify --remove-os-parameters-private parm3 <instance_name> Signed-off-by: Yiannis Tsiouris <[email protected]> --- lib/cli_opts.py | 17 +++++++++++++++++ lib/client/gnt_instance.py | 16 +++++++++++++++- lib/cmdlib/instance_set_params.py | 28 +++++++++++++++++++++++++--- man/gnt-instance.rst | 7 ++++++- src/Ganeti/OpCodes.hs | 2 ++ src/Ganeti/OpParams.hs | 12 ++++++++++++ test/hs/Test/Ganeti/OpCodes.hs | 2 ++ 7 files changed, 79 insertions(+), 5 deletions(-) diff --git a/lib/cli_opts.py b/lib/cli_opts.py index 3faf2bf..1624910 100644 --- a/lib/cli_opts.py +++ b/lib/cli_opts.py @@ -221,6 +221,8 @@ __all__ = [ "REASON_OPT", "REBOOT_TYPE_OPT", "REMOVE_INSTANCE_OPT", + "REMOVE_OSPARAMS_OPT", + "REMOVE_OSPARAMS_PRIVATE_OPT", "REMOVE_RESERVED_IPS_OPT", "REMOVE_UIDS_OPT", "RESERVED_LVS_OPT", @@ -744,6 +746,21 @@ CLEAR_OSPARAMS_PRIVATE_OPT = cli_option("--clear-os-parameters-private", help="Clear current private OS" " parameters") +REMOVE_OSPARAMS_OPT = cli_option("--remove-os-parameters", + dest="remove_osparams", + type="list", + default=None, + help="Comma-separated list of OS parameters" + " that should be removed") + +REMOVE_OSPARAMS_PRIVATE_OPT = cli_option("--remove-os-parameters-private", + dest="remove_osparams_private", + type="list", + default=None, + help="Comma-separated list of private" + " OS parameters that should be" + " removed") + FORCE_VARIANT_OPT = cli_option("--force-variant", dest="force_variant", action="store_true", default=False, help="Force an unknown variant") diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index f6effd0..bc4482b 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -1372,6 +1372,7 @@ 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 or opts.osparams_private or opts.clear_osparams or opts.clear_osparams_private + or opts.remove_osparams or opts.remove_osparams_private or opts.offline_inst or opts.online_inst or opts.runtime_mem or opts.new_primary_node or opts.instance_communication is not None): ToStderr("Please give at least one of the parameters.") @@ -1436,7 +1437,17 @@ def SetInstanceParams(opts, args): instance_comm = opts.instance_communication + if opts.clear_osparams and opts.remove_osparams is not None: + raise errors.OpPrereqError("Using --remove-os-parameters with " + "--clear-os-parameters is not possible", errors.ECODE_INVAL) + + if opts.clear_osparams_private and opts.remove_osparams_private is not None: + raise errors.OpPrereqError("Using --remove-os-parameters-private with " + "--clear-os-parameters-private is not possible", errors.ECODE_INVAL) + clear_osparams_priv = opts.clear_osparams_private + remove_osparams = opts.remove_osparams or [] + remove_osps_priv = opts.remove_osparams_private or [] op = opcodes.OpInstanceSetParams(instance_name=args[0], nics=nics, @@ -1458,6 +1469,8 @@ def SetInstanceParams(opts, args): osparams_private=opts.osparams_private, clear_osparams=opts.clear_osparams, clear_osparams_private=clear_osparams_priv, + remove_osparams=remove_osparams, + remove_osparams_private=remove_osps_priv, force_variant=opts.force_variant, force=opts.force, wait_for_sync=opts.wait_for_sync, @@ -1674,7 +1687,8 @@ commands = { NOCONFLICTSCHECK_OPT, NEW_PRIMARY_OPT, HOTPLUG_OPT, HOTPLUG_IF_POSSIBLE_OPT, INSTANCE_COMMUNICATION_OPT, EXT_PARAMS_OPT, FILESTORE_DRIVER_OPT, FILESTORE_DIR_OPT, - CLEAR_OSPARAMS_OPT, CLEAR_OSPARAMS_PRIVATE_OPT], + CLEAR_OSPARAMS_OPT, CLEAR_OSPARAMS_PRIVATE_OPT, + REMOVE_OSPARAMS_OPT, REMOVE_OSPARAMS_PRIVATE_OPT], "<instance>", "Alters the parameters of an instance"), "shutdown": ( GenericManyOps("shutdown", _ShutdownInstance), [ArgInstance()], diff --git a/lib/cmdlib/instance_set_params.py b/lib/cmdlib/instance_set_params.py index b4553c8..6b9a2ba 100644 --- a/lib/cmdlib/instance_set_params.py +++ b/lib/cmdlib/instance_set_params.py @@ -338,6 +338,7 @@ class LUInstanceSetParams(LogicalUnit): self.op.osparams or self.op.offline is not None or self.op.runtime_mem or self.op.pnode or self.op.osparams_private or self.op.clear_osparams or self.op.clear_osparams_private or + self.op.remove_osparams or self.op.remove_osparams_private or self.op.instance_communication is not None): raise errors.OpPrereqError("No changes submitted", errors.ECODE_INVAL) @@ -993,9 +994,12 @@ class LUInstanceSetParams(LogicalUnit): else self.instance.os) if (self.op.osparams or self.op.osparams_private or - self.op.clear_osparams or self.op.clear_osparams_private): + self.op.clear_osparams or self.op.clear_osparams_private or + self.op.remove_osparams or self.op.remove_osparams_private): public_parms = self.op.osparams or {} private_parms = self.op.osparams_private or {} + remove_osparams = self.op.remove_osparams or [] + remove_osparams_private = self.op.remove_osparams_private or [] self.os_inst_removed = self.os_inst_private_removed = [] dupe_keys = utils.GetRepeatedKeys(public_parms, private_parms) @@ -1011,6 +1015,24 @@ class LUInstanceSetParams(LogicalUnit): self.os_inst_private_removed = self.instance.osparams_private self.instance.osparams_private = {} + for osp in remove_osparams: + if osp in public_parms: + raise errors.OpPrereqError("Requested both removal and addition of " + "param %s" % osp) + + if osp in self.instance.osparams: + self.os_inst_removed.append(osp) + del self.instance.osparams[osp] + + for osp in remove_osparams_private: + if osp in private_parms: + raise errors.OpPrereqError("Requested both removal and addition of " + "param %s" % osp) + + if osp in self.instance.osparams_private: + self.os_inst_private_removed.append(osp) + del self.instance.osparams_private[osp] + self.os_inst = GetUpdatedParams(self.instance.osparams, public_parms) self.os_inst_private = GetUpdatedParams(self.instance.osparams_private, @@ -1966,12 +1988,12 @@ class LUInstanceSetParams(LogicalUnit): self.instance.os = self.op.os_name # osparams changes - if self.op.clear_osparams: + if self.op.clear_osparams or self.op.remove_osparams: self.instance.osparams = self.os_inst for osp in self.os_inst_removed: result.append(("os/%s" % osp, "<removed>")) - if self.op.clear_osparams_private: + if self.op.clear_osparams_private or self.op.remove_osparams_private: self.instance.osparams_private = self.os_inst_private for osp in self.os_inst_private_removed: result.append(("os_private/%s" % osp, "<removed>")) diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst index 8408a8f..f1e2640 100644 --- a/man/gnt-instance.rst +++ b/man/gnt-instance.rst @@ -1380,6 +1380,8 @@ MODIFY | [--os-parameters-private *param*=*value*... ] | [--clear-os-parameters] | [--clear-os-parameters-private] +| [--remove-os-parameters *param*[,*param*...]] +| [--remove-os-parameters-private *param*[,*param*...]] | [\--offline \| \--online] | [\--submit] [\--print-jobid] | [\--ignore-ipolicy] @@ -1399,7 +1401,10 @@ which options can be specified, see the **add** command. The ``--clear-os-parameters`` option will clear all current (public) instance OS parameters and the ``--clear-os-parameters-private`` will -clear all current private OS parameters. +clear all current private OS parameters. Similarly, the +``--remove-os-parameters`` option will clear only the specified +parameters and the ``--remove-os-parameters-private`` will clear only +the specified private OS parameters. The ``-t (--disk-template)`` option will change the disk template of the instance. Currently, conversions between all the available diff --git a/src/Ganeti/OpCodes.hs b/src/Ganeti/OpCodes.hs index c26a085..d792190 100644 --- a/src/Ganeti/OpCodes.hs +++ b/src/Ganeti/OpCodes.hs @@ -722,6 +722,8 @@ $(genOpCode "OpCode" , pInstOsParamsPrivate , pInstOsParamsClear , pInstOsParamsPrivateClear + , pInstOsParamsRemove + , pInstOsParamsPrivateRemove , pWaitForSync , withDoc "Whether to mark the instance as offline" pOffline , pIpConflictsCheck diff --git a/src/Ganeti/OpParams.hs b/src/Ganeti/OpParams.hs index 2b4b70f..fc0cef5 100644 --- a/src/Ganeti/OpParams.hs +++ b/src/Ganeti/OpParams.hs @@ -141,6 +141,8 @@ module Ganeti.OpParams , pInstOsParamsSecret , pInstOsParamsClear , pInstOsParamsPrivateClear + , pInstOsParamsRemove + , pInstOsParamsPrivateRemove , pCandidatePoolSize , pMaxRunningJobs , pMaxTrackedJobs @@ -1260,6 +1262,16 @@ pInstOsParamsPrivateClear = withDoc "Clear current private OS parameters from instance" $ defaultFalse "clear_osparams_private" +pInstOsParamsRemove :: Field +pInstOsParamsRemove = + withDoc "Remove OS parameters from instance" . + optionalField $ simpleField "remove_osparams" [t| [String] |] + +pInstOsParamsPrivateRemove :: Field +pInstOsParamsPrivateRemove = + withDoc "Remove private OS parameters from instance" . + optionalField $ simpleField "remove_osparams_private" [t| [String] |] + pPrimaryNode :: Field pPrimaryNode = withDoc "Primary node for an instance" $ diff --git a/test/hs/Test/Ganeti/OpCodes.hs b/test/hs/Test/Ganeti/OpCodes.hs index 96402c5..2d7078c 100644 --- a/test/hs/Test/Ganeti/OpCodes.hs +++ b/test/hs/Test/Ganeti/OpCodes.hs @@ -433,6 +433,8 @@ genOpCodeFromId op_id = <*> genMaybe arbitraryPrivateJSObj -- osparams_private <*> arbitrary -- clear_osparams <*> arbitrary -- clear_osparams_private + <*> genMaybe (listOf genPrintableAsciiString) -- remove_osparams + <*> genMaybe (listOf genPrintableAsciiString) -- remove_osparams_private <*> arbitrary -- wait_for_sync <*> arbitrary -- offline <*> arbitrary -- conflicts_check -- 2.10.2
