This patch adds '--remove-os-parameters' and
'--remove-os-parameters-private' options to 'gnt-instance reinstall'.
Similarly to 'gnt-instance modify', the new options can be used to
perform reinstalls to OS providers that support different parameters.
E.g.:

$ gnt-instance reinstall --remove-os-parameters param1,param2 \
  -o <new_os_provider> -O param3=val3 <instance_name>

or

$ gnt-instance reinstall --remove-os-parameters param1,param2 \
  -o <new_os_provider> -O param3=val3 <instance_name>

Signed-off-by: Yiannis Tsiouris <ts...@grnet.gr>
---
 lib/client/gnt_instance.py       | 17 +++++++++++++++--
 lib/cmdlib/instance_operation.py | 10 ++++++++++
 lib/rapi/rlib2.py                |  9 ++++++++-
 man/gnt-instance.rst             |  9 ++++++++-
 src/Ganeti/HTools/Repair.hs      |  4 ++++
 src/Ganeti/OpCodes.hs            |  2 ++
 src/Ganeti/OpParams.hs           | 12 ++++++++++++
 test/hs/Test/Ganeti/OpCodes.hs   |  2 ++
 8 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py
index 17ac709..6fb21fd 100644
--- a/lib/client/gnt_instance.py
+++ b/lib/client/gnt_instance.py
@@ -398,7 +398,17 @@ def ReinstallInstance(opts, args):
       if not AskUser(usertext):
         return 1
 
+  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 []
 
   jex = JobExecutor(verbose=multi_on, opts=opts)
   for instance_name in inames:
@@ -409,7 +419,9 @@ def ReinstallInstance(opts, args):
                                      osparams_private=opts.osparams_private,
                                      osparams_secret=opts.osparams_secret,
                                      clear_osparams=opts.clear_osparams,
-                                     
clear_osparams_private=clear_osparams_priv),
+                                     
clear_osparams_private=clear_osparams_priv,
+                                     remove_osparams=remove_osparams,
+                                     remove_osparams_private=remove_osps_priv)
     jex.QueueJob(instance_name, op)
 
   results = jex.WaitOrShow(not opts.submit_only)
@@ -1662,7 +1674,8 @@ commands = {
      m_pri_node_tags_opt, m_sec_node_tags_opt, m_inst_tags_opt, SELECT_OS_OPT]
     + SUBMIT_OPTS + [DRY_RUN_OPT, PRIORITY_OPT, OSPARAMS_OPT,
                      OSPARAMS_PRIVATE_OPT, OSPARAMS_SECRET_OPT,
-                     CLEAR_OSPARAMS_OPT, CLEAR_OSPARAMS_PRIVATE_OPT],
+                     CLEAR_OSPARAMS_OPT, CLEAR_OSPARAMS_PRIVATE_OPT,
+                     REMOVE_OSPARAMS_OPT, REMOVE_OSPARAMS_PRIVATE_OPT],
     "[-f] <instance>", "Reinstall a stopped instance"),
   "remove": (
     RemoveInstance, ARGS_ONE_INSTANCE,
diff --git a/lib/cmdlib/instance_operation.py b/lib/cmdlib/instance_operation.py
index e784a1a..ef56545 100644
--- a/lib/cmdlib/instance_operation.py
+++ b/lib/cmdlib/instance_operation.py
@@ -370,6 +370,8 @@ class LUInstanceReinstall(LogicalUnit):
     self.op.osparams = self.op.osparams or {}
     self.op.osparams_private = self.op.osparams_private or {}
     self.op.osparams_secret = self.op.osparams_secret or {}
+    self.op.remove_osparams = self.op.remove_osparams or []
+    self.op.remove_osparams_private = self.op.remove_osparams_private or []
 
     # Handle the use of 'default' values.
     if self.op.clear_osparams:
@@ -383,6 +385,14 @@ class LUInstanceReinstall(LogicalUnit):
                                         self.op.osparams_private)
     params_secret = self.op.osparams_secret
 
+    for osp in self.op.remove_osparams:
+      if osp in params_public:
+        del params_public[osp]
+
+    for osp in self.op.remove_osparams_private:
+      if osp in params_private:
+        del params_private[osp]
+
     # Handle OS parameters
     if self.op.os_type is not None:
       instance_os = self.op.os_type
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index 92156d1..4f76d44 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -1307,13 +1307,20 @@ def _ParseInstanceReinstallRequest(name, data):
   clear_osparams_private = baserlib.CheckParameter(data,
                                                    "clear_osparams_private",
                                                    default=False)
+  remove_osparams = baserlib.CheckParameter(data, "remove_osparams",
+                                            default=None)
+  remove_osparams_priv = baserlib.CheckParameter(data,
+                                                 "remove_osparams_private",
+                                                 default=None)
 
   ops = [
     opcodes.OpInstanceShutdown(instance_name=name),
     opcodes.OpInstanceReinstall(instance_name=name, os_type=ostype,
                                 osparams=osparams,
                                 clear_osparams=clear_osparams,
-                                clear_osparams_private=clear_osparams_private),
+                                clear_osparams_private=clear_osparams_private,
+                                remove_osparams=remove_osparams,
+                                remove_osparams_private=remove_osparams_priv),
     ]
 
   if start:
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index b40ed17..fced3f4 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -1528,6 +1528,8 @@ REINSTALL
 | [--os-parameters-secret} *OS\_PARAMETERS*]
 | [--clear-os-parameters]
 | [--clear-os-parameters-private]
