commit 6785674eb6f0eefcb0a2dcda537e7cd704dd0b04
Author: Iustin Pop <iustin@google.com>
Date:   Tue Oct 14 10:20:21 2008 +0000

    Switch instance hypervisor parameters to hvparams
    
    This big patch changes instance create to the new hvparams structure.
    Old parameters are removed, so old jobs or old instances file will break
    current clusters.
    
    Reviewed-by: ultrotter

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 6cdde4e..6743556 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -3153,7 +3153,7 @@ class LUCreateInstance(LogicalUnit):
   HTYPE = constants.HTYPE_INSTANCE
   _OP_REQP = ["instance_name", "mem_size", "disk_size",
               "disk_template", "swap_size", "mode", "start", "vcpus",
-              "wait_for_sync", "ip_check", "mac"]
+              "wait_for_sync", "ip_check", "mac", "hvparams"]
   REQ_BGL = False
 
   def _ExpandNode(self, node):
@@ -3174,10 +3174,7 @@ class LUCreateInstance(LogicalUnit):
     self.needed_locks = {}
 
     # set optional parameters to none if they don't exist
-    for attr in ["kernel_path", "initrd_path", "pnode", "snode",
-                 "iallocator", "hvm_boot_order", "hvm_acpi", "hvm_pae",
-                 "hvm_cdrom_image_path", "hvm_nic_type", "hvm_disk_type",
-                 "vnc_bind_address", "hypervisor"]:
+    for attr in ["pnode", "snode", "iallocator", "hypervisor"]:
       if not hasattr(self.op, attr):
         setattr(self.op, attr, None)
 
@@ -3202,6 +3199,11 @@ class LUCreateInstance(LogicalUnit):
                                  " cluster (%s)" % (self.op.hypervisor,
                                   ",".join(enabled_hvs)))
 
+    # check hypervisor parameter syntax (locally)
+
+    hv_type = hypervisor.GetHypervisor(self.op.hypervisor)
+    hv_type.CheckParameterSyntax(self.op.hvparams)
+
     #### instance parameters check
 
     # instance name verification
@@ -3237,11 +3239,6 @@ class LUCreateInstance(LogicalUnit):
         raise errors.OpPrereqError("invalid MAC address specified: %s" %
                                    self.op.mac)
 
-    # boot order verification
-    if self.op.hvm_boot_order is not None:
-      if len(self.op.hvm_boot_order.strip("acdn")) != 0:
-        raise errors.OpPrereqError("invalid boot order specified,"
-                                   " must be one or more of [acdn]")
     # file storage checks
     if (self.op.file_driver and
         not self.op.file_driver in constants.FILE_DRIVER):
@@ -3435,12 +3432,13 @@ class LUCreateInstance(LogicalUnit):
                                    " the primary node.")
       self.secondaries.append(self.op.snode)
 
+    nodenames = [pnode.name] + self.secondaries
+
     req_size = _ComputeDiskSize(self.op.disk_template,
                                 self.op.disk_size, self.op.swap_size)
 
     # Check lv size requirements
     if req_size is not None:
-      nodenames = [pnode.name] + self.secondaries
       nodeinfo = self.rpc.call_node_info(nodenames, self.cfg.GetVGName(),
                                          self.op.hypervisor)
       for node in nodenames:
@@ -3457,15 +3455,25 @@ class LUCreateInstance(LogicalUnit):
                                      " %d MB available, %d MB required" %
                                      (node, info['vg_free'], req_size))
 
+    # hypervisor parameter validation
+    hvinfo = self.rpc.call_hypervisor_validate_params(nodenames,
+                                                      self.op.hypervisor,
+                                                      self.op.hvparams)
+    for node in nodenames:
+      info = hvinfo.get(node, None)
+      if not info or not isinstance(info, (tuple, list)):
+        raise errors.OpPrereqError("Cannot get current information"
+                                   " from node '%s' (%s)" % (node, info))
+      if not info[0]:
+        raise errors.OpPrereqError("Hypervisor parameter validation failed:"
+                                   " %s" % info[1])
+
     # os verification
     os_obj = self.rpc.call_os_get(pnode.name, self.op.os_type)
     if not os_obj:
       raise errors.OpPrereqError("OS '%s' not in supported os list for"
                                  " primary node"  % self.op.os_type)
 
-    if self.op.kernel_path == constants.VALUE_NONE:
-      raise errors.OpPrereqError("Can't set instance kernel to none")
-
     # bridge check on primary node
     if not self.rpc.call_bridges_exist(self.pnode.name, [self.op.bridge]):
       raise errors.OpPrereqError("target bridge '%s' does not exist on"
@@ -3478,35 +3486,6 @@ class LUCreateInstance(LogicalUnit):
                            "creating instance %s" % self.op.instance_name,
                            self.op.mem_size, self.op.hypervisor)
 
