gnt-instance modify -m|--runtime-memory
authorGuido Trotter <ultrotter@google.com>
Tue, 17 Jan 2012 13:48:11 +0000 (13:48 +0000)
committerGuido Trotter <ultrotter@google.com>
Wed, 18 Jan 2012 16:03:32 +0000 (16:03 +0000)
Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

doc/hooks.rst
lib/cli.py
lib/client/gnt_instance.py
lib/cmdlib.py
lib/ht.py
lib/opcodes.py
man/gnt-instance.rst

index 72b7343..bac0649 100644 (file)
@@ -304,7 +304,7 @@ OP_INSTANCE_SET_PARAMS
 Modifies the instance parameters.
 
 :directory: instance-modify
-:env. vars: NEW_DISK_TEMPLATE
+:env. vars: NEW_DISK_TEMPLATE, RUNTIME_MEMORY
 :pre-execution: master node, primary and secondary nodes
 :post-execution: master node, primary and secondary nodes
 
index bc75823..282abad 100644 (file)
@@ -158,6 +158,7 @@ __all__ = [
   "REMOVE_INSTANCE_OPT",
   "REMOVE_UIDS_OPT",
   "RESERVED_LVS_OPT",
+  "RUNTIME_MEM_OPT",
   "ROMAN_OPT",
   "SECONDARY_IP_OPT",
   "SECONDARY_ONLY_OPT",
@@ -1361,6 +1362,10 @@ IGNORE_IPOLICY_OPT = cli_option("--ignore-ipolicy", dest="ignore_ipolicy",
                                 action="store_true", default=False,
                                 help="Ignore instance policy violations")
 
+RUNTIME_MEM_OPT = cli_option("-m", "--runtime-memory", dest="runtime_mem",
+                             help="Sets the instance's runtime memory,"
+                             " ballooning it up or down to the new value",
+                             default=None, type="unit", metavar="<size>")
 
 #: Options provided by all commands
 COMMON_OPTS = [DEBUG_OPT]
index 04df13c..19b10a0 100644 (file)
@@ -1264,7 +1264,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.offline_inst or opts.online_inst):
+          opts.offline_inst or opts.online_inst or opts.runtime_mem):
     ToStderr("Please give at least one of the parameters.")
     return 1
 
@@ -1317,6 +1317,7 @@ def SetInstanceParams(opts, args):
                                    remote_node=opts.node,
                                    hvparams=opts.hvparams,
                                    beparams=opts.beparams,
+                                   runtime_mem=opts.runtime_mem,
                                    os_name=opts.os,
                                    osparams=opts.osparams,
                                    force_variant=opts.force_variant,
@@ -1510,7 +1511,7 @@ commands = {
     [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, OFFLINE_INST_OPT,
-     ONLINE_INST_OPT, IGNORE_IPOLICY_OPT],
+     ONLINE_INST_OPT, IGNORE_IPOLICY_OPT, RUNTIME_MEM_OPT],
     "<instance>", "Alters the parameters of an instance"),
   "shutdown": (
     GenericManyOps("shutdown", _ShutdownInstance), [ArgInstance()],
index 1ca9b3d..1aaf3d6 100644 (file)
@@ -11587,7 +11587,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 or
-            self.op.online_inst or self.op.offline_inst):
+            self.op.online_inst or self.op.offline_inst or
+            self.op.runtime_mem):
       raise errors.OpPrereqError("No changes submitted", errors.ECODE_INVAL)
 
     if self.op.hvparams:
@@ -11771,6 +11772,8 @@ class LUInstanceSetParams(LogicalUnit):
     env = _BuildInstanceHookEnvByObject(self, self.instance, override=args)
     if self.op.disk_template:
       env["NEW_DISK_TEMPLATE"] = self.op.disk_template
+    if self.op.runtime_mem:
+      env["RUNTIME_MEMORY"] = self.op.runtime_mem
 
     return env
 
@@ -11975,6 +11978,33 @@ class LUInstanceSetParams(LogicalUnit):
                                        " %s, due to not enough memory" % node,
                                        errors.ECODE_STATE)
 
