From d77490c53fc3574b72e70b126b329fc1b59ce90e Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Fri, 18 Sep 2009 14:48:22 +0200
Subject: [PATCH] Unify the instance creation code

Currently the AddInstance in gnt-instance and ImportInstance in
gnt-backup duplicate all of their code except the actual opcode creation
(the parameters to it). By moving this to cli.py (not optimal location,
but we don't have another one), we can use a single copy of the code,
and simply change based on the mode parameter the few different
opcode parameters.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/cli.py           | 111 +++++++++++++++++++++++++++++++++++++++++++
 scripts/gnt-backup   |  90 ++---------------------------------
 scripts/gnt-instance |  88 +---------------------------------
 3 files changed, 116 insertions(+), 173 deletions(-)

diff --git a/lib/cli.py b/lib/cli.py
index 2cc8175c6..c7f23a1f0 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -116,6 +116,7 @@ __all__ = [
   "YES_DOIT_OPT",
   # Generic functions for CLI programs
   "GenericMain",
+  "GenericInstanceCreate",
   "GetClient",
   "GetOnlineNodes",
   "JobExecutor",
@@ -1323,6 +1324,116 @@ def GenericMain(commands, override=None, aliases=None):
   return result
 
 
+def GenericInstanceCreate(mode, opts, args):
+  """Add an instance to the cluster via either creation or import.
+
+  @param mode: constants.INSTANCE_CREATE or constants.INSTANCE_IMPORT
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should contain only one element, the new instance name
+  @rtype: int
+  @return: the desired exit code
+
+  """
+  instance = args[0]
+
+  (pnode, snode) = SplitNodeOption(opts.node)
+
+  hypervisor = None
+  hvparams = {}
+  if opts.hypervisor:
+    hypervisor, hvparams = opts.hypervisor
+
+  if opts.nics:
+    try:
+      nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
+    except ValueError, err:
+      raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
+    nics = [{}] * nic_max
+    for nidx, ndict in opts.nics:
+      nidx = int(nidx)
+      if not isinstance(ndict, dict):
+        msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
+        raise errors.OpPrereqError(msg)
+      nics[nidx] = ndict
+  elif opts.no_nics:
+    # no nics
+    nics = []
+  else:
+    # default of one nic, all auto
+    nics = [{}]
+
+  if opts.disk_template == constants.DT_DISKLESS:
+    if opts.disks or opts.sd_size is not None:
+      raise errors.OpPrereqError("Diskless instance but disk"
+                                 " information passed")
+    disks = []
+  else:
+    if not opts.disks and not opts.sd_size:
+      raise errors.OpPrereqError("No disk information specified")
+    if opts.disks and opts.sd_size is not None:
+      raise errors.OpPrereqError("Please use either the '--disk' or"
+                                 " '-s' option")
+    if opts.sd_size is not None:
+      opts.disks = [(0, {"size": opts.sd_size})]
+    try:
+      disk_max = max(int(didx[0])+1 for didx in opts.disks)
+    except ValueError, err:
+      raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
+    disks = [{}] * disk_max
+    for didx, ddict in opts.disks:
+      didx = int(didx)
+      if not isinstance(ddict, dict):
+        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
+        raise errors.OpPrereqError(msg)
+      elif "size" not in ddict:
+        raise errors.OpPrereqError("Missing size for disk %d" % didx)
+      try:
+        ddict["size"] = utils.ParseUnit(ddict["size"])
+      except ValueError, err:
+        raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
+                                   (didx, err))
+      disks[didx] = ddict
+
+  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
+  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
+
+  if mode == constants.INSTANCE_CREATE:
+    start = opts.start
+    os_type = opts.os
+    src_node = None
+    src_path = None
+  elif mode == constants.INSTANCE_IMPORT:
+    start = False
+    os_type = None
+    src_node = opts.src_node
+    src_path = opts.src_dir
+  else:
+    raise errors.ProgrammerError("Invalid creation mode %s" % mode)
+
+  op = opcodes.OpCreateInstance(instance_name=instance,
+                                disks=disks,
+                                disk_template=opts.disk_template,
+                                nics=nics,
+                                pnode=pnode, snode=snode,
+                                ip_check=opts.ip_check,
+                                wait_for_sync=opts.wait_for_sync,
+                                file_storage_dir=opts.file_storage_dir,
+                                file_driver=opts.file_driver,
+                                iallocator=opts.iallocator,
+                                hypervisor=hypervisor,
+                                hvparams=hvparams,
+                                beparams=opts.beparams,
+                                mode=mode,
+                                start=start,
+                                os_type=os_type,
+                                src_node=src_node,
+                                src_path=src_path)
+
+  SubmitOrSend(op, opts)
+  return 0
+
+
 def GenerateTable(headers, fields, separator, data,
                   numfields=None, unitfields=None,
                   units=None):
diff --git a/scripts/gnt-backup b/scripts/gnt-backup
index ae5c6016b..8189243c0 100755
--- a/scripts/gnt-backup
+++ b/scripts/gnt-backup
@@ -99,95 +99,10 @@ def ExportInstance(opts, args):
 def ImportInstance(opts, args):
   """Add an instance to the cluster.
 
-  @param opts: the command line options selected by the user
-  @type args: list
-  @param args: should contain only one element, the new instance name
-  @rtype: int
-  @return: the desired exit code
+  This is just a wrapper over GenericInstanceCreate.
 
   """
-  instance = args[0]
-
-  (pnode, snode) = SplitNodeOption(opts.node)
-
-  hypervisor = None
-  hvparams = {}
-  if opts.hypervisor:
-    hypervisor, hvparams = opts.hypervisor
-
-  if opts.nics:
-    try:
-      nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
-    except ValueError, err:
-      raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
-    nics = [{}] * nic_max
-    for nidx, ndict in opts.nics:
-      nidx = int(nidx)
-      if not isinstance(ndict, dict):
-        msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
-        raise errors.OpPrereqError(msg)
-      nics[nidx] = ndict
-  elif opts.no_nics:
-    # no nics
-    nics = []
-  else:
-    # default of one nic, all auto
-    nics = [{}]
-
-  if opts.disk_template == constants.DT_DISKLESS:
-    if opts.disks or opts.sd_size is not None:
-      raise errors.OpPrereqError("Diskless instance but disk"
-                                 " information passed")
-    disks = []
-  else:
-    if not opts.disks and not opts.sd_size:
-      raise errors.OpPrereqError("No disk information specified")
-    if opts.disks and opts.sd_size is not None:
-      raise errors.OpPrereqError("Please use either the '--disk' or"
-                                 " '-s' option")
-    if opts.sd_size is not None:
-      opts.disks = [(0, {"size": opts.sd_size})]
-    try:
-      disk_max = max(int(didx[0])+1 for didx in opts.disks)
-    except ValueError, err:
-      raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
-    disks = [{}] * disk_max
-    for didx, ddict in opts.disks:
-      didx = int(didx)
-      if not isinstance(ddict, dict):
-        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
-        raise errors.OpPrereqError(msg)
-      elif "size" not in ddict:
-        raise errors.OpPrereqError("Missing size for disk %d" % didx)
-      try:
-        ddict["size"] = utils.ParseUnit(ddict["size"])
-      except ValueError, err:
-        raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
-                                   (didx, err))
-      disks[didx] = ddict
-
-  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
-  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
-
-  op = opcodes.OpCreateInstance(instance_name=instance,
-                                disk_template=opts.disk_template,
-                                disks=disks,
-                                nics=nics,
-                                mode=constants.INSTANCE_IMPORT,
-                                pnode=pnode, snode=snode,
-                                ip_check=opts.ip_check,
-                                start=False,
-                                src_node=opts.src_node, src_path=opts.src_dir,
-                                wait_for_sync=opts.wait_for_sync,
-                                file_storage_dir=opts.file_storage_dir,
-                                file_driver=opts.file_driver,
-                                iallocator=opts.iallocator,
-                                hypervisor=hypervisor,
-                                hvparams=hvparams,
-                                beparams=opts.beparams)
-
-  SubmitOpCode(op)
-  return 0
+  return GenericInstanceCreate(constants.INSTANCE_IMPORT, opts, args)
 
 
 def RemoveExport(opts, args):