-    # hvm_cdrom_image_path verification
-    if self.op.hvm_cdrom_image_path is not None:
-      # FIXME (als): shouldn't these checks happen on the destination node?
-      if not os.path.isabs(self.op.hvm_cdrom_image_path):
-        raise errors.OpPrereqError("The path to the HVM CDROM image must"
-                                   " be an absolute path or None, not %s" %
-                                   self.op.hvm_cdrom_image_path)
-      if not os.path.isfile(self.op.hvm_cdrom_image_path):
-        raise errors.OpPrereqError("The HVM CDROM image must either be a"
-                                   " regular file or a symlink pointing to"
-                                   " an existing regular file, not %s" %
-                                   self.op.hvm_cdrom_image_path)
-
-    # vnc_bind_address verification
-    if self.op.vnc_bind_address is not None:
-      if not utils.IsValidIP(self.op.vnc_bind_address):
-        raise errors.OpPrereqError("given VNC bind address '%s' doesn't look"
-                                   " like a valid IP address" %
-                                   self.op.vnc_bind_address)
-
-    # Xen HVM device type checks
-    if self.op.hypervisor == constants.HT_XEN_HVM:
-      if self.op.hvm_nic_type not in constants.HT_HVM_VALID_NIC_TYPES:
-        raise errors.OpPrereqError("Invalid NIC type %s specified for Xen HVM"
-                                   " hypervisor" % self.op.hvm_nic_type)
-      if self.op.hvm_disk_type not in constants.HT_HVM_VALID_DISK_TYPES:
-        raise errors.OpPrereqError("Invalid disk type %s specified for Xen HVM"
-                                   " hypervisor" % self.op.hvm_disk_type)
-
     if self.op.start:
       self.instance_status = 'up'
     else:
@@ -3534,8 +3513,8 @@ class LUCreateInstance(LogicalUnit):
     else:
       network_port = None
 
-    if self.op.vnc_bind_address is None:
-      self.op.vnc_bind_address = constants.VNC_DEFAULT_BIND_ADDRESS
+    ##if self.op.vnc_bind_address is None:
+    ##  self.op.vnc_bind_address = constants.VNC_DEFAULT_BIND_ADDRESS
 
     # this is needed because os.path.join does not accept None arguments
     if self.op.file_storage_dir is None:
@@ -3565,15 +3544,7 @@ class LUCreateInstance(LogicalUnit):
                             disk_template=self.op.disk_template,
                             status=self.instance_status,
                             network_port=network_port,
-                            kernel_path=self.op.kernel_path,
-                            initrd_path=self.op.initrd_path,
-                            hvm_boot_order=self.op.hvm_boot_order,
-                            hvm_acpi=self.op.hvm_acpi,
-                            hvm_pae=self.op.hvm_pae,
-                            hvm_cdrom_image_path=self.op.hvm_cdrom_image_path,
-                            vnc_bind_address=self.op.vnc_bind_address,
-                            hvm_nic_type=self.op.hvm_nic_type,
-                            hvm_disk_type=self.op.hvm_disk_type,
+                            hvparams=self.op.hvparams,
                             hypervisor=self.op.hypervisor,
                             )
 
diff --git a/lib/objects.py b/lib/objects.py
index 6e6667f..a4c58d1 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -514,15 +514,6 @@ class Instance(TaggableObject):
     "disks",
     "disk_template",
     "network_port",
-    "kernel_path",
-    "initrd_path",
-    "hvm_boot_order",
-    "hvm_acpi",
-    "hvm_pae",
-    "hvm_cdrom_image_path",
-    "hvm_nic_type",
-    "hvm_disk_type",
-    "vnc_bind_address",
     "serial_no",
     ]
 
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 550e408..8166ca3 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -323,11 +323,9 @@ class OpCreateInstance(OpCode):
     "disk_template", "snode", "swap_size", "mode",
     "vcpus", "ip", "bridge", "src_node", "src_path", "start",
     "wait_for_sync", "ip_check", "mac",
-    "kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
-    "hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
     "file_storage_dir", "file_driver",
-    "iallocator", "hvm_nic_type", "hvm_disk_type",
-    "hypervisor",
+    "iallocator",
+    "hypervisor", "hvparams", "beparams",
     ]
 
 
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 557ae0c..c05bdf5 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -266,17 +266,22 @@ def AddInstance(opts, args):
 
   (pnode, snode) = SplitNodeOption(opts.node)
 
