Merge branch 'stable-2.5' into stable-2.6
[ganeti-local] / tools / burnin
index 8ab7a15..fec9a04 100755 (executable)
@@ -91,12 +91,12 @@ def Err(msg, exit_code=1):
 
 class SimpleOpener(urllib.FancyURLopener):
   """A simple url opener"""
-  # pylint: disable-msg=W0221
+  # pylint: disable=W0221
 
   def prompt_user_passwd(self, host, realm, clear_cache=0):
     """No-interaction version of prompt_user_passwd."""
     # we follow parent class' API
-    # pylint: disable-msg=W0613
+    # pylint: disable=W0613
     return None, None
 
   def http_error_default(self, url, fp, errcode, errmsg, headers):
@@ -124,6 +124,14 @@ OPTIONS = [
   cli.cli_option("--disk-growth", dest="disk_growth", help="Disk growth",
                  default="128m", type="string", metavar="<size,size,...>"),
   cli.cli_option("--mem-size", dest="mem_size", help="Memory size",
+                 default=None, type="unit", metavar="<size>",
+                 completion_suggest=("128M 256M 512M 1G 4G 8G"
+                                     " 12G 16G").split()),
+  cli.cli_option("--maxmem-size", dest="maxmem_size", help="Max Memory size",
+                 default=256, type="unit", metavar="<size>",
+                 completion_suggest=("128M 256M 512M 1G 4G 8G"
+                                     " 12G 16G").split()),
+  cli.cli_option("--minmem-size", dest="minmem_size", help="Min Memory size",
                  default=128, type="unit", metavar="<size>",
                  completion_suggest=("128M 256M 512M 1G 4G 8G"
                                      " 12G 16G").split()),
@@ -178,7 +186,7 @@ OPTIONS = [
                  const=[], default=[{}]),
   cli.cli_option("--no-confd", dest="do_confd_tests",
                  help="Skip confd queries",
-                 action="store_false", default=True),
+                 action="store_false", default=constants.ENABLE_CONFD),
   cli.cli_option("--rename", dest="rename", default=None,
                  help=("Give one unused instance name which is taken"
                        " to start the renaming sequence"),
@@ -232,7 +240,7 @@ def _DoCheckInstances(fn):
   def wrapper(self, *args, **kwargs):
     val = fn(self, *args, **kwargs)
     for instance in self.instances:
-      self._CheckInstanceAlive(instance) # pylint: disable-msg=W0212
+      self._CheckInstanceAlive(instance) # pylint: disable=W0212
     return val
 
   return wrapper
@@ -312,7 +320,7 @@ class Burner(object):
         Log("Idempotent %s succeeded after %d retries",
             msg, MAX_RETRIES - retry_count)
       return val
-    except Exception, err: # pylint: disable-msg=W0703
+    except Exception, err: # pylint: disable=W0703
       if retry_count == 0:
         Log("Non-idempotent %s failed, aborting", msg)
         raise
@@ -358,7 +366,7 @@ class Burner(object):
       cli.SetGenericOpcodeOpts(ops, self.opts)
       self.queued_ops.append((ops, name, post_process))
     else:
-      val = self.ExecOp(self.queue_retry, *ops) # pylint: disable-msg=W0142
+      val = self.ExecOp(self.queue_retry, *ops) # pylint: disable=W0142
       if post_process is not None:
         post_process()
       return val
@@ -400,10 +408,10 @@ class Burner(object):
     self.ClearFeedbackBuf()
     jex = cli.JobExecutor(cl=self.cl, feedback_fn=self.Feedback)
     for ops, name, _ in jobs:
-      jex.QueueJob(name, *ops) # pylint: disable-msg=W0142
+      jex.QueueJob(name, *ops) # pylint: disable=W0142
     try:
       results = jex.GetResults()
-    except Exception, err: # pylint: disable-msg=W0703
+    except Exception, err: # pylint: disable=W0703
       Log("Jobs failed: %s", err)
       raise BurninFailure()
 
@@ -414,7 +422,7 @@ class Burner(object):
         if post_process:
           try:
             post_process()
-          except Exception, err: # pylint: disable-msg=W0703
+          except Exception, err: # pylint: disable=W0703
             Log("Post process call for job %s failed: %s", name, err)
             fail = True
         val.append(result)
@@ -442,11 +450,19 @@ class Burner(object):
     if len(args) < 1 or options.os is None:
       Usage()
 
+    if options.mem_size:
+      options.maxmem_size = options.mem_size
+      options.minmem_size = options.mem_size
+    elif options.minmem_size > options.maxmem_size:
+      Err("Maximum memory lower than minimum memory")
+
     supported_disk_templates = (constants.DT_DISKLESS,
                                 constants.DT_FILE,
                                 constants.DT_SHARED_FILE,
                                 constants.DT_PLAIN,
-                                constants.DT_DRBD8)
+                                constants.DT_DRBD8,
+                                constants.DT_RBD,
+                                )
     if options.disk_template not in supported_disk_templates:
       Err("Unknown disk template '%s'" % options.disk_template)
 
@@ -476,7 +492,8 @@ class Burner(object):
     self.opts = options
     self.instances = args
     self.bep = {
-      constants.BE_MEMORY: options.mem_size,
+      constants.BE_MINMEM: options.minmem_size,
+      constants.BE_MAXMEM: options.maxmem_size,
       constants.BE_VCPUS: options.vcpu_count,
       }
 
@@ -589,6 +606,18 @@ class Burner(object):
       self.ExecOrQueue(instance, [op], post_process=remove_instance(instance))
 
   @_DoBatch(False)
+  def BurnModifyRuntimeMemory(self):
+    """Alter the runtime memory."""
+    Log("Setting instance runtime memory")
+    for instance in self.instances:
+      Log("instance %s", instance, indent=1)
+      tgt_mem = self.bep[constants.BE_MINMEM]
+      op = opcodes.OpInstanceSetParams(instance_name=instance,
+                                       runtime_mem=tgt_mem)
+      Log("Set memory to %s MB", tgt_mem, indent=2)
+      self.ExecOrQueue(instance, [op])
+
+  @_DoBatch(False)
   def BurnGrowDisks(self):
     """Grow both the os and the swap disks by the requested amount, if any."""
     Log("Growing disks")
@@ -991,9 +1020,16 @@ class Burner(object):
       Err("When one node is available/selected the disk template must"
           " be 'diskless', 'file' or 'plain'")
 
+    if opts.do_confd_tests and not constants.ENABLE_CONFD:
+      Err("You selected confd tests but confd was disabled at configure time")
+
     has_err = True
     try:
       self.BurnCreateInstances()
+
+      if self.bep[constants.BE_MINMEM] < self.bep[constants.BE_MAXMEM]:
+        self.BurnModifyRuntimeMemory()
+
       if opts.do_replace1 and opts.disk_template in constants.DTS_INT_MIRROR:
         self.BurnReplaceDisks1D8()
       if (opts.do_replace2 and len(self.nodes) > 2 and
@@ -1066,7 +1102,7 @@ class Burner(object):
       if not self.opts.keep_instances:
         try:
           self.BurnRemove()
-        except Exception, err:  # pylint: disable-msg=W0703
+        except Exception, err:  # pylint: disable=W0703
           if has_err: # already detected errors, so errors in removal
                       # are quite expected
             Log("Note: error detected during instance remove: %s", err)