On Fri, Aug 05, 2011 at 05:31:51PM +0100, Andrea Spadaccini wrote:
> Implemented the following SPICE options:
> - spice_bind
> - spice_ip_version
> - spice_password_file
> 
> Signed-off-by: Andrea Spadaccini <[email protected]>
> ---
>  lib/constants.py         |   11 +++++++
>  lib/hypervisor/hv_kvm.py |   74 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 85 insertions(+), 0 deletions(-)
> 
> diff --git a/lib/constants.py b/lib/constants.py
> index f0d88d2..a803acc 100644
> --- a/lib/constants.py
> +++ b/lib/constants.py
> @@ -567,6 +567,8 @@ DISK_TRANSFER_CONNECT_TIMEOUT = 60
>  # Disk index separator
>  DISK_SEPARATOR = _autoconf.DISK_SEPARATOR
>  IP_COMMAND_PATH = _autoconf.IP_PATH
> +# Makes SPICE use the default cluster IP version
> +SPICE_USE_CLUSTER_DEFAULT_IP_VERSION = 0

I think having this spice specific is bad; we also have a VNC bind
address, etc.

I'd rather have a single setting, cluster-wide, that is used for
converting iface names into IP addresses, and that would apply both to
VNC, Spice or any other similar use (e.g. RAPI).

>  #: Key for job IDs in opcode result
>  JOB_IDS_KEY = "jobs"
> @@ -658,6 +660,9 @@ HV_VNC_PASSWORD_FILE = "vnc_password_file"
>  HV_VNC_TLS = "vnc_tls"
>  HV_VNC_X509 = "vnc_x509_path"
>  HV_VNC_X509_VERIFY = "vnc_x509_verify"
> +HV_KVM_SPICE_BIND = "spice_bind"
> +HV_KVM_SPICE_IP_VERSION = "spice_ip_version"
> +HV_KVM_SPICE_PASSWORD_FILE = "spice_password_file"
>  HV_ACPI = "acpi"
>  HV_PAE = "pae"
>  HV_USE_BOOTLOADER = "use_bootloader"
> @@ -701,6 +706,9 @@ HVS_PARAMETER_TYPES = {
>    HV_VNC_TLS: VTYPE_BOOL,
>    HV_VNC_X509: VTYPE_STRING,
>    HV_VNC_X509_VERIFY: VTYPE_BOOL,
> +  HV_KVM_SPICE_BIND: VTYPE_STRING,
> +  HV_KVM_SPICE_IP_VERSION: VTYPE_INT,
> +  HV_KVM_SPICE_PASSWORD_FILE: VTYPE_STRING,
>    HV_ACPI: VTYPE_BOOL,
>    HV_PAE: VTYPE_BOOL,
>    HV_USE_BOOTLOADER: VTYPE_BOOL,
> @@ -1278,6 +1286,9 @@ HVC_DEFAULTS = {
>      HV_VNC_X509: "",
>      HV_VNC_X509_VERIFY: False,
>      HV_VNC_PASSWORD_FILE: "",
> +    HV_KVM_SPICE_BIND: "",
> +    HV_KVM_SPICE_IP_VERSION: SPICE_USE_CLUSTER_DEFAULT_IP_VERSION,
> +    HV_KVM_SPICE_PASSWORD_FILE: "",
>      HV_KVM_FLOPPY_IMAGE_PATH: "",
>      HV_CDROM_IMAGE_PATH: "",
>      HV_KVM_CDROM2_IMAGE_PATH: "",
> diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
> index 1b95d6d..74f01a0 100644
> --- a/lib/hypervisor/hv_kvm.py
> +++ b/lib/hypervisor/hv_kvm.py
> @@ -165,6 +165,10 @@ class KVMHypervisor(hv_base.BaseHypervisor):
>      constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
>      constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
>      constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
> +    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
> +    constants.HV_KVM_SPICE_IP_VERSION:
> +      hv_base.ParamInSet(False, constants.VALID_IP_VERSIONS),
> +    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
>      constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
>      constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
>      constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
> @@ -716,6 +720,76 @@ class KVMHypervisor(hv_base.BaseHypervisor):
>      else:
>        kvm_cmd.extend(["-serial", "none"])
>  
> +    spice_bind = hvp[constants.HV_KVM_SPICE_BIND]
> +    # Only one of VNC and SPICE can be used currently.
> +    if vnc_bind_address and spice_bind:
> +        raise errors.HypervisorError("both spice and vnc are configured, but"
> +                                     " only one of them can be used at a"
> +                                     " given time.")

This should not be checked here, but in CheckParameterSyntax.

> +    if spice_bind:
> +      # SPICE support is available only on KVM >= 0.14.0
> +      if (v_major, v_min) < (0, 14):
> +        raise errors.HypervisorError("spice is configured, but it is not"
> +                                     " available in versions of KVM < 0.14")
> +
> +      spice_ip_version = hvp[constants.HV_KVM_SPICE_IP_VERSION]
> +      if spice_ip_version == constants.SPICE_USE_CLUSTER_DEFAULT_IP_VERSION:
> +        cluster_family = ssconf.SimpleStore().GetPrimaryIPFamily()
> +        spice_ip_version = netutils.IpAddressFamilyToVersion(cluster_family)
> +      elif not spice_ip_version in constants.VALID_IP_VERSIONS:
> +        raise errors.HypervisorError("spice: The specified IP version (%d) 
> is"
> +                                     " invalid." % spice_ip_version)

Also this.

> +      if netutils.IP4Address.IsValid(spice_bind):
> +        if spice_ip_version != constants.IP4_VERSION:
> +          raise errors.HypervisorError("spice: got an IPv4 address (%s), but"
> +                                       " the specified IP version is %d."
> +                                       % (spice_bind, spice_ip_version))

Also this.

> +      elif netutils.IP6Address.IsValid(spice_bind):
> +        if spice_ip_version != constants.IP6_VERSION:
> +          raise errors.HypervisorError("spice: got an IPv6 address (%s), but"
> +                                       " the specified IP version is %d."
> +                                       % (spice_bind, spice_ip_version))
> +
> +      elif netutils.IsValidInterface(spice_bind):
> +        addresses = netutils.GetInterfaceIpAddresses(spice_bind,
> +                                                     spice_ip_version)
> +        if not addresses:
> +          raise errors.HypervisorError("spice: unable to get an IPv%d 
> address"
> +                                       " for %s" % (spice_ip_version, 
> +                                                    spice_bind))

And this.
> +        spice_bind = addresses[0]
> +
> +      else:
> +        raise errors.HypervisorError("spice: the %s parameter must be either 
> a"
> +                                     " valid IP address or interface name" %
> +                                     constants.HV_KVM_SPICE_BIND)
> +
> +
> +      spice_arg = "addr=%s,ipv%d,port=%d" % (spice_bind,
> +                                             spice_ip_version,
> +                                             instance.network_port)
> +
> +      spice_pwd_file = hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]
> +      if spice_pwd_file:
> +        try:
> +          spice_pwd = utils.ReadOneLineFile(spice_pwd_file, strict=True)
> +          spice_arg = "%s,password=%s" % (spice_arg, spice_pwd)
> +        except EnvironmentError, err:
> +          raise errors.HypervisorError("spice: failed to open the password"
> +                                       " file %s: %s" % (spice_pwd_file, 
> err))

I think this too.


thanks,
iustin

Reply via email to