-  kernel_path = _TransformPath(opts.kernel_path)
-  initrd_path = _TransformPath(opts.initrd_path)
+  hypervisor = None
+  hvparams = {}
+  if opts.hypervisor:
+    hypervisor, hvparams = opts.hypervisor
 
-  hvm_acpi = opts.hvm_acpi == _VALUE_TRUE
-  hvm_pae = opts.hvm_pae == _VALUE_TRUE
+##  kernel_path = _TransformPath(opts.kernel_path)
+##  initrd_path = _TransformPath(opts.initrd_path)
 
-  if ((opts.hvm_cdrom_image_path is not None) and
-      (opts.hvm_cdrom_image_path.lower() == constants.VALUE_NONE)):
-    hvm_cdrom_image_path = None
-  else:
-    hvm_cdrom_image_path = opts.hvm_cdrom_image_path
+##  hvm_acpi = opts.hvm_acpi == _VALUE_TRUE
+##  hvm_pae = opts.hvm_pae == _VALUE_TRUE
+
+##  if ((opts.hvm_cdrom_image_path is not None) and
+##      (opts.hvm_cdrom_image_path.lower() == constants.VALUE_NONE)):
+##    hvm_cdrom_image_path = None
+##  else:
+##    hvm_cdrom_image_path = opts.hvm_cdrom_image_path
 
   op = opcodes.OpCreateInstance(instance_name=instance, mem_size=opts.mem,
                                 disk_size=opts.size, swap_size=opts.swap,
@@ -288,17 +293,12 @@ def AddInstance(opts, args):
                                 start=opts.start, ip_check=opts.ip_check,
                                 wait_for_sync=opts.wait_for_sync,
                                 mac=opts.mac,
-                                kernel_path=kernel_path,
-                                initrd_path=initrd_path,
+                                hypervisor=hypervisor,
+                                hvparams=hvparams,
                                 iallocator=opts.iallocator,
-                                hvm_boot_order=opts.hvm_boot_order,
                                 file_storage_dir=opts.file_storage_dir,
                                 file_driver=opts.file_driver,
-                                hvm_acpi=hvm_acpi, hvm_pae=hvm_pae,
-                                hvm_cdrom_image_path=hvm_cdrom_image_path,
-                                vnc_bind_address=opts.vnc_bind_address,
-                                hvm_nic_type=opts.hvm_nic_type,
-                                hvm_disk_type=opts.hvm_disk_type)
+                                )
 
   SubmitOrSend(op, opts)
   return 0
@@ -918,28 +918,10 @@ add_opts = [
   make_option("--iallocator", metavar="<NAME>",
               help="Select nodes for the instance automatically using the"
               " <NAME> iallocator plugin", default=None, type="string"),
-  make_option("--hvm-acpi", dest="hvm_acpi",
-              help="ACPI support for HVM (true|false)",
-              metavar="<BOOL>", choices=["true", "false"]),
-  make_option("--hvm-nic-type", dest="hvm_nic_type",
-              help="Type of virtual NIC for HVM "
-              "(rtl8139,ne2k_pci,ne2k_isa,paravirtual)",
-              metavar="NICTYPE", choices=[constants.HT_HVM_NIC_RTL8139,
-                                          constants.HT_HVM_NIC_NE2K_PCI,
-                                          constants.HT_HVM_NIC_NE2K_ISA,
-                                          constants.HT_HVM_DEV_PARAVIRTUAL],
-              default=constants.HT_HVM_NIC_RTL8139),
-  make_option("--hvm-disk-type", dest="hvm_disk_type",
-              help="Type of virtual disks for HVM (ioemu,paravirtual)",
-              metavar="DISKTYPE", choices=[constants.HT_HVM_DEV_IOEMU,
-                                           constants.HT_HVM_DEV_PARAVIRTUAL],
-              default=constants.HT_HVM_DEV_IOEMU,),
-  make_option("--hvm-pae", dest="hvm_pae",
-              help="PAE support for HVM (true|false)",
-              metavar="<BOOL>", choices=["true", "false"]),
-  make_option("--hvm-cdrom-image-path", dest="hvm_cdrom_image_path",
-              help="CDROM image path for HVM (absolute path or None)",
-              default=None, type="string", metavar="<CDROMIMAGE>"),
+  ikv_option("-H", "--hypervisor", dest="hypervisor",
+              help="Hypervisor and hypervisor options, in the format"
+              " hypervisor:option=value,option=value,...", default=None,
+              type="identkeyval"),
   make_option("--vnc-bind-address", dest="vnc_bind_address",
               help="bind address for VNC (IP address)",
               default=None, type="string", metavar="<VNCADDRESS>"),
