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