+    if self.op.runtime_mem:
+      remote_info = self.rpc.call_instance_info(instance.primary_node,
+                                                instance.name,
+                                                instance.hypervisor)
+      remote_info.Raise("Error checking node %s" % instance.primary_node)
+      if not remote_info.payload: # not running already
+        raise errors.OpPrereqError("Instance %s is not running" % instance.name,
+                                   errors.ECODE_STATE)
+
+      current_memory = remote_info.payload["memory"]
+      if (not self.op.force and
+           (self.op.runtime_mem > self.be_proposed[constants.BE_MAXMEM] or
+            self.op.runtime_mem < self.be_proposed[constants.BE_MINMEM])):
+        raise errors.OpPrereqError("Instance %s must have memory between %d"
+                                   " and %d MB of memory unless --force is"
+                                   " given" % (instance.name,
+                                    self.be_proposed[constants.BE_MINMEM],
+                                    self.be_proposed[constants.BE_MAXMEM]),
+                                   errors.ECODE_INVAL)
+
+      if self.op.runtime_mem > current_memory:
+        _CheckNodeFreeMemory(self, instance.primary_node,
+                             "ballooning memory for instance %s" %
+                             instance.name,
+                             self.op.memory - current_memory,
+                             instance.hypervisor)
+
     # NIC processing
     self.nic_pnew = {}
     self.nic_pinst = {}
@@ -12218,6 +12248,15 @@ class LUInstanceSetParams(LogicalUnit):
 
     result = []
     instance = self.instance
+
+    # runtime memory
+    if self.op.runtime_mem:
+      rpcres = self.rpc.call_instance_balloon_memory(instance.primary_node,
+                                                     instance,
+                                                     self.op.runtime_mem)
+      rpcres.Raise("Cannot modify instance runtime memory")
+      result.append(("runtime_memory", self.op.runtime_mem))
+
     # disk changes
     for disk_op, disk_dict in self.op.disks:
       if disk_op == constants.DDM_REMOVE:
index 4a511dc..c28ff1a 100644 (file)
--- a/lib/ht.py
+++ b/lib/ht.py
@@ -322,10 +322,16 @@ TMaybeDict = TOr(TDict, TNone)
 TPositiveInt = \
   TAnd(TInt, WithDesc("EqualGreaterZero")(lambda v: v >= 0))
 
+#: a maybe positive integer (positive integer or None)
+TMaybePositiveInt = TOr(TPositiveInt, TNone)
+
 #: a strictly positive integer
 TStrictPositiveInt = \
   TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0))
 
+#: a maybe strictly positive integer (strictly positive integer or None)
+TMaybeStrictPositiveInt = TOr(TStrictPositiveInt, TNone)
+
 #: a strictly negative integer (0 > value)
 TStrictNegativeInt = \
   TAnd(TInt, WithDesc("LessThanZero")(compat.partial(operator.gt, 0)))
index ea3acdc..31f6180 100644 (file)
@@ -1372,6 +1372,7 @@ class OpInstanceSetParams(OpCode):
      (constants.DDM_ADD, constants.DDM_REMOVE)),
     ("disks", ht.EmptyList, ht.TList, "List of disk changes. See ``nics``."),
     ("beparams", ht.EmptyDict, ht.TDict, "Per-instance backend parameters"),
+    ("runtime_mem", None, ht.TMaybeStrictPositiveInt, "New runtime memory"),
     ("hvparams", ht.EmptyDict, ht.TDict,
      "Per-instance hypervisor parameters, hypervisor-dependent"),
     ("disk_template", None, ht.TOr(ht.TNone, _BuildDiskTemplateCheck(False)),
index 39b15f6..88e66ab 100644 (file)
@@ -857,6 +857,7 @@ MODIFY
 | **modify**
 | [{-H|--hypervisor-parameters} *HYPERVISOR\_PARAMETERS*]
 | [{-B|--backend-parameters} *BACKEND\_PARAMETERS*]
+| [{-m|--runtime-memory} *SIZE*]
 | [--net add*[:options]* \| --net remove \| --net *N:options*]
 | [--disk add:size=*SIZE*[,vg=*VG*][,metavg=*VG*] \| --disk remove \|
 |  --disk *N*:mode=*MODE*]
@@ -887,6 +888,10 @@ option. The option ``--no-wait-for-sync`` can be used when converting
 to the ``drbd`` template in order to make the instance available for
 startup before DRBD has finished resyncing.
 
+The ``-m (--runtime-memory)`` option will change an instance's runtime
+memory to the given size (in MB if a different suffix is not specified),
+by ballooning it up or down to the new value.
+
 The ``--disk add:size=``*SIZE* option adds a disk to the instance. The
 optional ``vg=``*VG* option specifies LVM volume group other than
 default vg to create the disk on. For DRBD disks, the ``metavg=``*VG*