From 31a853d29eef10d91092cbb41ad814d0b11050f3 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sat, 31 May 2008 23:14:35 +0000
Subject: [PATCH] Forward-port: patch 2/4 extended HVM features for 1.2

This patch adds the commandline extensions and the code to store
and display the extended HVM features.

Author: schreiberal
Reviewed-by: iustinp
---
 lib/cmdlib.py        | 73 +++++++++++++++++++++++++++++++++++++++++---
 lib/constants.py     |  2 ++
 lib/opcodes.py       |  6 ++--
 scripts/gnt-instance | 69 ++++++++++++++++++++++++++++++++++++++---
 4 files changed, 140 insertions(+), 10 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index dc213b331..8c5fd4327 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -3294,7 +3294,8 @@ class LUCreateInstance(LogicalUnit):
     """
     # set optional parameters to none if they don't exist
     for attr in ["kernel_path", "initrd_path", "hvm_boot_order", "pnode",
-                 "iallocator"]:
+                 "iallocator", "hvm_acpi", "hvm_pae", "hvm_cdrom_image_path",
+                 "vnc_bind_address"]:
       if not hasattr(self.op, attr):
         setattr(self.op, attr, None)
 
@@ -3484,6 +3485,25 @@ class LUCreateInstance(LogicalUnit):
                                  " destination node '%s'" %
                                  (self.op.bridge, pnode.name))
 
+    # hvm_cdrom_image_path verification
+    if self.op.hvm_cdrom_image_path is not None:
+      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)
+
     if self.op.start:
       self.instance_status = 'up'
     else:
@@ -3511,6 +3531,9 @@ 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
+
     # this is needed because os.path.join does not accept None arguments
     if self.op.file_storage_dir is None:
       string_file_storage_dir = ""
@@ -3542,6 +3565,10 @@ class LUCreateInstance(LogicalUnit):
                             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,
                             )
 
     feedback_fn("* creating instance disks...")
@@ -4231,6 +4258,10 @@ class LUQueryInstanceData(NoHooksLU):
         "kernel_path": instance.kernel_path,
         "initrd_path": instance.initrd_path,
         "hvm_boot_order": instance.hvm_boot_order,
+        "hvm_acpi": instance.hvm_acpi,
+        "hvm_pae": instance.hvm_pae,
+        "hvm_cdrom_image_path": instance.hvm_cdrom_image_path,
+        "vnc_bind_address": instance.vnc_bind_address,
         }
 
       result[instance.name] = idict
@@ -4290,9 +4321,15 @@ class LUSetInstanceParams(LogicalUnit):
     self.kernel_path = getattr(self.op, "kernel_path", None)
     self.initrd_path = getattr(self.op, "initrd_path", None)
     self.hvm_boot_order = getattr(self.op, "hvm_boot_order", None)
-    all_params = [self.mem, self.vcpus, self.ip, self.bridge, self.mac,
-                  self.kernel_path, self.initrd_path, self.hvm_boot_order]
-    if all_params.count(None) == len(all_params):
+    self.hvm_acpi = getattr(self.op, "hvm_acpi", None)
+    self.hvm_pae = getattr(self.op, "hvm_pae", None)
+    self.hvm_cdrom_image_path = getattr(self.op, "hvm_cdrom_image_path", None)
+    self.vnc_bind_address = getattr(self.op, "vnc_bind_address", None)
+    all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac,
+                 self.kernel_path, self.initrd_path, self.hvm_boot_order,
+                 self.hvm_acpi, self.hvm_pae, self.hvm_cdrom_image_path,
+                 self.vnc_bind_address]
+    if all_parms.count(None) == len(all_parms):
       raise errors.OpPrereqError("No changes submitted")
     if self.mem is not None:
       try:
@@ -4351,6 +4388,25 @@ class LUSetInstanceParams(LogicalUnit):
                                      " must be one or more of [acdn]"
                                      " or 'default'")
 
+    # hvm_cdrom_image_path verification
+    if self.op.hvm_cdrom_image_path is not None:
+      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)
+
     instance = self.cfg.GetInstanceInfo(
       self.cfg.ExpandInstanceName(self.op.instance_name))
     if instance is None:
@@ -4394,6 +4450,15 @@ class LUSetInstanceParams(LogicalUnit):
       else:
         instance.hvm_boot_order = self.hvm_boot_order
       result.append(("hvm_boot_order", self.hvm_boot_order))
+    if self.hvm_acpi:
+      result.append(("hvm_acpi", self.hvm_acpi))
+    if self.hvm_pae:
+      result.append(("hvm_pae", self.hvm_pae))
+    if self.hvm_cdrom_image_path:
+      result.append(("hvm_cdrom_image_path", self.hvm_cdrom_image_path))
+    if self.vnc_bind_address:
+      instance.vnc_bind_address = self.vnc_bind_address
+      result.append(("vnc_bind_address", self.vnc_bind_address))
 
     self.cfg.AddInstance(instance)
 
diff --git a/lib/constants.py b/lib/constants.py
index a522ede84..1236b793d 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -160,6 +160,7 @@ LOCALHOST_IP_ADDRESS = "127.0.0.1"
 TCP_PING_TIMEOUT = 10
 GANETI_RUNAS = "root"
 DEFAULT_VG = "xenvg"
+BIND_ADDRESS_GLOBAL = "0.0.0.0"
 
 # valid os status
 OS_VALID_STATUS = "VALID"
@@ -189,6 +190,7 @@ HTS_REQ_PORT = frozenset([HT_XEN_HVM31])
 HT_HVM_VNC_BASE_PORT = 5900
 HT_HVM_DEFAULT_BOOT_ORDER = 'dc'
 VNC_PASSWORD_FILE = _autoconf.SYSCONFDIR + "/ganeti/vnc-cluster-password"
+VNC_DEFAULT_BIND_ADDRESS = '0.0.0.0'
 
 # Cluster Verify steps
 VERIFY_NPLUSONE_MEM = 'nplusone_mem'
diff --git a/lib/opcodes.py b/lib/opcodes.py
index ad4716956..dbae63cc3 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -282,7 +282,8 @@ 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",
+    "kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
+    "hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
     "file_storage_dir", "file_driver",
     "iallocator",
     ]
@@ -372,7 +373,8 @@ class OpSetInstanceParams(OpCode):
   OP_ID = "OP_INSTANCE_SET_PARAMS"
   __slots__ = [
     "instance_name", "mem", "vcpus", "ip", "bridge", "mac",
-    "kernel_path", "initrd_path", "hvm_boot_order",
+    "kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
+    "hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address"
     ]
 
 
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 4fb38fc54..afea5e885 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -40,6 +40,8 @@ _SHUTDOWN_NODES_SEC = "nodes-sec"
 _SHUTDOWN_INSTANCES = "instances"
 
 
+_VALUE_TRUE = "true"
+
 _LIST_DEF_FIELDS = [
   "name", "os", "pnode", "status", "oper_ram",
   ]
@@ -254,6 +256,15 @@ def AddInstance(opts, args):
   kernel_path = _TransformPath(opts.kernel_path)
   initrd_path = _TransformPath(opts.initrd_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,
                                 disk_template=opts.disk_template,
@@ -266,10 +277,14 @@ def AddInstance(opts, args):
                                 mac=opts.mac,
                                 kernel_path=kernel_path,
                                 initrd_path=initrd_path,
+                                iallocator=opts.iallocator,
                                 hvm_boot_order=opts.hvm_boot_order,
                                 file_storage_dir=opts.file_storage_dir,
                                 file_driver=opts.file_driver,
-                                iallocator=opts.iallocator)
+                                hvm_acpi=hvm_acpi, hvm_pae=hvm_pae,
+                                hvm_cdrom_image_path=hvm_cdrom_image_path,
+                                vnc_bind_address=opts.vnc_bind_address)
+
   SubmitOpCode(op)
   return 0
 
@@ -641,7 +656,12 @@ def ShowInstanceConfig(opts, args):
     else:
       initrd = instance["initrd_path"]
     buf.write("       initrd: %s\n" % initrd)
-    buf.write("  HVM boot order: %s\n" % instance["hvm_boot_order"])
+    buf.write("  HVM:\n")
+    buf.write("    - boot order: %s\n" % instance["hvm_boot_order"])
+    buf.write("    - ACPI support: %s\n" % instance["hvm_acpi"])
+    buf.write("    - PAE support: %s\n" % instance["hvm_pae"])
+    buf.write("    - virtual CDROM: %s\n" % instance["hvm_cdrom_image_path"])
+    buf.write("  VNC bind address: %s\n" % instance["vnc_bind_address"])
     buf.write("  Hardware:\n")
     buf.write("    - VCPUs: %d\n" % instance["vcpus"])
     buf.write("    - memory: %dMiB\n" % instance["memory"])
@@ -673,7 +693,9 @@ def SetInstanceParams(opts, args):
 
   """
   if not (opts.mem or opts.vcpus or opts.ip or opts.bridge or opts.mac or
-          opts.kernel_path or opts.initrd_path or opts.hvm_boot_order):
+          opts.kernel_path or opts.initrd_path or opts.hvm_boot_order or
+          opts.hvm_acpi or opts.hvm_acpi or opts.hvm_cdrom_image_path or
+          opts.vnc_bind_address):
     logger.ToStdout("Please give at least one of the parameters.")
     return 1
 
