diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index 3d6d68533b0ebbd6f184f0a78899c9b6e9630117..84cc869af243e8c9d76bb5521f1b94d345d49d5c 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -934,6 +934,9 @@ def _DoConsole(console, show_command, cluster_name, feedback_fn=ToStdout, " URL <vnc://%s:%s/>", console.instance, console.host, console.port, console.display, console.host, console.port) + elif console.kind == constants.CONS_SPICE: + feedback_fn("Instance %s has SPICE listening on %s:%s", console.instance, + console.host, console.port) elif console.kind == constants.CONS_SSH: # Convert to string if not already one if isinstance(console.command, basestring): diff --git a/lib/constants.py b/lib/constants.py index 92c3523b72eefe507d6da3e2676129f5a061de16..80d32fd4fa515d129b9713db7fe09e9ac9be2b46 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -255,11 +255,14 @@ CONS_SSH = "ssh" #: Console as VNC server CONS_VNC = "vnc" +#: Console as SPICE server +CONS_SPICE = "spice" + #: Display a message for console access CONS_MESSAGE = "msg" #: All console types -CONS_ALL = frozenset([CONS_SSH, CONS_VNC, CONS_MESSAGE]) +CONS_ALL = frozenset([CONS_SSH, CONS_VNC, CONS_SPICE, CONS_MESSAGE]) # For RSA keys more bits are better, but they also make operations more # expensive. NIST SP 800-131 recommends a minimum of 2048 bits from the year diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 19a9bf9480f8d4c61d346a2433a853c48ea1c1a5..8334dede518720a72307c4395021ba4199d60188 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -1527,6 +1527,13 @@ class KVMHypervisor(hv_base.BaseHypervisor): port=instance.network_port, display=display) + spice_bind = hvparams[constants.HV_KVM_SPICE_BIND] + if spice_bind: + return objects.InstanceConsole(instance=instance.name, + kind=constants.CONS_SPICE, + host=spice_bind, + port=instance.network_port) + return objects.InstanceConsole(instance=instance.name, kind=constants.CONS_MESSAGE, message=("No serial shell for instance %s" % diff --git a/lib/objects.py b/lib/objects.py index ab55b3d2acae3b7faca6e4b1f2c93b6e90bed93e..69862b606322c218a81f408d2a5b5929af08ff43 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -1523,15 +1523,20 @@ class InstanceConsole(ConfigObject): """ assert self.kind in constants.CONS_ALL, "Unknown console type" assert self.instance, "Missing instance name" - assert self.message or self.kind in [constants.CONS_SSH, constants.CONS_VNC] + assert self.message or self.kind in [constants.CONS_SSH, + constants.CONS_SPICE, + constants.CONS_VNC] assert self.host or self.kind == constants.CONS_MESSAGE assert self.port or self.kind in [constants.CONS_MESSAGE, constants.CONS_SSH] assert self.user or self.kind in [constants.CONS_MESSAGE, + constants.CONS_SPICE, constants.CONS_VNC] assert self.command or self.kind in [constants.CONS_MESSAGE, + constants.CONS_SPICE, constants.CONS_VNC] assert self.display or self.kind in [constants.CONS_MESSAGE, + constants.CONS_SPICE, constants.CONS_SSH] return True diff --git a/test/ganeti.hypervisor.hv_kvm_unittest.py b/test/ganeti.hypervisor.hv_kvm_unittest.py index 7ff3d4d2938348e863fd3f7c7e01d518b1337bf2..14ab34546910d5a76350a4c9ca9c06aecff68d1c 100755 --- a/test/ganeti.hypervisor.hv_kvm_unittest.py +++ b/test/ganeti.hypervisor.hv_kvm_unittest.py @@ -173,6 +173,7 @@ class TestConsole(unittest.TestCase): hvparams = { constants.HV_SERIAL_CONSOLE: True, constants.HV_VNC_BIND_ADDRESS: None, + constants.HV_KVM_SPICE_BIND: None, } cons = self._Test(instance, hvparams) self.assertEqual(cons.kind, constants.CONS_SSH) @@ -187,6 +188,7 @@ class TestConsole(unittest.TestCase): hvparams = { constants.HV_SERIAL_CONSOLE: False, constants.HV_VNC_BIND_ADDRESS: "192.0.2.1", + constants.HV_KVM_SPICE_BIND: None, } cons = self._Test(instance, hvparams) self.assertEqual(cons.kind, constants.CONS_VNC) @@ -194,6 +196,20 @@ class TestConsole(unittest.TestCase): self.assertEqual(cons.port, constants.VNC_BASE_PORT + 10) self.assertEqual(cons.display, 10) + def testSpice(self): + instance = objects.Instance(name="kvm.example.com", + primary_node="node7235", + network_port=11000) + hvparams = { + constants.HV_SERIAL_CONSOLE: False, + constants.HV_VNC_BIND_ADDRESS: None, + constants.HV_KVM_SPICE_BIND: "192.0.2.1", + } + cons = self._Test(instance, hvparams) + self.assertEqual(cons.kind, constants.CONS_SPICE) + self.assertEqual(cons.host, "192.0.2.1") + self.assertEqual(cons.port, 11000) + def testNoConsole(self): instance = objects.Instance(name="kvm.example.com", primary_node="node24325", @@ -201,6 +217,7 @@ class TestConsole(unittest.TestCase): hvparams = { constants.HV_SERIAL_CONSOLE: False, constants.HV_VNC_BIND_ADDRESS: None, + constants.HV_KVM_SPICE_BIND: None, } cons = self._Test(instance, hvparams) self.assertEqual(cons.kind, constants.CONS_MESSAGE)