Expose a get_spice_console RPC API method
To mirror the existing get_vnc_console RPC API method, expose a new get_spice_console RPC API method. The only console type supported currently is 'spice-html5' which is equivalent to 'novnc' Blueprint: libvirt-spice Change-Id: Iab9d3dfc3564a122a8cd2b53d34fdcc725bfa29b Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
d597993a07
commit
518bdb5aba
@ -0,0 +1,5 @@
|
||||
{
|
||||
"os-getSPICEConsole": {
|
||||
"type": "spice-html5"
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<os-getSPICEConsole type="spice-html5" />
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"console": {
|
||||
"type": "spice-html5",
|
||||
"url": "http://example.com:6080/spice_auto.html?token=f9906a48-b71e-4f18-baca-c987da3ebdb3&title=dafa(75ecef58-3b8e-4659-ab3b-5501454188e9)"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<console>
|
||||
<type>spice-html5</type>
|
||||
<url>http://example.com:6080/spice_auto.html?token=f9906a48-b71e-4f18-baca-c987da3ebdb3</url>
|
||||
</console>
|
@ -53,10 +53,33 @@ class ConsolesController(wsgi.Controller):
|
||||
|
||||
return {'console': {'type': console_type, 'url': output['url']}}
|
||||
|
||||
@wsgi.action('os-getSPICEConsole')
|
||||
def get_spice_console(self, req, id, body):
|
||||
"""Get text console output."""
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
||||
# If type is not supplied or unknown, get_spice_console below will cope
|
||||
console_type = body['os-getSPICEConsole'].get('type')
|
||||
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
output = self.compute_api.get_spice_console(context,
|
||||
instance,
|
||||
console_type)
|
||||
except exception.InstanceNotFound as e:
|
||||
raise webob.exc.HTTPNotFound(explanation=unicode(e))
|
||||
except exception.InstanceNotReady as e:
|
||||
raise webob.exc.HTTPConflict(explanation=unicode(e))
|
||||
|
||||
return {'console': {'type': console_type, 'url': output['url']}}
|
||||
|
||||
def get_actions(self):
|
||||
"""Return the actions the extension adds, as required by contract."""
|
||||
actions = [extensions.ActionExtension("servers", "os-getVNCConsole",
|
||||
self.get_vnc_console)]
|
||||
self.get_vnc_console),
|
||||
extensions.ActionExtension("servers", "os-getSPICEConsole",
|
||||
self.get_spice_console)]
|
||||
return actions
|
||||
|
||||
|
||||
|
@ -2030,6 +2030,29 @@ class API(base.Base):
|
||||
instance=instance, console_type=console_type)
|
||||
return connect_info
|
||||
|
||||
@wrap_check_policy
|
||||
def get_spice_console(self, context, instance, console_type):
|
||||
"""Get a url to an instance Console."""
|
||||
if not instance['host']:
|
||||
raise exception.InstanceNotReady(instance_id=instance['uuid'])
|
||||
|
||||
connect_info = self.compute_rpcapi.get_spice_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type, connect_info['host'],
|
||||
connect_info['port'], connect_info['internal_access_path'])
|
||||
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
def get_spice_connect_info(self, context, instance, console_type):
|
||||
"""Used in a child cell to get console info."""
|
||||
if not instance['host']:
|
||||
raise exception.InstanceNotReady(instance_id=instance['uuid'])
|
||||
connect_info = self.compute_rpcapi.get_spice_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
return connect_info
|
||||
|
||||
@wrap_check_policy
|
||||
def get_console_output(self, context, instance, tail_length=None):
|
||||
"""Get console output for an instance."""
|
||||
|
@ -439,6 +439,21 @@ class ComputeCellsAPI(compute_api.API):
|
||||
connect_info['port'], connect_info['internal_access_path'])
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@wrap_check_policy
|
||||
@validate_cell
|
||||
def get_spice_console(self, context, instance, console_type):
|
||||
"""Get a url to a SPICE Console."""
|
||||
if not instance['host']:
|
||||
raise exception.InstanceNotReady(instance_id=instance['uuid'])
|
||||
|
||||
connect_info = self._call_to_cells(context, instance,
|
||||
'get_spice_connect_info', console_type)
|
||||
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type, connect_info['host'],
|
||||
connect_info['port'], connect_info['internal_access_path'])
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@validate_cell
|
||||
def get_console_output(self, context, instance, *args, **kwargs):
|
||||
"""Get console output for an an instance."""
|
||||
|
@ -293,7 +293,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
|
||||
class ComputeManager(manager.SchedulerDependentManager):
|
||||
"""Manages the running instances from creation to destruction."""
|
||||
|
||||
RPC_API_VERSION = '2.23'
|
||||
RPC_API_VERSION = '2.24'
|
||||
|
||||
def __init__(self, compute_driver=None, *args, **kwargs):
|
||||
"""Load configuration options and connect to the hypervisor."""
|
||||
@ -2387,6 +2387,9 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
LOG.debug(_("Getting vnc console"), instance=instance)
|
||||
token = str(uuid.uuid4())
|
||||
|
||||
if not CONF.vnc_enabled:
|
||||
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
||||
|
||||
if console_type == 'novnc':
|
||||
# For essex, novncproxy_base_url must include the full path
|
||||
# including the html file (like http://myhost/vnc_auto.html)
|
||||
@ -2404,6 +2407,33 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
|
||||
return connect_info
|
||||
|
||||
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
|
||||
@wrap_instance_fault
|
||||
def get_spice_console(self, context, console_type, instance):
|
||||
"""Return connection information for a spice console."""
|
||||
context = context.elevated()
|
||||
LOG.debug(_("Getting spice console"), instance=instance)
|
||||
token = str(uuid.uuid4())
|
||||
|
||||
if not CONF.spice.enabled:
|
||||
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
||||
|
||||
if console_type == 'spice-html5':
|
||||
# For essex, spicehtml5proxy_base_url must include the full path
|
||||
# including the html file (like http://myhost/spice_auto.html)
|
||||
access_url = '%s?token=%s' % (CONF.spice.html5proxy_base_url,
|
||||
token)
|
||||
else:
|
||||
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
||||
|
||||
# Retrieve connect info from driver, and then decorate with our
|
||||
# access info token
|
||||
connect_info = self.driver.get_spice_console(instance)
|
||||
connect_info['token'] = token
|
||||
connect_info['access_url'] = access_url
|
||||
|
||||
return connect_info
|
||||
|
||||
def _attach_volume_boot(self, context, instance, volume, mountpoint):
|
||||
"""Attach a volume to an instance at boot time. So actual attach
|
||||
is done by instance creation"""
|
||||
|
@ -158,6 +158,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
2.22 - Add recreate, on_shared_storage and host arguments to
|
||||
rebuild_instance()
|
||||
2.23 - Remove network_info from reboot_instance
|
||||
2.24 - Added get_spice_console method
|
||||
'''
|
||||
|
||||
#
|
||||
@ -295,6 +296,13 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
||||
instance=instance_p, console_type=console_type),
|
||||
topic=_compute_topic(self.topic, ctxt, None, instance))
|
||||
|
||||
def get_spice_console(self, ctxt, instance, console_type):
|
||||
instance_p = jsonutils.to_primitive(instance)
|
||||
return self.call(ctxt, self.make_msg('get_spice_console',
|
||||
instance=instance_p, console_type=console_type),
|
||||
topic=_compute_topic(self.topic, ctxt, None, instance),
|
||||
version='2.24')
|
||||
|
||||
def host_maintenance_mode(self, ctxt, host_param, mode, host):
|
||||
'''Set host maintenance mode
|
||||
|
||||
|
@ -26,19 +26,36 @@ def fake_get_vnc_console(self, _context, _instance, _console_type):
|
||||
return {'url': 'http://fake'}
|
||||
|
||||
|
||||
def fake_get_spice_console(self, _context, _instance, _console_type):
|
||||
return {'url': 'http://fake'}
|
||||
|
||||
|
||||
def fake_get_vnc_console_invalid_type(self, _context,
|
||||
_instance, _console_type):
|
||||
raise exception.ConsoleTypeInvalid(console_type=_console_type)
|
||||
|
||||
|
||||
def fake_get_spice_console_invalid_type(self, _context,
|
||||
_instance, _console_type):
|
||||
raise exception.ConsoleTypeInvalid(console_type=_console_type)
|
||||
|
||||
|
||||
def fake_get_vnc_console_not_ready(self, _context, instance, _console_type):
|
||||
raise exception.InstanceNotReady(instance_id=instance["uuid"])
|
||||
|
||||
|
||||
def fake_get_spice_console_not_ready(self, _context, instance, _console_type):
|
||||
raise exception.InstanceNotReady(instance_id=instance["uuid"])
|
||||
|
||||
|
||||
def fake_get_vnc_console_not_found(self, _context, instance, _console_type):
|
||||
raise exception.InstanceNotFound(instance_id=instance["uuid"])
|
||||
|
||||
|
||||
def fake_get_spice_console_not_found(self, _context, instance, _console_type):
|
||||
raise exception.InstanceNotFound(instance_id=instance["uuid"])
|
||||
|
||||
|
||||
def fake_get(self, context, instance_uuid):
|
||||
return {'uuid': instance_uuid}
|
||||
|
||||
@ -53,6 +70,8 @@ class ConsolesExtensionTest(test.TestCase):
|
||||
super(ConsolesExtensionTest, self).setUp()
|
||||
self.stubs.Set(compute_api.API, 'get_vnc_console',
|
||||
fake_get_vnc_console)
|
||||
self.stubs.Set(compute_api.API, 'get_spice_console',
|
||||
fake_get_spice_console)
|
||||
self.stubs.Set(compute_api.API, 'get', fake_get)
|
||||
self.flags(
|
||||
osapi_compute_extension=[
|
||||
@ -132,3 +151,76 @@ class ConsolesExtensionTest(test.TestCase):
|
||||
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
||||
def test_get_spice_console(self):
|
||||
body = {'os-getSPICEConsole': {'type': 'spice-html5'}}
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
output = jsonutils.loads(res.body)
|
||||
self.assertEqual(res.status_int, 200)
|
||||
self.assertEqual(output,
|
||||
{u'console': {u'url': u'http://fake', u'type': u'spice-html5'}})
|
||||
|
||||
def test_get_spice_console_not_ready(self):
|
||||
self.stubs.Set(compute_api.API, 'get_spice_console',
|
||||
fake_get_spice_console_not_ready)
|
||||
body = {'os-getSPICEConsole': {'type': 'spice-html5'}}
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
output = jsonutils.loads(res.body)
|
||||
self.assertEqual(res.status_int, 409)
|
||||
|
||||
def test_get_spice_console_no_type(self):
|
||||
self.stubs.Set(compute_api.API, 'get_spice_console',
|
||||
fake_get_spice_console_invalid_type)
|
||||
body = {'os-getSPICEConsole': {}}
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
||||
def test_get_spice_console_no_instance(self):
|
||||
self.stubs.Set(compute_api.API, 'get', fake_get_not_found)
|
||||
body = {'os-getSPICEConsole': {'type': 'spice-html5'}}
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_get_spice_console_no_instance_on_console_get(self):
|
||||
self.stubs.Set(compute_api.API, 'get_spice_console',
|
||||
fake_get_spice_console_not_found)
|
||||
body = {'os-getSPICEConsole': {'type': 'spice-html5'}}
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_get_spice_console_invalid_type(self):
|
||||
body = {'os-getSPICEConsole': {'type': 'invalid'}}
|
||||
self.stubs.Set(compute_api.API, 'get_spice_console',
|
||||
fake_get_spice_console_invalid_type)
|
||||
req = webob.Request.blank('/v2/fake/servers/1/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
@ -1335,6 +1335,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
|
||||
def test_novnc_vnc_console(self):
|
||||
# Make sure we can a vnc console for an instance.
|
||||
self.flags(vnc_enabled=True)
|
||||
self.flags(enabled=False, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
@ -1347,6 +1350,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
|
||||
def test_xvpvnc_vnc_console(self):
|
||||
# Make sure we can a vnc console for an instance.
|
||||
self.flags(vnc_enabled=True)
|
||||
self.flags(enabled=False, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
@ -1357,6 +1363,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
|
||||
def test_invalid_vnc_console_type(self):
|
||||
# Raise useful error if console type is an unrecognised string.
|
||||
self.flags(vnc_enabled=True)
|
||||
self.flags(enabled=False, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
@ -1367,6 +1376,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
|
||||
def test_missing_vnc_console_type(self):
|
||||
# Raise useful error is console type is None.
|
||||
self.flags(vnc_enabled=True)
|
||||
self.flags(enabled=False, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
@ -1375,6 +1387,47 @@ class ComputeTestCase(BaseTestCase):
|
||||
self.context, None, instance=instance)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_spicehtml5_spice_console(self):
|
||||
# Make sure we can a spice console for an instance.
|
||||
self.flags(vnc_enabled=False)
|
||||
self.flags(enabled=True, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
# Try with the full instance
|
||||
console = self.compute.get_spice_console(self.context, 'spice-html5',
|
||||
instance=instance)
|
||||
self.assert_(console)
|
||||
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_invalid_spice_console_type(self):
|
||||
# Raise useful error if console type is an unrecognised string
|
||||
self.flags(vnc_enabled=False)
|
||||
self.flags(enabled=True, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
self.assertRaises(exception.ConsoleTypeInvalid,
|
||||
self.compute.get_spice_console,
|
||||
self.context, 'invalid', instance=instance)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_missing_spice_console_type(self):
|
||||
# Raise useful error is console type is None
|
||||
self.flags(vnc_enabled=False)
|
||||
self.flags(enabled=True, group='spice')
|
||||
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
self.assertRaises(exception.ConsoleTypeInvalid,
|
||||
self.compute.get_spice_console,
|
||||
self.context, None, instance=instance)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_diagnostics(self):
|
||||
# Make sure we can get diagnostics for an instance.
|
||||
expected_diagnostic = {'cpu0_time': 17300000000,
|
||||
@ -5512,6 +5565,50 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
|
||||
db.instance_destroy(self.context, instance['uuid'])
|
||||
|
||||
def test_spice_console(self):
|
||||
# Make sure we can a spice console for an instance.
|
||||
|
||||
fake_instance = {'uuid': 'fake_uuid',
|
||||
'host': 'fake_compute_host'}
|
||||
fake_console_type = "spice-html5"
|
||||
fake_connect_info = {'token': 'fake_token',
|
||||
'console_type': fake_console_type,
|
||||
'host': 'fake_console_host',
|
||||
'port': 'fake_console_port',
|
||||
'internal_access_path': 'fake_access_path'}
|
||||
fake_connect_info2 = copy.deepcopy(fake_connect_info)
|
||||
fake_connect_info2['access_url'] = 'fake_console_url'
|
||||
|
||||
self.mox.StubOutWithMock(rpc, 'call')
|
||||
|
||||
rpc_msg1 = {'method': 'get_spice_console',
|
||||
'args': {'instance': fake_instance,
|
||||
'console_type': fake_console_type},
|
||||
'version': '2.24'}
|
||||
rpc_msg2 = {'method': 'authorize_console',
|
||||
'args': fake_connect_info,
|
||||
'version': '1.0'}
|
||||
|
||||
rpc.call(self.context, 'compute.%s' % fake_instance['host'],
|
||||
rpc_msg1, None).AndReturn(fake_connect_info2)
|
||||
rpc.call(self.context, CONF.consoleauth_topic,
|
||||
rpc_msg2, None).AndReturn(None)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
console = self.compute_api.get_spice_console(self.context,
|
||||
fake_instance, fake_console_type)
|
||||
self.assertEqual(console, {'url': 'fake_console_url'})
|
||||
|
||||
def test_get_spice_console_no_host(self):
|
||||
instance = self._create_fake_instance(params={'host': ''})
|
||||
|
||||
self.assertRaises(exception.InstanceNotReady,
|
||||
self.compute_api.get_spice_console,
|
||||
self.context, instance, 'spice')
|
||||
|
||||
db.instance_destroy(self.context, instance['uuid'])
|
||||
|
||||
def test_get_backdoor_port(self):
|
||||
# Test api call to get backdoor_port.
|
||||
fake_backdoor_port = 59697
|
||||
|
@ -165,6 +165,11 @@ class ComputeRpcAPITestCase(test.TestCase):
|
||||
self._test_compute_api('get_vnc_console', 'call',
|
||||
instance=self.fake_instance, console_type='type')
|
||||
|
||||
def test_get_spice_console(self):
|
||||
self._test_compute_api('get_spice_console', 'call',
|
||||
instance=self.fake_instance, console_type='type',
|
||||
version='2.24')
|
||||
|
||||
def test_host_maintenance_mode(self):
|
||||
self._test_compute_api('host_maintenance_mode', 'call',
|
||||
host_param='param', mode='mode', host='host')
|
||||
|
@ -42,6 +42,7 @@ policy_data = """
|
||||
"compute:unlock": "",
|
||||
|
||||
"compute:get_vnc_console": "",
|
||||
"compute:get_spice_console": "",
|
||||
"compute:get_console_output": "",
|
||||
|
||||
"compute:associate_floating_ip": "",
|
||||
|
@ -414,6 +414,7 @@ class Domain(object):
|
||||
<input type='tablet' bus='usb'/>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes'/>
|
||||
<graphics type='spice' port='-1' autoport='yes'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02'
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"os-getSPICEConsole": {
|
||||
"type": "spice-html5"
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<os-getSPICEConsole>
|
||||
<type>spice-html5</type>
|
||||
</os-getSPICEConsole>
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"console": {
|
||||
"type": "spice-html5",
|
||||
"url":"%(url)s"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<console>
|
||||
<type>spice-html5</type>
|
||||
<url>%(url)s</url>
|
||||
</console>
|
@ -2116,6 +2116,11 @@ class ConsolesSampleJsonTests(ServersSampleBase):
|
||||
extension_name = ("nova.api.openstack.compute.contrib"
|
||||
".consoles.Consoles")
|
||||
|
||||
def setUp(self):
|
||||
super(ConsolesSampleJsonTests, self).setUp()
|
||||
self.flags(vnc_enabled=True)
|
||||
self.flags(enabled=True, group='spice')
|
||||
|
||||
def test_get_vnc_console(self):
|
||||
uuid = self._post_server()
|
||||
response = self._do_post('servers/%s/action' % uuid,
|
||||
@ -2128,6 +2133,18 @@ class ConsolesSampleJsonTests(ServersSampleBase):
|
||||
return self._verify_response('get-vnc-console-post-resp',
|
||||
subs, response)
|
||||
|
||||
def test_get_spice_console(self):
|
||||
uuid = self._post_server()
|
||||
response = self._do_post('servers/%s/action' % uuid,
|
||||
'get-spice-console-post-req',
|
||||
{'action': 'os-getSPICEConsole'})
|
||||
self.assertEqual(response.status, 200)
|
||||
subs = self._get_regexes()
|
||||
subs["url"] = \
|
||||
"((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)"
|
||||
return self._verify_response('get-spice-console-post-resp',
|
||||
subs, response)
|
||||
|
||||
|
||||
class ConsolesSampleXmlTests(ConsolesSampleJsonTests):
|
||||
ctype = 'xml'
|
||||
|
@ -53,6 +53,7 @@ def get_vm_xml(name="testname", uuid=None, source_type='file',
|
||||
</interface>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='5901' autoport='yes' keymap='en-us'/>
|
||||
<graphics type='spice' port='5901' autoport='yes' keymap='en-us'/>
|
||||
</devices>
|
||||
</domain>''' % {'name': name,
|
||||
'uuid_tag': uuid_tag,
|
||||
|
Loading…
Reference in New Issue
Block a user