@@ -684,12 +706,25 @@ def SetInstanceParams(opts, args):
   else:
     hvm_boot_order = opts.hvm_boot_order
 
+  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.OpSetInstanceParams(instance_name=args[0], mem=opts.mem,
                                    vcpus=opts.vcpus, ip=opts.ip,
                                    bridge=opts.bridge, mac=opts.mac,
                                    kernel_path=opts.kernel_path,
                                    initrd_path=opts.initrd_path,
-                                   hvm_boot_order=hvm_boot_order)
+                                   hvm_boot_order=hvm_boot_order,
+                                   hvm_acpi=hvm_acpi, hvm_pae=hvm_pae,
+                                   hvm_cdrom_image_path=hvm_cdrom_image_path,
+                                   vnc_bind_address=opts.vnc_bind_address)
+
   result = SubmitOpCode(op)
 
   if result:
@@ -792,6 +827,18 @@ 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-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>"),
+  make_option("--vnc-bind-address", dest="vnc_bind_address",
+              help="bind address for VNC (IP address)",
+              default=None, type="string", metavar="<VNCADDRESS>"),
   ]
 
 commands = {
@@ -899,6 +946,20 @@ commands = {
                           help="boot device order for HVM"
                           "(either one or more of [acdn] or 'default')",
                           default=None, type="string", metavar="<BOOTORDER>"),
+              make_option("--hvm-acpi", dest="hvm_acpi",
+                          help="ACPI support for HVM (true|false)",
+                          metavar="<BOOL>", choices=["true", "false"]),
+              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>"),
+              make_option("--vnc-bind-address", dest="vnc_bind_address",
+                          help="bind address for VNC (IP address)",
+                          default=None, type="string", metavar="<VNCADDRESS>"),
               ],
              "<instance>", "Alters the parameters of an instance"),
   'shutdown': (ShutdownInstance, ARGS_ANY,
-- 
GitLab