merge trunk

This commit is contained in:
Salvatore Orlando
2011-03-30 10:41:25 +01:00
10 changed files with 229 additions and 58 deletions

View File

@@ -14,3 +14,8 @@ CA/newcerts/*.pem
CA/private/cakey.pem
nova/vcsversion.py
*.DS_Store
.project
.pydevproject
clean.sqlite
run_tests.log
tests.sqlite

View File

@@ -12,6 +12,7 @@ Chiradeep Vittal <chiradeep@cloud.com>
Chmouel Boudjnah <chmouel@chmouel.com>
Chris Behrens <cbehrens@codestud.com>
Christian Berendt <berendt@b1-systems.de>
Chuck Short <zulcss@ubuntu.com>
Cory Wright <corywright@gmail.com>
Dan Prince <dan.prince@rackspace.com>
David Pravec <David.Pravec@danix.org>

View File

@@ -115,7 +115,7 @@ class AjaxConsoleProxy(object):
{'args': data['args'], 'last_activity': time.time()}
conn = rpc.Connection.instance(new=True)
consumer = rpc.TopicConsumer(
consumer = rpc.TopicAdapterConsumer(
connection=conn,
topic=FLAGS.ajax_console_proxy_topic)
consumer.register_callback(Callback())

View File

@@ -48,6 +48,7 @@ flags.DECLARE('auth_driver', 'nova.auth.manager')
flags.DECLARE('network_size', 'nova.network.manager')
flags.DECLARE('num_networks', 'nova.network.manager')
flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager')
flags.DEFINE_string('dnsmasq_interface', 'br0', 'Default Dnsmasq interface')
LOG = logging.getLogger('nova.dhcpbridge')
@@ -103,7 +104,8 @@ def main():
utils.default_flagfile(flagfile)
argv = FLAGS(sys.argv)
logging.setup()
interface = os.environ.get('DNSMASQ_INTERFACE', 'br0')
# check ENV first so we don't break any older deploys
interface = os.environ.get('DNSMASQ_INTERFACE', FLAGS.dnsmasq_interface)
if int(os.environ.get('TESTING', '0')):
from nova.tests import fake_flags
action = argv[1]

View File

@@ -1098,8 +1098,8 @@ def main():
script_name = argv.pop(0)
if len(argv) < 1:
print script_name + " category action [<args>]"
print "Available categories:"
for k, _ in CATEGORIES:
print _("Available categories:")
for k, _v in CATEGORIES:
print "\t%s" % k
sys.exit(2)
category = argv.pop(0)
@@ -1110,7 +1110,7 @@ def main():
actions = methods_of(command_object)
if len(argv) < 1:
print script_name + " category action [<args>]"
print "Available actions for %s category:" % category
print _("Available actions for %s category:") % category
for k, _v in actions:
print "\t%s" % k
sys.exit(2)
@@ -1122,9 +1122,12 @@ def main():
fn(*argv)
sys.exit(0)
except TypeError:
print "Possible wrong number of arguments supplied"
print _("Possible wrong number of arguments supplied")
print "%s %s: %s" % (category, action, fn.__doc__)
raise
except Exception:
print _("Command failed, please check log for more info")
raise
if __name__ == '__main__':
main()

101
bin/nova-vncproxy Executable file
View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 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
import gettext
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)
gettext.install('nova', unicode=1)
from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from nova import wsgi
from nova import version
from nova.vnc import auth
from nova.vnc import proxy
LOG = logging.getLogger('nova.vnc-proxy')
FLAGS = flags.FLAGS
flags.DEFINE_string('vncproxy_wwwroot', '/var/lib/nova/noVNC/',
'Full path to noVNC directory')
flags.DEFINE_boolean('vnc_debug', False,
'Enable debugging features, like token bypassing')
flags.DEFINE_integer('vncproxy_port', 6080,
'Port that the VNC proxy should bind to')
flags.DEFINE_string('vncproxy_host', '0.0.0.0',
'Address that the VNC proxy should bind to')
flags.DEFINE_integer('vnc_token_ttl', 300,
'How many seconds before deleting tokens')
flags.DEFINE_string('vncproxy_manager', 'nova.vnc.auth.VNCProxyAuthManager',
'Manager for vncproxy auth')
flags.DEFINE_flag(flags.HelpFlag())
flags.DEFINE_flag(flags.HelpshortFlag())
flags.DEFINE_flag(flags.HelpXMLFlag())
if __name__ == "__main__":
utils.default_flagfile()
FLAGS(sys.argv)
logging.setup()
LOG.audit(_("Starting nova-vnc-proxy node (version %s)"),
version.version_string_with_vcs())
if not (os.path.exists(FLAGS.vncproxy_wwwroot) and
os.path.exists(FLAGS.vncproxy_wwwroot + '/vnc_auto.html')):
LOG.info(_("Missing vncproxy_wwwroot (version %s)"),
FLAGS.vncproxy_wwwroot)
LOG.info(_("You need a slightly modified version of noVNC "
"to work with the nova-vnc-proxy"))
LOG.info(_("Check out the most recent nova noVNC code: %s"),
"git://github.com/sleepsonthefloor/noVNC.git")
LOG.info(_("And drop it in %s"), FLAGS.vncproxy_wwwroot)
exit(1)
app = proxy.WebsocketVNCProxy(FLAGS.vncproxy_wwwroot)
LOG.audit(_("Allowing access to the following files: %s"),
app.get_whitelist())
with_logging = auth.LoggingMiddleware(app)
if FLAGS.vnc_debug:
with_auth = proxy.DebugMiddleware(with_logging)
else:
with_auth = auth.VNCNovaAuthMiddleware(with_logging)
service.serve()
server = wsgi.Server()
server.start(with_auth, FLAGS.vncproxy_port, host=FLAGS.vncproxy_host)
server.wait()

View File

@@ -324,14 +324,11 @@ class NovaAdminClient(object):
def get_user(self, name):
"""Grab a single user by name."""
try:
return self.apiconn.get_object('DescribeUser',
{'Name': name},
UserInfo)
except boto.exception.BotoServerError, e:
if e.status == 400 and e.error_code == 'NotFound':
return None
raise
user = self.apiconn.get_object('DescribeUser',
{'Name': name},
UserInfo)
if user.username != None:
return user
def has_user(self, username):
"""Determine if user exists."""

View File

@@ -286,6 +286,16 @@ class ComputeTestCase(test.TestCase):
console = self.compute.get_ajax_console(self.context,
instance_id)
self.assert_(set(['token', 'host', 'port']).issubset(console.keys()))
self.compute.terminate_instance(self.context, instance_id)
def test_vnc_console(self):
"""Make sure we can a vnc console for an instance."""
instance_id = self._create_instance()
self.compute.run_instance(self.context, instance_id)
console = self.compute.get_vnc_console(self.context,
instance_id)
self.assert_(console)
self.compute.terminate_instance(self.context, instance_id)

View File

@@ -225,6 +225,49 @@ class LibvirtConnTestCase(test.TestCase):
self._check_xml_and_uri(instance_data, expect_kernel=True,
expect_ramdisk=True, rescue=True)
def test_lxc_container_and_uri(self):
instance_data = dict(self.test_instance)
self._check_xml_and_container(instance_data)
def _check_xml_and_container(self, instance):
user_context = context.RequestContext(project=self.project,
user=self.user)
instance_ref = db.instance_create(user_context, instance)
host = self.network.get_network_host(user_context.elevated())
network_ref = db.project_get_network(context.get_admin_context(),
self.project.id)
fixed_ip = {'address': self.test_ip,
'network_id': network_ref['id']}
ctxt = context.get_admin_context()
fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip)
db.fixed_ip_update(ctxt, self.test_ip,
{'allocated': True,
'instance_id': instance_ref['id']})
self.flags(libvirt_type='lxc')
conn = libvirt_conn.LibvirtConnection(True)
uri = conn.get_uri()
self.assertEquals(uri, 'lxc:///')
xml = conn.to_xml(instance_ref)
tree = xml_to_tree(xml)
check = [
(lambda t: t.find('.').get('type'), 'lxc'),
(lambda t: t.find('./os/type').text, 'exe'),
(lambda t: t.find('./devices/filesystem/target').get('dir'), '/')]
for i, (check, expected_result) in enumerate(check):
self.assertEqual(check(tree),
expected_result,
'%s failed common check %d' % (xml, i))
target = tree.find('./devices/filesystem/source').get('dir')
self.assertTrue(len(target) > 0)
def _check_xml_and_uri(self, instance, expect_ramdisk, expect_kernel,
rescue=False):
user_context = context.RequestContext(project=self.project,

View File

@@ -14,9 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
"""
Test suite for XenAPI
"""
"""Test suite for XenAPI."""
import functools
import os
@@ -65,9 +63,7 @@ def stub_vm_utils_with_vdi_attached_here(function, should_return=True):
class XenAPIVolumeTestCase(test.TestCase):
"""
Unit tests for Volume operations
"""
"""Unit tests for Volume operations."""
def setUp(self):
super(XenAPIVolumeTestCase, self).setUp()
self.stubs = stubout.StubOutForTesting()
@@ -101,7 +97,7 @@ class XenAPIVolumeTestCase(test.TestCase):
return db.volume_create(self.context, vol)
def test_create_iscsi_storage(self):
""" This shows how to test helper classes' methods """
"""This shows how to test helper classes' methods."""
stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests)
session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
helper = volume_utils.VolumeHelper
@@ -116,7 +112,7 @@ class XenAPIVolumeTestCase(test.TestCase):
db.volume_destroy(context.get_admin_context(), vol['id'])
def test_parse_volume_info_raise_exception(self):
""" This shows how to test helper classes' methods """
"""This shows how to test helper classes' methods."""
stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests)
session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass')
helper = volume_utils.VolumeHelper
@@ -130,7 +126,7 @@ class XenAPIVolumeTestCase(test.TestCase):
db.volume_destroy(context.get_admin_context(), vol['id'])
def test_attach_volume(self):
""" This shows how to test Ops classes' methods """
"""This shows how to test Ops classes' methods."""
stubs.stubout_session(self.stubs, stubs.FakeSessionForVolumeTests)
conn = xenapi_conn.get_connection(False)
volume = self._create_volume()
@@ -149,7 +145,7 @@ class XenAPIVolumeTestCase(test.TestCase):
check()
def test_attach_volume_raise_exception(self):
""" This shows how to test when exceptions are raised """
"""This shows how to test when exceptions are raised."""
stubs.stubout_session(self.stubs,
stubs.FakeSessionForVolumeFailedTests)
conn = xenapi_conn.get_connection(False)
@@ -172,9 +168,7 @@ def reset_network(*args):
class XenAPIVMTestCase(test.TestCase):
"""
Unit tests for VM operations
"""
"""Unit tests for VM operations."""
def setUp(self):
super(XenAPIVMTestCase, self).setUp()
self.manager = manager.AuthManager()
@@ -188,6 +182,7 @@ class XenAPIVMTestCase(test.TestCase):
instance_name_template='%d')
xenapi_fake.reset()
xenapi_fake.create_local_srs()
xenapi_fake.create_local_pifs()
db_fakes.stub_out_db_instance_api(self.stubs)
xenapi_fake.create_network('fake', FLAGS.flat_network_bridge)
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
@@ -247,12 +242,12 @@ class XenAPIVMTestCase(test.TestCase):
check()
def create_vm_record(self, conn, os_type):
def create_vm_record(self, conn, os_type, instance_id=1):
instances = conn.list_instances()
self.assertEquals(instances, ['1'])
self.assertEquals(instances, [str(instance_id)])
# Get Nova record for VM
vm_info = conn.get_info(1)
vm_info = conn.get_info(instance_id)
# Get XenAPI record for VM
vms = [rec for ref, rec
in xenapi_fake.get_all_records('VM').iteritems()
@@ -286,19 +281,19 @@ class XenAPIVMTestCase(test.TestCase):
key = 'vm-data/networking/aabbccddeeff'
xenstore_value = xenstore_data[key]
tcpip_data = ast.literal_eval(xenstore_value)
self.assertEquals(tcpip_data, {
'label': 'test_network',
'broadcast': '10.0.0.255',
'ips': [{'ip': '10.0.0.3',
'netmask':'255.255.255.0',
'enabled':'1'}],
'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff',
'netmask': '120',
'enabled': '1',
'gateway': 'fe80::a00:1'}],
'mac': 'aa:bb:cc:dd:ee:ff',
'dns': ['10.0.0.2'],
'gateway': '10.0.0.1'})
self.assertEquals(tcpip_data,
{'label': 'fake_flat_network',
'broadcast': '10.0.0.255',
'ips': [{'ip': '10.0.0.3',
'netmask':'255.255.255.0',
'enabled':'1'}],
'ip6s': [{'ip': 'fe80::a8bb:ccff:fedd:eeff',
'netmask': '120',
'enabled': '1',
'gateway': 'fe80::a00:1'}],
'mac': 'aa:bb:cc:dd:ee:ff',
'dns': ['10.0.0.2'],
'gateway': '10.0.0.1'})
def check_vm_params_for_windows(self):
self.assertEquals(self.vm['platform']['nx'], 'true')
@@ -347,9 +342,9 @@ class XenAPIVMTestCase(test.TestCase):
def _test_spawn(self, image_id, kernel_id, ramdisk_id,
instance_type="m1.large", os_type="linux",
check_injection=False):
instance_id=1, check_injection=False):
stubs.stubout_loopingcall_start(self.stubs)
values = {'id': 1,
values = {'id': instance_id,
'project_id': self.project.id,
'user_id': self.user.id,
'image_id': image_id,
@@ -360,7 +355,7 @@ class XenAPIVMTestCase(test.TestCase):
'os_type': os_type}
instance = db.instance_create(self.context, values)
self.conn.spawn(instance)
self.create_vm_record(self.conn, os_type)
self.create_vm_record(self.conn, os_type, instance_id)
self.check_vm_record(self.conn, check_injection)
def test_spawn_not_enough_memory(self):
@@ -505,6 +500,28 @@ class XenAPIVMTestCase(test.TestCase):
# guest agent is detected
self.assertFalse(self._tee_executed)
def test_spawn_vlanmanager(self):
self.flags(xenapi_image_service='glance',
network_manager='nova.network.manager.VlanManager',
network_driver='nova.network.xenapi_net',
vlan_interface='fake0')
# Reset network table
xenapi_fake.reset_table('network')
# Instance id = 2 will use vlan network (see db/fakes.py)
fake_instance_id = 2
network_bk = self.network
# Ensure we use xenapi_net driver
self.network = utils.import_object(FLAGS.network_manager)
self.network.setup_compute_network(None, fake_instance_id)
self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE,
glance_stubs.FakeGlance.IMAGE_KERNEL,
glance_stubs.FakeGlance.IMAGE_RAMDISK,
instance_id=fake_instance_id)
# TODO(salvatore-orlando): a complete test here would require
# a check for making sure the bridge for the VM's VIF is
# consistent with bridge specified in nova db
self.network = network_bk
def test_spawn_with_network_qos(self):
self._create_instance()
for vif_ref in xenapi_fake.get_all('VIF'):
@@ -551,9 +568,7 @@ class XenAPIVMTestCase(test.TestCase):
class XenAPIDiffieHellmanTestCase(test.TestCase):
"""
Unit tests for Diffie-Hellman code
"""
"""Unit tests for Diffie-Hellman code."""
def setUp(self):
super(XenAPIDiffieHellmanTestCase, self).setUp()
self.alice = SimpleDH()
@@ -577,9 +592,7 @@ class XenAPIDiffieHellmanTestCase(test.TestCase):
class XenAPIMigrateInstance(test.TestCase):
"""
Unit test for verifying migration-related actions
"""
"""Unit test for verifying migration-related actions."""
def setUp(self):
super(XenAPIMigrateInstance, self).setUp()
@@ -634,9 +647,7 @@ class XenAPIMigrateInstance(test.TestCase):
class XenAPIDetermineDiskImageTestCase(test.TestCase):
"""
Unit tests for code that detects the ImageType
"""
"""Unit tests for code that detects the ImageType."""
def setUp(self):
super(XenAPIDetermineDiskImageTestCase, self).setUp()
glance_stubs.stubout_glance_client(self.stubs,
@@ -655,9 +666,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase):
self.assertEqual(disk_type, dt)
def test_instance_disk(self):
"""
If a kernel is specified then the image type is DISK (aka machine)
"""
"""If a kernel is specified, the image type is DISK (aka machine)."""
FLAGS.xenapi_image_service = 'objectstore'
self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_MACHINE
self.fake_instance.kernel_id = glance_stubs.FakeGlance.IMAGE_KERNEL