@@ -225,6 +140,7 @@ import_opts = [
   FILESTORE_DIR_OPT,
   FILESTORE_DRIVER_OPT,
   HYPERVISOR_OPT,
+  SUBMIT_OPT,
   ]
 
 commands = {
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 3ed658e1e..fd758d49b 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -311,94 +311,10 @@ def ListInstances(opts, args):
 def AddInstance(opts, args):
   """Add an instance to the cluster.
 
-  @param opts: the command line options selected by the user
-  @type args: list
-  @param args: should contain only one element, the new instance name
-  @rtype: int
-  @return: the desired exit code
+  This is just a wrapper over GenericInstanceCreate.
 
   """
-  instance = args[0]
-
-  (pnode, snode) = SplitNodeOption(opts.node)
-
-  hypervisor = None
-  hvparams = {}
-  if opts.hypervisor:
-    hypervisor, hvparams = opts.hypervisor
-
-  if opts.nics:
-    try:
-      nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
-    except ValueError, err:
-      raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
-    nics = [{}] * nic_max
-    for nidx, ndict in opts.nics:
-      nidx = int(nidx)
-      if not isinstance(ndict, dict):
-        msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
-        raise errors.OpPrereqError(msg)
-      nics[nidx] = ndict
-  elif opts.no_nics:
-    # no nics
-    nics = []
-  else:
-    # default of one nic, all auto
-    nics = [{}]
-
-  if opts.disk_template == constants.DT_DISKLESS:
-    if opts.disks or opts.sd_size is not None:
-      raise errors.OpPrereqError("Diskless instance but disk"
-                                 " information passed")
-    disks = []
-  else:
-    if not opts.disks and not opts.sd_size:
-      raise errors.OpPrereqError("No disk information specified")
-    if opts.disks and opts.sd_size is not None:
-      raise errors.OpPrereqError("Please use either the '--disk' or"
-                                 " '-s' option")
-    if opts.sd_size is not None:
-      opts.disks = [(0, {"size": opts.sd_size})]
-    try:
-      disk_max = max(int(didx[0])+1 for didx in opts.disks)
-    except ValueError, err:
-      raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
-    disks = [{}] * disk_max
-    for didx, ddict in opts.disks:
-      didx = int(didx)
-      if not isinstance(ddict, dict):
-        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
-        raise errors.OpPrereqError(msg)
-      elif "size" not in ddict:
-        raise errors.OpPrereqError("Missing size for disk %d" % didx)
-      try:
-        ddict["size"] = utils.ParseUnit(ddict["size"])
-      except ValueError, err:
-        raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
-                                   (didx, err))
-      disks[didx] = ddict
-
-  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
-  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
-
-  op = opcodes.OpCreateInstance(instance_name=instance,
-                                disks=disks,
-                                disk_template=opts.disk_template,
-                                nics=nics,
-                                mode=constants.INSTANCE_CREATE,
-                                os_type=opts.os, pnode=pnode,
-                                snode=snode,
-                                start=opts.start, ip_check=opts.ip_check,
-                                wait_for_sync=opts.wait_for_sync,
-                                hypervisor=hypervisor,
-                                hvparams=hvparams,
-                                beparams=opts.beparams,
-                                iallocator=opts.iallocator,
-                                file_storage_dir=opts.file_storage_dir,
-                                file_driver=opts.file_driver,
-                                )
-
-  SubmitOrSend(op, opts)
+  return GenericInstanceCreate(constants.INSTANCE_CREATE, opts, args)
   return 0
 
 
-- 
GitLab