diff --git a/lib/backend.py b/lib/backend.py index 36da855cc33448a052366b2d9e11eb4b20248a1b..5e50f2f373b3f821ad6ad557505130892af77370 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -196,6 +196,8 @@ def _BuildUploadFileList(): constants.SSH_KNOWN_HOSTS_FILE, constants.VNC_PASSWORD_FILE, constants.RAPI_CERT_FILE, + constants.SPICE_CERT_FILE, + constants.SPICE_CACERT_FILE, constants.RAPI_USERS_FILE, constants.CONFD_HMAC_KEY, constants.CLUSTER_DOMAIN_SECRET_FILE, @@ -411,6 +413,8 @@ def LeaveCluster(modify_ssh_setup): try: utils.RemoveFile(constants.CONFD_HMAC_KEY) utils.RemoveFile(constants.RAPI_CERT_FILE) + utils.RemoveFile(constants.SPICE_CERT_FILE) + utils.RemoveFile(constants.SPICE_CACERT_FILE) utils.RemoveFile(constants.NODED_CERT_FILE) except: # pylint: disable=W0702 logging.exception("Error while removing cluster secrets") diff --git a/lib/bootstrap.py b/lib/bootstrap.py index 733a8ba98a27eab9b88e7062fc41e76629ded3c6..a058c568e4aedcc562df864189154a197a5ccc84 100644 --- a/lib/bootstrap.py +++ b/lib/bootstrap.py @@ -557,6 +557,8 @@ def SetupNodeDaemon(cluster_name, node, ssh_key_check): # either by being constants or by the checks above sshrunner.CopyFileToNode(node, constants.NODED_CERT_FILE) sshrunner.CopyFileToNode(node, constants.RAPI_CERT_FILE) + sshrunner.CopyFileToNode(node, constants.SPICE_CERT_FILE) + sshrunner.CopyFileToNode(node, constants.SPICE_CACERT_FILE) sshrunner.CopyFileToNode(node, constants.CONFD_HMAC_KEY) mycommand = ("%s stop-all; %s start %s -b %s" % (constants.DAEMON_UTIL, constants.DAEMON_UTIL, constants.NODED, diff --git a/lib/constants.py b/lib/constants.py index 13a1a07b90a06baaf05acb1855980bdf2433c960..c9e1c5c7f3566b506e21c487cbb58752d4ef8030 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -139,6 +139,8 @@ CLUSTER_CONF_FILE = DATA_DIR + "/config.data" NODED_CERT_FILE = DATA_DIR + "/server.pem" RAPI_CERT_FILE = DATA_DIR + "/rapi.pem" CONFD_HMAC_KEY = DATA_DIR + "/hmac.key" +SPICE_CERT_FILE = DATA_DIR + "/spice.pem" +SPICE_CACERT_FILE = DATA_DIR + "/spice-ca.pem" CLUSTER_DOMAIN_SECRET_FILE = DATA_DIR + "/cluster-domain-secret" INSTANCE_STATUS_FILE = RUN_GANETI_DIR + "/instance-status" SSH_KNOWN_HOSTS_FILE = DATA_DIR + "/known_hosts" @@ -172,7 +174,12 @@ WATCHER_GROUP_INSTANCE_STATUS_FILE = DATA_DIR + "/watcher.%s.instance-status" #: File containing Unix timestamp until which watcher should be paused WATCHER_PAUSEFILE = DATA_DIR + "/watcher.pause" -ALL_CERT_FILES = frozenset([NODED_CERT_FILE, RAPI_CERT_FILE]) +ALL_CERT_FILES = frozenset([ + NODED_CERT_FILE, + RAPI_CERT_FILE, + SPICE_CERT_FILE, + SPICE_CACERT_FILE, + ]) MASTER_SOCKET = SOCKET_DIR + "/ganeti-master" @@ -679,6 +686,7 @@ HV_KVM_SPICE_JPEG_IMG_COMPR = "spice_jpeg_wan_compression" HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR = "spice_zlib_glz_wan_compression" HV_KVM_SPICE_STREAMING_VIDEO_DETECTION = "spice_streaming_video" HV_KVM_SPICE_AUDIO_COMPR = "spice_playback_compression" +HV_KVM_SPICE_USE_TLS = "spice_use_tls" HV_ACPI = "acpi" HV_PAE = "pae" HV_USE_BOOTLOADER = "use_bootloader" @@ -730,6 +738,7 @@ HVS_PARAMETER_TYPES = { HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR: VTYPE_STRING, HV_KVM_SPICE_STREAMING_VIDEO_DETECTION: VTYPE_STRING, HV_KVM_SPICE_AUDIO_COMPR: VTYPE_BOOL, + HV_KVM_SPICE_USE_TLS: VTYPE_BOOL, HV_ACPI: VTYPE_BOOL, HV_PAE: VTYPE_BOOL, HV_USE_BOOTLOADER: VTYPE_BOOL, @@ -1355,6 +1364,7 @@ HVC_DEFAULTS = { HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR: "", HV_KVM_SPICE_STREAMING_VIDEO_DETECTION: "", HV_KVM_SPICE_AUDIO_COMPR: True, + HV_KVM_SPICE_USE_TLS: False, 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 15358a683ed67e0e76313111666b420c06668b6d..754efb4d79e3ed96cb4ca3856426b966ac30057e 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -432,6 +432,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): hv_base.ParamInSet(False, constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS), constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK, + constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_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, @@ -1030,7 +1031,15 @@ class KVMHypervisor(hv_base.BaseHypervisor): # ValidateParameters checked it. spice_address = spice_bind - spice_arg = "addr=%s,port=%s" % (spice_address, instance.network_port) + spice_arg = "addr=%s" % spice_address + if hvp[constants.HV_KVM_SPICE_USE_TLS]: + spice_arg = "%s,tls-port=%s,x509-cacert-file=%s" % (spice_arg, + instance.network_port, constants.SPICE_CACERT_FILE) + spice_arg = "%s,x509-key-file=%s,x509-cert-file=%s" % (spice_arg, + constants.SPICE_CERT_FILE, constants.SPICE_CERT_FILE) + else: + spice_arg = "%s,port=%s" % (spice_arg, instance.network_port) + if not hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]: spice_arg = "%s,disable-ticketing" % spice_arg @@ -1651,6 +1660,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): constants.HV_KVM_SPICE_JPEG_IMG_COMPR, constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR, constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION, + constants.HV_KVM_SPICE_USE_TLS, ]) for param in spice_additional_params: if hvparams[param]: diff --git a/lib/tools/ensure_dirs.py b/lib/tools/ensure_dirs.py index 7abcce2a2bcf556326fd9b8df9663bac52a015b1..3d65c8c699a10d199151a35a60751e51c262ba9d 100644 --- a/lib/tools/ensure_dirs.py +++ b/lib/tools/ensure_dirs.py @@ -209,6 +209,10 @@ def GetPaths(): getent.masterd_gid, False), (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid, getent.masterd_gid, False), + (constants.SPICE_CERT_FILE, FILE, 0440, getent.noded_uid, + getent.masterd_gid, False), + (constants.SPICE_CACERT_FILE, FILE, 0440, getent.noded_uid, + getent.masterd_gid, False), (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid, getent.masterd_gid, False), ]