console: add typed console objects
Adds typed console objects used by virt driver API to return information about consoles. Also updates virt drivers to use them. Closes-Bug: #1361611 Change-Id: I8f6a857b88659ee30b4aa1a25ac52d7e01156a68
This commit is contained in:
parent
9cf0c413d4
commit
0c3a47e573
@ -4233,9 +4233,8 @@ class ComputeManager(manager.Manager):
|
||||
try:
|
||||
# Retrieve connect info from driver, and then decorate with our
|
||||
# access info token
|
||||
connect_info = self.driver.get_vnc_console(context, instance)
|
||||
connect_info['token'] = token
|
||||
connect_info['access_url'] = access_url
|
||||
console = self.driver.get_vnc_console(context, instance)
|
||||
connect_info = console.get_connection_info(token, access_url)
|
||||
except exception.InstanceNotFound:
|
||||
if instance['vm_state'] != vm_states.BUILDING:
|
||||
raise
|
||||
@ -4270,9 +4269,8 @@ class ComputeManager(manager.Manager):
|
||||
try:
|
||||
# Retrieve connect info from driver, and then decorate with our
|
||||
# access info token
|
||||
connect_info = self.driver.get_spice_console(context, instance)
|
||||
connect_info['token'] = token
|
||||
connect_info['access_url'] = access_url
|
||||
console = self.driver.get_spice_console(context, instance)
|
||||
connect_info = console.get_connection_info(token, access_url)
|
||||
except exception.InstanceNotFound:
|
||||
if instance['vm_state'] != vm_states.BUILDING:
|
||||
raise
|
||||
@ -4306,9 +4304,8 @@ class ComputeManager(manager.Manager):
|
||||
try:
|
||||
# Retrieve connect info from driver, and then decorate with our
|
||||
# access info token
|
||||
connect_info = self.driver.get_rdp_console(context, instance)
|
||||
connect_info['token'] = token
|
||||
connect_info['access_url'] = access_url
|
||||
console = self.driver.get_rdp_console(context, instance)
|
||||
connect_info = console.get_connection_info(token, access_url)
|
||||
except exception.InstanceNotFound:
|
||||
if instance['vm_state'] != vm_states.BUILDING:
|
||||
raise
|
||||
@ -4330,7 +4327,7 @@ class ComputeManager(manager.Manager):
|
||||
else:
|
||||
console_info = self.driver.get_vnc_console(ctxt, instance)
|
||||
|
||||
return console_info['port'] == port
|
||||
return console_info.port == port
|
||||
|
||||
@object_compat
|
||||
@wrap_exception()
|
||||
|
42
nova/console/type.py
Normal file
42
nova/console/type.py
Normal file
@ -0,0 +1,42 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class Console(object):
|
||||
def __init__(self, host, port, internal_access_path=None):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.internal_access_path = internal_access_path
|
||||
|
||||
def get_connection_info(self, token, access_url):
|
||||
"""Returns an unreferenced dict with connection information."""
|
||||
|
||||
ret = dict(self.__dict__)
|
||||
ret['token'] = token
|
||||
ret['access_url'] = access_url
|
||||
return ret
|
||||
|
||||
|
||||
class ConsoleVNC(Console):
|
||||
pass
|
||||
|
||||
|
||||
class ConsoleRDP(Console):
|
||||
pass
|
||||
|
||||
|
||||
class ConsoleSpice(Console):
|
||||
def __init__(self, host, port, tlsPort, internal_access_path=None):
|
||||
super(ConsoleSpice, self).__init__(host, port, internal_access_path)
|
||||
self.tlsPort = tlsPort
|
@ -48,6 +48,7 @@ from nova.compute import task_states
|
||||
from nova.compute import utils as compute_utils
|
||||
from nova.compute import vm_states
|
||||
from nova.conductor import manager as conductor_manager
|
||||
from nova.console import type as ctype
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
@ -3091,13 +3092,13 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance = self._create_fake_instance_obj()
|
||||
|
||||
def fake_driver_get_console(*args, **kwargs):
|
||||
return {'host': "fake_host", 'port': "5900",
|
||||
'internal_access_path': None}
|
||||
return ctype.ConsoleVNC(host="fake_host", port=5900)
|
||||
|
||||
self.stubs.Set(self.compute.driver, "get_vnc_console",
|
||||
fake_driver_get_console)
|
||||
|
||||
self.assertTrue(self.compute.validate_console_port(
|
||||
context=self.context, instance=instance, port="5900",
|
||||
context=self.context, instance=instance, port=5900,
|
||||
console_type="novnc"))
|
||||
|
||||
def test_validate_console_port_spice(self):
|
||||
@ -3106,13 +3107,13 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance = self._create_fake_instance_obj()
|
||||
|
||||
def fake_driver_get_console(*args, **kwargs):
|
||||
return {'host': "fake_host", 'port': "5900",
|
||||
'internal_access_path': None}
|
||||
return ctype.ConsoleSpice(host="fake_host", port=5900, tlsPort=88)
|
||||
|
||||
self.stubs.Set(self.compute.driver, "get_spice_console",
|
||||
fake_driver_get_console)
|
||||
|
||||
self.assertTrue(self.compute.validate_console_port(
|
||||
context=self.context, instance=instance, port="5900",
|
||||
context=self.context, instance=instance, port=5900,
|
||||
console_type="spice-html5"))
|
||||
|
||||
def test_validate_console_port_rdp(self):
|
||||
@ -3120,13 +3121,13 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance = self._create_fake_instance_obj()
|
||||
|
||||
def fake_driver_get_console(*args, **kwargs):
|
||||
return {'host': "fake_host", 'port': "5900",
|
||||
'internal_access_path': None}
|
||||
return ctype.ConsoleRDP(host="fake_host", port=5900)
|
||||
|
||||
self.stubs.Set(self.compute.driver, "get_rdp_console",
|
||||
fake_driver_get_console)
|
||||
|
||||
self.assertTrue(self.compute.validate_console_port(
|
||||
context=self.context, instance=instance, port="5900",
|
||||
context=self.context, instance=instance, port=5900,
|
||||
console_type="rdp-html5"))
|
||||
|
||||
def test_validate_console_port_wrong_port(self):
|
||||
@ -3135,8 +3136,8 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance = self._create_fake_instance_obj()
|
||||
|
||||
def fake_driver_get_console(*args, **kwargs):
|
||||
return {'host': "fake_host", 'port': "5900",
|
||||
'internal_access_path': None}
|
||||
return ctype.ConsoleSpice(host="fake_host", port=5900, tlsPort=88)
|
||||
|
||||
self.stubs.Set(self.compute.driver, "get_vnc_console",
|
||||
fake_driver_get_console)
|
||||
|
||||
|
59
nova/tests/console/test_type.py
Normal file
59
nova/tests/console/test_type.py
Normal file
@ -0,0 +1,59 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from nova.console import type as ctype
|
||||
from nova import test
|
||||
|
||||
|
||||
class TypeTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TypeTestCase, self).setUp()
|
||||
|
||||
def test_console(self):
|
||||
c = ctype.Console(host='127.0.0.1', port=8945)
|
||||
|
||||
self.assertTrue(hasattr(c, 'host'))
|
||||
self.assertTrue(hasattr(c, 'port'))
|
||||
self.assertTrue(hasattr(c, 'internal_access_path'))
|
||||
|
||||
self.assertEqual('127.0.0.1', c.host)
|
||||
self.assertEqual(8945, c.port)
|
||||
self.assertIsNone(c.internal_access_path)
|
||||
|
||||
self.assertEqual({
|
||||
'host': '127.0.0.1',
|
||||
'port': 8945,
|
||||
'internal_access_path': None,
|
||||
'token': 'a-token',
|
||||
'access_url': 'an-url'},
|
||||
c.get_connection_info('a-token', 'an-url'))
|
||||
|
||||
def test_console_vnc(self):
|
||||
c = ctype.ConsoleVNC(host='127.0.0.1', port=8945)
|
||||
|
||||
self.assertIsInstance(c, ctype.Console)
|
||||
|
||||
def test_console_rdp(self):
|
||||
c = ctype.ConsoleRDP(host='127.0.0.1', port=8945)
|
||||
|
||||
self.assertIsInstance(c, ctype.Console)
|
||||
|
||||
def test_console_spice(self):
|
||||
c = ctype.ConsoleSpice(host='127.0.0.1', port=8945, tlsPort=6547)
|
||||
|
||||
self.assertIsInstance(c, ctype.Console)
|
||||
self.assertEqual(6547, c.tlsPort)
|
||||
self.assertEqual(
|
||||
6547, c.get_connection_info('a-token', 'an-url')['tlsPort'])
|
@ -1832,9 +1832,9 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase,
|
||||
connect_info = self._conn.get_rdp_console(self._context, instance)
|
||||
self._mox.VerifyAll()
|
||||
|
||||
self.assertEqual(CONF.my_ip, connect_info['host'])
|
||||
self.assertEqual(fake_port, connect_info['port'])
|
||||
self.assertEqual(fake_vm_id, connect_info['internal_access_path'])
|
||||
self.assertEqual(CONF.my_ip, connect_info.host)
|
||||
self.assertEqual(fake_port, connect_info.port)
|
||||
self.assertEqual(fake_vm_id, connect_info.internal_access_path)
|
||||
|
||||
|
||||
class VolumeOpsTestCase(HyperVAPIBaseTestCase):
|
||||
|
@ -8294,7 +8294,7 @@ Active: 8381604 kB
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
vnc_dict = conn.get_vnc_console(self.context, instance)
|
||||
self.assertEqual(vnc_dict['port'], '5900')
|
||||
self.assertEqual(vnc_dict.port, '5900')
|
||||
|
||||
def test_get_vnc_console_unavailable(self):
|
||||
instance = self.create_instance_obj(self.context)
|
||||
@ -8334,7 +8334,7 @@ Active: 8381604 kB
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
spice_dict = conn.get_spice_console(self.context, instance)
|
||||
self.assertEqual(spice_dict['port'], '5950')
|
||||
self.assertEqual(spice_dict.port, '5950')
|
||||
|
||||
def test_get_spice_console_unavailable(self):
|
||||
instance = self.create_instance_obj(self.context)
|
||||
|
@ -22,6 +22,7 @@ import netaddr
|
||||
import six
|
||||
|
||||
from nova.compute import manager
|
||||
from nova.console import type as ctype
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.openstack.common import importutils
|
||||
@ -539,27 +540,20 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
|
||||
def test_get_vnc_console(self):
|
||||
instance, network_info = self._get_running_instance(obj=True)
|
||||
vnc_console = self.connection.get_vnc_console(self.ctxt, instance)
|
||||
self.assertIn('internal_access_path', vnc_console)
|
||||
self.assertIn('host', vnc_console)
|
||||
self.assertIn('port', vnc_console)
|
||||
self.assertIsInstance(vnc_console, ctype.ConsoleVNC)
|
||||
|
||||
@catch_notimplementederror
|
||||
def test_get_spice_console(self):
|
||||
instance_ref, network_info = self._get_running_instance()
|
||||
spice_console = self.connection.get_spice_console(self.ctxt,
|
||||
instance_ref)
|
||||
self.assertIn('internal_access_path', spice_console)
|
||||
self.assertIn('host', spice_console)
|
||||
self.assertIn('port', spice_console)
|
||||
self.assertIn('tlsPort', spice_console)
|
||||
self.assertIsInstance(spice_console, ctype.ConsoleSpice)
|
||||
|
||||
@catch_notimplementederror
|
||||
def test_get_rdp_console(self):
|
||||
instance_ref, network_info = self._get_running_instance()
|
||||
rdp_console = self.connection.get_rdp_console(self.ctxt, instance_ref)
|
||||
self.assertIn('internal_access_path', rdp_console)
|
||||
self.assertIn('host', rdp_console)
|
||||
self.assertIn('port', rdp_console)
|
||||
self.assertIsInstance(rdp_console, ctype.ConsoleRDP)
|
||||
|
||||
@catch_notimplementederror
|
||||
def test_get_console_pool_info(self):
|
||||
|
@ -443,7 +443,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
||||
|
||||
# Note(sulo): We don't care about session id in test
|
||||
# they will always differ so strip that out
|
||||
actual_path = console['internal_access_path'].split('&')[0]
|
||||
actual_path = console.internal_access_path.split('&')[0]
|
||||
expected_path = "/console?ref=%s" % str(vm_ref)
|
||||
|
||||
self.assertEqual(expected_path, actual_path)
|
||||
@ -460,7 +460,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
||||
|
||||
# Note(sulo): We don't care about session id in test
|
||||
# they will always differ so strip that out
|
||||
actual_path = console['internal_access_path'].split('&')[0]
|
||||
actual_path = console.internal_access_path.split('&')[0]
|
||||
expected_path = "/console?ref=%s" % str(rescue_vm)
|
||||
|
||||
self.assertEqual(expected_path, actual_path)
|
||||
|
@ -373,6 +373,8 @@ class ComputeDriver(object):
|
||||
|
||||
:param context: security context
|
||||
:param instance: nova.objects.instance.Instance
|
||||
|
||||
:returns an instance of console.type.ConsoleVNC
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@ -381,6 +383,8 @@ class ComputeDriver(object):
|
||||
|
||||
:param context: security context
|
||||
:param instance: nova.objects.instance.Instance
|
||||
|
||||
:returns an instance of console.type.ConsoleSpice
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@ -389,6 +393,8 @@ class ComputeDriver(object):
|
||||
|
||||
:param context: security context
|
||||
:param instance: nova.objects.instance.Instance
|
||||
|
||||
:returns an instance of console.type.ConsoleRDP
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -29,6 +29,7 @@ from oslo.config import cfg
|
||||
|
||||
from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
from nova.console import type as ctype
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
@ -337,20 +338,20 @@ class FakeDriver(driver.ComputeDriver):
|
||||
return 'FAKE CONSOLE OUTPUT\nANOTHER\nLAST LINE'
|
||||
|
||||
def get_vnc_console(self, context, instance):
|
||||
return {'internal_access_path': 'FAKE',
|
||||
'host': 'fakevncconsole.com',
|
||||
'port': 6969}
|
||||
return ctype.ConsoleVNC(internal_access_path='FAKE',
|
||||
host='fakevncconsole.com',
|
||||
port=6969)
|
||||
|
||||
def get_spice_console(self, context, instance):
|
||||
return {'internal_access_path': 'FAKE',
|
||||
'host': 'fakespiceconsole.com',
|
||||
'port': 6969,
|
||||
'tlsPort': 6970}
|
||||
return ctype.ConsoleSpice(internal_access_path='FAKE',
|
||||
host='fakespiceconsole.com',
|
||||
port=6969,
|
||||
tlsPort=6970)
|
||||
|
||||
def get_rdp_console(self, context, instance):
|
||||
return {'internal_access_path': 'FAKE',
|
||||
'host': 'fakerdpconsole.com',
|
||||
'port': 6969}
|
||||
return ctype.ConsoleRDP(internal_access_path='FAKE',
|
||||
host='fakerdpconsole.com',
|
||||
port=6969)
|
||||
|
||||
def get_console_pool_info(self, console_type):
|
||||
return {'address': '127.0.0.1',
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.console import type as ctype
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.virt.hyperv import hostops
|
||||
from nova.virt.hyperv import utilsfactory
|
||||
@ -35,6 +36,5 @@ class RDPConsoleOps(object):
|
||||
LOG.debug("RDP console: %(host)s:%(port)s, %(vm_id)s",
|
||||
{"host": host, "port": port, "vm_id": vm_id})
|
||||
|
||||
return {'host': host,
|
||||
'port': port,
|
||||
'internal_access_path': vm_id}
|
||||
return ctype.ConsoleRDP(
|
||||
host=host, port=port, internal_access_path=vm_id)
|
||||
|
@ -56,6 +56,7 @@ from nova.compute import task_states
|
||||
from nova.compute import utils as compute_utils
|
||||
from nova.compute import vm_mode
|
||||
from nova.console import serial as serial_console
|
||||
from nova.console import type as ctype
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
@ -2652,7 +2653,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
port = get_vnc_port_for_instance(instance.name)
|
||||
host = CONF.vncserver_proxyclient_address
|
||||
|
||||
return {'host': host, 'port': port, 'internal_access_path': None}
|
||||
return ctype.ConsoleVNC(host=host, port=port)
|
||||
|
||||
def get_spice_console(self, context, instance):
|
||||
def get_spice_ports_for_instance(instance_name):
|
||||
@ -2672,8 +2673,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
ports = get_spice_ports_for_instance(instance['name'])
|
||||
host = CONF.spice.server_proxyclient_address
|
||||
|
||||
return {'host': host, 'port': ports[0],
|
||||
'tlsPort': ports[1], 'internal_access_path': None}
|
||||
return ctype.ConsoleSpice(host=host, port=ports[0], tlsPort=ports[1])
|
||||
|
||||
@staticmethod
|
||||
def _supports_direct_io(dirpath):
|
||||
|
@ -30,6 +30,7 @@ from nova import compute
|
||||
from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
from nova.compute import vm_states
|
||||
from nova.console import type as ctype
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _, _LE
|
||||
@ -1291,7 +1292,7 @@ class VMwareVMOps(object):
|
||||
"""Return connection info for a vnc console using ESX logic."""
|
||||
vnc_console = self._get_vnc_console_connection(instance)
|
||||
vnc_console['host'] = CONF.vmware.host_ip
|
||||
return vnc_console
|
||||
return ctype.ConsoleVNC(**vnc_console)
|
||||
|
||||
@staticmethod
|
||||
def _get_machine_id_str(network_info):
|
||||
|
@ -33,6 +33,7 @@ from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
from nova.compute import vm_mode
|
||||
from nova.compute import vm_states
|
||||
from nova.console import type as ctype
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
@ -1616,8 +1617,10 @@ class VMOps(object):
|
||||
path = "/console?ref=%s&session_id=%s" % (str(vm_ref), session_id)
|
||||
|
||||
# NOTE: XS5.6sp2+ use http over port 80 for xenapi com
|
||||
return {'host': CONF.vncserver_proxyclient_address, 'port': 80,
|
||||
'internal_access_path': path}
|
||||
return ctype.ConsoleVNC(
|
||||
host=CONF.vncserver_proxyclient_address,
|
||||
port=80,
|
||||
internal_access_path=path)
|
||||
|
||||
def _vif_xenstore_data(self, vif):
|
||||
"""convert a network info vif to injectable instance data."""
|
||||
|
Loading…
Reference in New Issue
Block a user