Implements blueprint vnc-console-cleanup

* Creates a unified way to access vnc consoles for xenserver and libvirt
 * Now supports both java and websocket clients
 * Removes nova-vncproxy - a replacement version of this (nova-novncproxy) can be found as described in vncconsole.rst
 * Adds nova-xvpvncproxy, which supports a java vnc client
 * Adds api extension to access java and novnc access_urls
 * Fixes proxy server to close/shutdown sockets more cleanly
 * Address style feedback
 * Use new-style extension format
 * Fix setup.py
 * utils.gen_uuid must be wrapped like str(utils.gen_uuid()) or it can't be serialized

Change-Id: I5e42e2f160e8e3476269bd64b0e8aa77e66c918c
This commit is contained in:
Anthony Young
2011-12-22 21:39:21 +00:00
parent 34b10921b1
commit 1a195e0af3
6 changed files with 147 additions and 18 deletions

View File

@@ -44,7 +44,6 @@ from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from nova.vnc import server
from nova.objectstore import s3server
@@ -60,17 +59,12 @@ if __name__ == '__main__':
servers.append(service.WSGIService(api))
except (Exception, SystemExit):
logging.exception(_('Failed to load %s') % '%s-api' % api)
# nova-vncproxy
try:
servers.append(server.get_wsgi_server())
except (Exception, SystemExit):
logging.exception(_('Failed to load %s') % 'vncproxy-wsgi')
# nova-objectstore
try:
servers.append(s3server.get_wsgi_server())
except (Exception, SystemExit):
logging.exception(_('Failed to load %s') % 'objectstore-wsgi')
for binary in ['nova-vncproxy', 'nova-compute', 'nova-volume',
for binary in ['nova-xvpvncproxy', 'nova-compute', 'nova-volume',
'nova-network', 'nova-scheduler', 'nova-vsa']:
try:
servers.append(service.Service.create(binary=binary))

48
bin/nova-consoleauth Executable file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 Openstack, LLC.
# 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.
"""VNC Console Proxy Server."""
import eventlet
eventlet.monkey_patch()
import os
import sys
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from nova.consoleauth import manager
if __name__ == "__main__":
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
server = service.Service.create(binary='nova-consoleauth')
service.serve(server)
service.wait()

View File

@@ -16,7 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""VNC Console Proxy Server."""
"""XVP VNC Console Proxy Server."""
import eventlet
eventlet.monkey_patch()
@@ -35,7 +35,7 @@ from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from nova.vnc import server
from nova.vnc import xvp_proxy
if __name__ == "__main__":
@@ -43,7 +43,6 @@ if __name__ == "__main__":
flags.FLAGS(sys.argv)
logging.setup()
wsgi_server = server.get_wsgi_server()
server = service.Service.create(binary='nova-vncproxy')
service.serve(wsgi_server, server)
wsgi_server = xvp_proxy.get_wsgi_server()
service.serve(wsgi_server)
service.wait()

View File

@@ -696,15 +696,40 @@ class ComputeTestCase(BaseTestCase):
self.assert_(set(['token', 'host', 'port']).issubset(console.keys()))
self.compute.terminate_instance(self.context, instance['uuid'])
def test_vnc_console(self):
def test_novnc_vnc_console(self):
"""Make sure we can a vnc console for an instance."""
instance = self._create_fake_instance()
self.compute.run_instance(self.context, instance['uuid'])
console = self.compute.get_vnc_console(self.context, instance['uuid'])
console = self.compute.get_vnc_console(self.context,
instance['uuid'],
'novnc')
self.assert_(console)
self.compute.terminate_instance(self.context, instance['uuid'])
def test_xvpvnc_vnc_console(self):
"""Make sure we can a vnc console for an instance."""
instance = self._create_fake_instance()
self.compute.run_instance(self.context, instance['uuid'])
console = self.compute.get_vnc_console(self.context,
instance['uuid'],
'xvpvnc')
self.assert_(console)
self.compute.terminate_instance(self.context, instance['uuid'])
def test_invalid_vnc_console_type(self):
"""Make sure we can a vnc console for an instance."""
instance = self._create_fake_instance()
self.compute.run_instance(self.context, instance['uuid'])
self.assertRaises(exception.ConsoleTypeInvalid,
self.compute.get_vnc_console,
self.context,
instance['uuid'],
'invalid')
self.compute.terminate_instance(self.context, instance['uuid'])
def test_diagnostics(self):
"""Make sure we can get diagnostics for an instance."""
instance = self._create_fake_instance()
@@ -2831,16 +2856,20 @@ class ComputeAPITestCase(BaseTestCase):
def test_vnc_console(self):
"""Make sure we can a vnc console for an instance."""
def vnc_rpc_call_wrapper(*args, **kwargs):
return {'token': 'asdf', 'host': '0.0.0.0', 'port': 8080}
return {'token': 'asdf', 'host': '0.0.0.0',
'port': 8080, 'access_url': None,
'internal_access_path': None}
self.stubs.Set(rpc, 'call', vnc_rpc_call_wrapper)
instance = self._create_fake_instance()
console = self.compute_api.get_vnc_console(self.context, instance)
console = self.compute_api.get_vnc_console(self.context,
instance,
'novnc')
self.compute_api.delete(self.context, instance)
def test_ajax_console(self):
"""Make sure we can a vnc console for an instance."""
"""Make sure we can an ajax console for an instance."""
def ajax_rpc_call_wrapper(*args, **kwargs):
return {'token': 'asdf', 'host': '0.0.0.0', 'port': 8080}

View File

@@ -0,0 +1,59 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 OpenStack LLC.
# Administrator of the National Aeronautics and Space Administration.
# 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.
"""
Tests for Consoleauth Code.
"""
import time
from nova import context
from nova import db
from nova import flags
from nova import log as logging
from nova import test
from nova import utils
from nova.consoleauth import manager
FLAGS = flags.FLAGS
LOG = logging.getLogger('nova.tests.consoleauth')
class ConsoleauthTestCase(test.TestCase):
"""Test Case for consoleauth."""
def setUp(self):
super(ConsoleauthTestCase, self).setUp()
self.manager = utils.import_object(FLAGS.consoleauth_manager)
self.context = context.get_admin_context()
self.old_ttl = FLAGS.console_token_ttl
def tearDown(self):
super(ConsoleauthTestCase, self).tearDown()
FLAGS.console_token_ttl = self.old_ttl
def test_tokens_expire(self):
"""Test that tokens expire correctly."""
token = 'mytok'
FLAGS.console_token_ttl = 1
self.manager.authorize_console(self.context, token, 'novnc',
'127.0.0.1', 'host', '')
self.assertTrue(self.manager.check_token(self.context, token))
time.sleep(1.1)
self.assertFalse(self.manager.check_token(self.context, token))

View File

@@ -294,7 +294,7 @@ class _VirtDriverTestCase(test.TestCase):
def test_get_vnc_console(self):
instance_ref, network_info = self._get_running_instance()
vnc_console = self.connection.get_vnc_console(instance_ref)
self.assertIn('token', vnc_console)
self.assertIn('internal_access_path', vnc_console)
self.assertIn('host', vnc_console)
self.assertIn('port', vnc_console)