+| [--remove-os-parameters *param*[,*param*...]]
+| [--remove-os-parameters-private *param*[,*param*...]]
 | [\--submit] [\--print-jobid]
 | {*instance*...}
 
@@ -1544,7 +1546,12 @@ available OS templates. OS parameters can be overridden 
using ``-O
 The ``--clear-os-parameters`` option will clear all (public) OS
 parameters before executing the reinstall and
 ``--clear-os-parameters-private`` will clear all private OS parameters
-of the instance.
+of the instance. Similarly, the
+``--remove-os-parameters``/``--remove-os-parameters-private`` option
+will clear only the specified public/private parameters and will pass
+the rest to the 'create' command provided by the appropriate OS
+interface (see **ganeti-os-interface**\(7) man page for more
+information).
 
 Since this is a potentially dangerous command, the user will be
 required to confirm this action, unless the ``-f`` flag is passed.
diff --git a/src/Ganeti/HTools/Repair.hs b/src/Ganeti/HTools/Repair.hs
index 9d07d70..3e10cb9 100644
--- a/src/Ganeti/HTools/Repair.hs
+++ b/src/Ganeti/HTools/Repair.hs
@@ -244,6 +244,8 @@ detectBroken nl inst =
                                  , opOsparamsSecret = Nothing
                                  , opClearOsparams = False
                                  , opClearOsparamsPrivate = False
+                                 , opRemoveOsparams = Nothing
+                                 , opRemoveOsparamsPrivate = Nothing
                                  , opForceVariant = False
                                  }
            ])
@@ -300,6 +302,8 @@ detectBroken nl inst =
                                  , opOsparamsSecret = Nothing
                                  , opClearOsparams = False
                                  , opClearOsparamsPrivate = False
+                                 , opRemoveOsparams = Nothing
+                                 , opRemoveOsparamsPrivate = Nothing
                                  , opForceVariant = False
                                  }
            ])
diff --git a/src/Ganeti/OpCodes.hs b/src/Ganeti/OpCodes.hs
index e5012fe..baf200c 100644
--- a/src/Ganeti/OpCodes.hs
+++ b/src/Ganeti/OpCodes.hs
@@ -536,6 +536,8 @@ $(genOpCode "OpCode"
      , pTempOsParamsSecret
      , pTempOsParamsClear
      , pTempOsParamsPrivateClear
+     , pTempOsParamsRemove
+     , pTempOsParamsPrivateRemove
      ],
      "instance_name")
   , ("OpInstanceRemove",
diff --git a/src/Ganeti/OpParams.hs b/src/Ganeti/OpParams.hs
index 7bd893c..c536e47 100644
--- a/src/Ganeti/OpParams.hs
+++ b/src/Ganeti/OpParams.hs
@@ -219,6 +219,8 @@ module Ganeti.OpParams
   , pTempOsParamsSecret
   , pTempOsParamsClear
   , pTempOsParamsPrivateClear
+  , pTempOsParamsRemove
+  , pTempOsParamsPrivateRemove
   , pTempHvParams
   , pTempBeParams
   , pIgnoreFailures
@@ -1404,6 +1406,16 @@ pTempOsParamsPrivateClear =
   withDoc "Clear current OS private parameters before instance reinstalls" $
   defaultFalse "clear_osparams_private"
 
+pTempOsParamsRemove :: Field
+pTempOsParamsRemove =
+  withDoc "Remove OS parameters before instance reinstalls" .
+  optionalField $ simpleField "remove_osparams" [t| [String] |]
+
+pTempOsParamsPrivateRemove :: Field
+pTempOsParamsPrivateRemove =
+  withDoc "Remove private OS parameters before instance reinstalls" .
+  optionalField $ simpleField "remove_osparams_private" [t| [String] |]
+
 pShutdownTimeout :: Field
 pShutdownTimeout =
   withDoc "How long to wait for instance to shut down" .
diff --git a/test/hs/Test/Ganeti/OpCodes.hs b/test/hs/Test/Ganeti/OpCodes.hs
index b82229f..c990e7b 100644
--- a/test/hs/Test/Ganeti/OpCodes.hs
+++ b/test/hs/Test/Ganeti/OpCodes.hs
@@ -366,6 +366,8 @@ genOpCodeFromId op_id =
         arbitrary <*> genMaybe genNameNE <*> genMaybe (pure emptyJSObject)
         <*> genMaybe arbitraryPrivateJSObj <*> genMaybe arbitrarySecretJSObj
         <*> arbitrary <*> arbitrary
+        <*> genMaybe (listOf genPrintableAsciiString)
+        <*> genMaybe (listOf genPrintableAsciiString)
     "OP_INSTANCE_REMOVE" ->
       OpCodes.OpInstanceRemove <$> genFQDN <*> return Nothing <*>
         arbitrary <*> arbitrary
-- 
2.10.2

Reply via email to