summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJason Koelker <jason@koelker.net>2011-06-16 10:54:59 -0500
committerJason Koelker <jason@koelker.net>2011-06-16 10:54:59 -0500
commit5da9e78a3fe5e6da1d01c8e25b5616f20db08aea (patch)
treec232bd2dd4a73a2ff5aac20c699bc36783582c8d /nova
parent070cbfeaf4ddc44b75df9b159887d35b36dcb932 (diff)
parenta2ea6652fce1b75d61b2217676c8447327a2467e (diff)
merge with trey
Diffstat (limited to 'nova')
-rw-r--r--nova/api/ec2/cloud.py29
-rw-r--r--nova/api/openstack/limits.py2
-rw-r--r--nova/api/openstack/server_metadata.py11
-rw-r--r--nova/api/openstack/wsgi.py12
-rw-r--r--nova/compute/api.py2
-rw-r--r--nova/compute/manager.py6
-rw-r--r--nova/crypto.py3
-rw-r--r--nova/db/api.py10
-rw-r--r--nova/db/sqlalchemy/api.py3
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/023_multi_nic.py2
-rw-r--r--nova/db/sqlalchemy/models.py7
-rw-r--r--nova/exception.py4
-rw-r--r--nova/flags.py6
-rw-r--r--nova/image/__init__.py7
-rw-r--r--nova/image/glance.py37
-rw-r--r--nova/network/manager.py13
-rw-r--r--nova/tests/api/openstack/test_server_metadata.py25
-rw-r--r--nova/tests/api/openstack/test_wsgi.py20
-rw-r--r--nova/tests/db/fakes.py88
-rw-r--r--nova/tests/image/test_glance.py4
-rw-r--r--nova/tests/network/base.py26
-rw-r--r--nova/tests/scheduler/test_host_filter.py8
-rw-r--r--nova/tests/scheduler/test_least_cost_scheduler.py8
-rw-r--r--nova/tests/scheduler/test_zone_aware_scheduler.py2
-rw-r--r--nova/tests/test_cloud.py13
-rw-r--r--nova/tests/test_compute.py1
-rw-r--r--nova/tests/test_crypto.py83
-rw-r--r--nova/tests/test_host_filter.py108
-rw-r--r--nova/tests/test_libvirt.py41
-rw-r--r--nova/tests/test_xenapi.py108
-rw-r--r--nova/virt/images.py11
-rw-r--r--nova/virt/xenapi/vm_utils.py17
-rw-r--r--nova/virt/xenapi/vmops.py5
-rw-r--r--nova/virt/xenapi_conn.py4
34 files changed, 487 insertions, 239 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 3c3f259b4..e74256dfa 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -39,6 +39,7 @@ from nova import flags
from nova import ipv6
from nova import log as logging
from nova import network
+from nova import rpc
from nova import utils
from nova import volume
from nova.api.ec2 import ec2utils
@@ -120,8 +121,8 @@ class CloudController(object):
result = {}
for instance in self.compute_api.get_all(context,
project_id=project_id):
- if instance['fixed_ip']:
- line = '%s slots=%d' % (instance['fixed_ip']['address'],
+ if instance['fixed_ips']:
+ line = '%s slots=%d' % (instance['fixed_ips'][0]['address'],
instance['vcpus'])
key = str(instance['key_name'])
if key in result:
@@ -792,15 +793,15 @@ class CloudController(object):
'name': instance['state_description']}
fixed_addr = None
floating_addr = None
- if instance['fixed_ip']:
- fixed_addr = instance['fixed_ip']['address']
- if instance['fixed_ip']['floating_ips']:
- fixed = instance['fixed_ip']
+ if instance['fixed_ips']:
+ fixed = instance['fixed_ips'][0]
+ fixed_addr = fixed['address']
+ if fixed['floating_ips']:
floating_addr = fixed['floating_ips'][0]['address']
- if instance['fixed_ip']['network'] and 'use_v6' in kwargs:
+ if fixed['network'] and 'use_v6' in kwargs:
i['dnsNameV6'] = ipv6.to_global(
- instance['fixed_ip']['network']['cidr_v6'],
- instance['fixed_ip']['virtual_interface']['address'],
+ fixed['network']['cidr_v6'],
+ fixed['virtual_interface']['address'],
instance['project_id'])
i['privateDnsName'] = fixed_addr
@@ -872,8 +873,14 @@ class CloudController(object):
def allocate_address(self, context, **kwargs):
LOG.audit(_("Allocate address"), context=context)
- public_ip = self.network_api.allocate_floating_ip(context)
- return {'publicIp': public_ip}
+ try:
+ public_ip = self.network_api.allocate_floating_ip(context)
+ return {'publicIp': public_ip}
+ except rpc.RemoteError as ex:
+ if ex.exc_type == 'NoMoreAddresses':
+ raise exception.NoMoreFloatingIps()
+ else:
+ raise
def release_address(self, context, public_ip, **kwargs):
LOG.audit(_("Release address %s"), public_ip, context=context)
diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/limits.py
index dc2bc6bbc..fede96e33 100644
--- a/nova/api/openstack/limits.py
+++ b/nova/api/openstack/limits.py
@@ -99,7 +99,7 @@ def create_resource(version='1.0'):
serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns,
- metadata=metadata)
+ metadata=metadata),
}
return wsgi.Resource(controller, serializers=serializers)
diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py
index b38b84a2a..57666f6b7 100644
--- a/nova/api/openstack/server_metadata.py
+++ b/nova/api/openstack/server_metadata.py
@@ -37,12 +37,18 @@ class Controller(object):
meta_dict[key] = value
return dict(metadata=meta_dict)
+ def _check_body(self, body):
+ if body == None or body == "":
+ expl = _('No Request Body')
+ raise exc.HTTPBadRequest(explanation=expl)
+
def index(self, req, server_id):
""" Returns the list of metadata for a given instance """
context = req.environ['nova.context']
return self._get_metadata(context, server_id)
def create(self, req, server_id, body):
+ self._check_body(body)
context = req.environ['nova.context']
metadata = body.get('metadata')
try:
@@ -51,9 +57,10 @@ class Controller(object):
metadata)
except quota.QuotaError as error:
self._handle_quota_error(error)
- return req.body
+ return body
def update(self, req, server_id, id, body):
+ self._check_body(body)
context = req.environ['nova.context']
if not id in body:
expl = _('Request body and URI mismatch')
@@ -68,7 +75,7 @@ class Controller(object):
except quota.QuotaError as error:
self._handle_quota_error(error)
- return req.body
+ return body
def show(self, req, server_id, id):
""" Return a single metadata item """
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index ddf4e6fa9..b0e2cab2c 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -60,7 +60,7 @@ class TextDeserializer(object):
def deserialize(self, datastring, action='default'):
"""Find local deserialization method and parse request body."""
- action_method = getattr(self, action, self.default)
+ action_method = getattr(self, str(action), self.default)
return action_method(datastring)
def default(self, datastring):
@@ -189,7 +189,7 @@ class DictSerializer(object):
def serialize(self, data, action='default'):
"""Find local serialization method and encode response body."""
- action_method = getattr(self, action, self.default)
+ action_method = getattr(self, str(action), self.default)
return action_method(data)
def default(self, data):
@@ -225,7 +225,7 @@ class XMLDictSerializer(DictSerializer):
if not xmlns and self.xmlns:
node.setAttribute('xmlns', self.xmlns)
- return node.toprettyxml(indent=' ')
+ return node.toprettyxml(indent=' ', encoding='utf-8')
def _to_xml_node(self, doc, metadata, nodename, data):
"""Recursive method to convert data members to XML nodes."""
@@ -296,7 +296,7 @@ class ResponseSerializer(object):
}
self.serializers.update(serializers or {})
- def serialize(self, response_data, content_type):
+ def serialize(self, response_data, content_type, action='default'):
"""Serialize a dict into a string and wrap in a wsgi.Request object.
:param response_data: dict produced by the Controller
@@ -307,7 +307,7 @@ class ResponseSerializer(object):
response.headers['Content-Type'] = content_type
serializer = self.get_serializer(content_type)
- response.body = serializer.serialize(response_data)
+ response.body = serializer.serialize(response_data, action)
return response
@@ -358,7 +358,7 @@ class Resource(wsgi.Application):
#TODO(bcwaldon): find a more elegant way to pass through non-dict types
if type(action_result) is dict:
- response = self.serializer.serialize(action_result, accept)
+ response = self.serializer.serialize(action_result, accept, action)
else:
response = action_result
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 2a2dc6f0e..83a31707a 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -263,7 +263,7 @@ class API(base.Base):
'instance_type': instance_type,
'filter': filter_class,
'blob': zone_blob,
- 'num_instances': num_instances
+ 'num_instances': num_instances,
}
rpc.cast(context,
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index cf9a97b4c..d08286224 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -596,8 +596,10 @@ class ComputeManager(manager.SchedulerDependentManager):
# reload the updated instance ref
# FIXME(mdietz): is there reload functionality?
- instance_ref = self.db.instance_get(context, instance_id)
- self.driver.finish_resize(instance_ref, disk_info)
+ instance = self.db.instance_get(context, instance_id)
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance)
+ self.driver.finish_resize(instance, disk_info, network_info)
self.db.migration_update(context, migration_id,
{'status': 'finished', })
diff --git a/nova/crypto.py b/nova/crypto.py
index bdc32482a..8d535f426 100644
--- a/nova/crypto.py
+++ b/nova/crypto.py
@@ -176,7 +176,8 @@ def revoke_certs_by_project(project_id):
def revoke_certs_by_user_and_project(user_id, project_id):
"""Revoke certs for user in project."""
admin = context.get_admin_context()
- for cert in db.certificate_get_all_by_user(admin, user_id, project_id):
+ for cert in db.certificate_get_all_by_user_and_project(admin,
+ user_id, project_id):
revoke_cert(cert['project_id'], cert['file_name'])
diff --git a/nova/db/api.py b/nova/db/api.py
index c990af094..64b6a893e 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -224,13 +224,13 @@ def certificate_update(context, certificate_id, values):
###################
-def floating_ip_allocate_address(context, host, project_id):
+def floating_ip_allocate_address(context, project_id):
"""Allocate free floating ip and return the address.
Raises if one is not available.
"""
- return IMPL.floating_ip_allocate_address(context, host, project_id)
+ return IMPL.floating_ip_allocate_address(context, project_id)
def floating_ip_create(context, values):
@@ -433,9 +433,9 @@ def virtual_interface_get_by_instance(context, instance_id):
def virtual_interface_get_by_instance_and_network(context, instance_id,
network_id):
"""gets all virtual interfaces for instance"""
- return IMPL.virtual_interfaces_get_by_instance_and_network(context,
- instance_id,
- network_id)
+ return IMPL.virtual_interface_get_by_instance_and_network(context,
+ instance_id,
+ network_id)
def virtual_interface_get_by_network(context, network_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 076f7ba67..46f5e7494 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -433,7 +433,7 @@ def certificate_update(context, certificate_id, values):
@require_context
-def floating_ip_allocate_address(context, host, project_id):
+def floating_ip_allocate_address(context, project_id):
authorize_project_context(context, project_id)
session = get_session()
with session.begin():
@@ -448,7 +448,6 @@ def floating_ip_allocate_address(context, host, project_id):
if not floating_ip_ref:
raise db.NoMoreAddresses()
floating_ip_ref['project_id'] = project_id
- floating_ip_ref['host'] = host
session.add(floating_ip_ref)
return floating_ip_ref['address']
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/023_multi_nic.py b/nova/db/sqlalchemy/migrate_repo/versions/023_multi_nic.py
index 12cd7621a..85ab1fdd8 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/023_multi_nic.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/023_multi_nic.py
@@ -48,7 +48,7 @@ virtual_interfaces = Table('virtual_interfaces', meta,
String(length=255, convert_unicode=False, assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False),
unique=True),
- )
+ mysql_engine='InnoDB')
# bridge_interface column to add to networks table
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 9455ed95a..605e6126a 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -184,13 +184,6 @@ class Instance(BASE, NovaBase):
def project(self):
return auth.manager.AuthManager().get_project(self.project_id)
- #TODO{tr3buchet): i don't like this shim.....
- # prevents breaking ec2 api
- # should go away with zones when ec2 api doesn't have compute db access
- @property
- def fixed_ip(self):
- return self.fixed_ips[0] if self.fixed_ips else None
-
image_ref = Column(String(255))
kernel_id = Column(String(255))
ramdisk_id = Column(String(255))
diff --git a/nova/exception.py b/nova/exception.py
index 352fbefed..2c24d883a 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -396,6 +396,10 @@ class NoFloatingIpsDefinedForInstance(NoFloatingIpsDefined):
message = _("Zero floating ips defined for instance %(instance_id)s.")
+class NoMoreFloatingIps(NotFound):
+ message = _("Zero floating ips available.")
+
+
class KeypairNotFound(NotFound):
message = _("Keypair %(keypair_name)s not found for user %(user_id)s")
diff --git a/nova/flags.py b/nova/flags.py
index a8f16c6bb..acfcf8d68 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -270,8 +270,10 @@ DEFINE_list('region_list',
DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake')
DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID')
DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key')
-DEFINE_integer('glance_port', 9292, 'glance port')
-DEFINE_string('glance_host', '$my_ip', 'glance host')
+# NOTE(sirp): my_ip interpolation doesn't work within nested structures
+DEFINE_list('glance_api_servers',
+ ['127.0.0.1:9292'],
+ 'list of glance api servers available to nova (host:port)')
DEFINE_integer('s3_port', 3333, 's3 port')
DEFINE_string('s3_host', '$my_ip', 's3 host (for infrastructure)')
DEFINE_string('s3_dmz', '$my_ip', 's3 dmz ip (for instances)')
diff --git a/nova/image/__init__.py b/nova/image/__init__.py
index 93d83df24..a27d649d4 100644
--- a/nova/image/__init__.py
+++ b/nova/image/__init__.py
@@ -22,6 +22,7 @@ import nova
from nova import exception
from nova import utils
from nova import flags
+from nova.image import glance as glance_image_service
FLAGS = flags.FLAGS
@@ -48,6 +49,8 @@ def get_default_image_service():
return ImageService()
+# FIXME(sirp): perhaps this should be moved to nova/images/glance so that we
+# keep Glance specific code together for the most part
def get_glance_client(image_href):
"""Get the correct glance client and id for the given image_href.
@@ -62,7 +65,9 @@ def get_glance_client(image_href):
"""
image_href = image_href or 0
if str(image_href).isdigit():
- glance_client = GlanceClient(FLAGS.glance_host, FLAGS.glance_port)
+ glance_host, glance_port = \
+ glance_image_service.pick_glance_api_server()
+ glance_client = GlanceClient(glance_host, glance_port)
return (glance_client, int(image_href))
try:
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 61308431d..6e058ab2f 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -20,6 +20,7 @@
from __future__ import absolute_import
import datetime
+import random
from glance.common import exception as glance_exception
@@ -39,6 +40,21 @@ FLAGS = flags.FLAGS
GlanceClient = utils.import_class('glance.client.Client')
+def pick_glance_api_server():
+ """Return which Glance API server to use for the request
+
+ This method provides a very primitive form of load-balancing suitable for
+ testing and sandbox environments. In production, it would be better to use
+ one IP and route that to a real load-balancer.
+
+ Returns (host, port)
+ """
+ host_port = random.choice(FLAGS.glance_api_servers)
+ host, port_str = host_port.split(':')
+ port = int(port_str)
+ return host, port
+
+
class GlanceImageService(service.BaseImageService):
"""Provides storage and retrieval of disk image objects within Glance."""
@@ -51,12 +67,21 @@ class GlanceImageService(service.BaseImageService):
GLANCE_ONLY_ATTRS
def __init__(self, client=None):
- # FIXME(sirp): can we avoid dependency-injection here by using
- # stubbing out a fake?
- if client is None:
- self.client = GlanceClient(FLAGS.glance_host, FLAGS.glance_port)
- else:
- self.client = client
+ self._client = client
+
+ def _get_client(self):
+ # NOTE(sirp): we want to load balance each request across glance
+ # servers. Since GlanceImageService is a long-lived object, `client`
+ # is made to choose a new server each time via this property.
+ if self._client is not None:
+ return self._client
+ glance_host, glance_port = pick_glance_api_server()
+ return GlanceClient(glance_host, glance_port)
+
+ def _set_client(self, client):
+ self._client = client
+
+ client = property(_get_client, _set_client)
def index(self, context, filters=None, marker=None, limit=None):
"""Calls out to Glance for a list of images available."""
diff --git a/nova/network/manager.py b/nova/network/manager.py
index d7cb31160..d725be69f 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -197,7 +197,7 @@ class FloatingIP(object):
fixed_ip = fixed_ips[0] if fixed_ips else None
# call to correct network host to associate the floating ip
- network_api.associate_floating_ip(context,
+ self.network_api.associate_floating_ip(context,
floating_ip,
fixed_ip,
affect_auto_assigned=True)
@@ -220,10 +220,12 @@ class FloatingIP(object):
# disassociate floating ips related to fixed_ip
for floating_ip in fixed_ip.floating_ips:
address = floating_ip['address']
- network_api.disassociate_floating_ip(context, address)
+ self.network_api.disassociate_floating_ip(context, address)
# deallocate if auto_assigned
if floating_ip['auto_assigned']:
- network_api.release_floating_ip(context, address, True)
+ self.network_api.release_floating_ip(context,
+ address,
+ True)
# call the next inherited class's deallocate_for_instance()
# which is currently the NetworkManager version
@@ -242,7 +244,6 @@ class FloatingIP(object):
'allocate any more addresses'))
# TODO(vish): add floating ips through manage command
return self.db.floating_ip_allocate_address(context,
- self.host,
project_id)
def associate_floating_ip(self, context, floating_address, fixed_address):
@@ -284,6 +285,7 @@ class NetworkManager(manager.SchedulerDependentManager):
if not network_driver:
network_driver = FLAGS.network_driver
self.driver = utils.import_object(network_driver)
+ self.network_api = network_api.API()
super(NetworkManager, self).__init__(service_name='network',
*args, **kwargs)
@@ -418,7 +420,8 @@ class NetworkManager(manager.SchedulerDependentManager):
"enabled": "1"}
network_dict = {
'bridge': network['bridge'],
- 'id': network['id']}
+ 'id': network['id'],
+ 'injected': network['injected']}
info = {
'label': network['label'],
'gateway': network['gateway'],
diff --git a/nova/tests/api/openstack/test_server_metadata.py b/nova/tests/api/openstack/test_server_metadata.py
index c4d1d4fd8..b583d40fe 100644
--- a/nova/tests/api/openstack/test_server_metadata.py
+++ b/nova/tests/api/openstack/test_server_metadata.py
@@ -89,6 +89,7 @@ class ServerMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
+ self.assertEqual('application/json', res.headers['Content-Type'])
self.assertEqual('value1', res_dict['metadata']['key1'])
def test_index_no_data(self):
@@ -99,6 +100,7 @@ class ServerMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
+ self.assertEqual('application/json', res.headers['Content-Type'])
self.assertEqual(0, len(res_dict['metadata']))
def test_show(self):
@@ -109,6 +111,7 @@ class ServerMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
+ self.assertEqual('application/json', res.headers['Content-Type'])
self.assertEqual('value5', res_dict['key5'])
def test_show_meta_not_found(self):
@@ -140,8 +143,19 @@ class ServerMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int)
+ self.assertEqual('application/json', res.headers['Content-Type'])
self.assertEqual('value1', res_dict['metadata']['key1'])
+ def test_create_empty_body(self):
+ self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create',
+ return_create_instance_metadata)
+ req = webob.Request.blank('/v1.1/servers/1/meta')
+ req.environ['api.version'] = '1.1'
+ req.method = 'POST'
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, res.status_int)
+
def test_update_item(self):
self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create',
return_create_instance_metadata)
@@ -152,9 +166,20 @@ class ServerMetaDataTest(unittest.TestCase):
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(200, res.status_int)
+ self.assertEqual('application/json', res.headers['Content-Type'])
res_dict = json.loads(res.body)
self.assertEqual('value1', res_dict['key1'])
+ def test_update_item_empty_body(self):
+ self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create',
+ return_create_instance_metadata)
+ req = webob.Request.blank('/v1.1/servers/1/meta/key1')
+ req.environ['api.version'] = '1.1'
+ req.method = 'PUT'
+ req.headers["content-type"] = "application/json"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, res.status_int)
+
def test_update_item_too_many_keys(self):
self.stubs.Set(nova.db.api, 'instance_metadata_update_or_create',
return_create_instance_metadata)
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index ebbdc9409..2fa50ac9b 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -89,6 +89,12 @@ class DictSerializerTest(test.TestCase):
serializer.default = lambda x: 'trousers'
self.assertEqual(serializer.serialize({}, 'update'), 'trousers')
+ def test_dispatch_action_None(self):
+ serializer = wsgi.DictSerializer()
+ serializer.create = lambda x: 'pants'
+ serializer.default = lambda x: 'trousers'
+ self.assertEqual(serializer.serialize({}, None), 'trousers')
+
class XMLDictSerializerTest(test.TestCase):
def test_xml(self):
@@ -123,6 +129,12 @@ class TextDeserializerTest(test.TestCase):
deserializer.default = lambda x: 'trousers'
self.assertEqual(deserializer.deserialize({}, 'update'), 'trousers')
+ def test_dispatch_action_None(self):
+ deserializer = wsgi.TextDeserializer()
+ deserializer.create = lambda x: 'pants'
+ deserializer.default = lambda x: 'trousers'
+ self.assertEqual(deserializer.deserialize({}, None), 'trousers')
+
class JSONDeserializerTest(test.TestCase):
def test_json(self):
@@ -171,11 +183,11 @@ class XMLDeserializerTest(test.TestCase):
class ResponseSerializerTest(test.TestCase):
def setUp(self):
class JSONSerializer(object):
- def serialize(self, data):
+ def serialize(self, data, action='default'):
return 'pew_json'
class XMLSerializer(object):
- def serialize(self, data):
+ def serialize(self, data, action='default'):
return 'pew_xml'
self.serializers = {
@@ -211,11 +223,11 @@ class ResponseSerializerTest(test.TestCase):
class RequestDeserializerTest(test.TestCase):
def setUp(self):
class JSONDeserializer(object):
- def deserialize(self, data):
+ def deserialize(self, data, action='default'):
return 'pew_json'
class XMLDeserializer(object):
- def deserialize(self, data):
+ def deserialize(self, data, action='default'):
return 'pew_xml'
self.deserializers = {
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index 2d949a26d..525f720a5 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -68,16 +68,18 @@ def stub_out_db_network_api(stubs):
'dns': '192.168.0.1',
'vlan': None,
'host': None,
+ 'injected': False,
'vpn_public_address': '192.168.0.2'}
fixed_ip_fields = {'id': 0,
'network_id': 0,
+ 'network': FakeModel(network_fields),
'address': '192.168.0.100',
'instance': False,
'instance_id': 0,
'allocated': False,
- 'mac_address_id': 0,
- 'mac_address': None,
+ 'virtual_interface_id': 0,
+ 'virtual_interface': None,
'floating_ips': []}
flavor_fields = {'id': 0,
@@ -85,20 +87,20 @@ def stub_out_db_network_api(stubs):
floating_ip_fields = {'id': 0,
'address': '192.168.1.100',
- 'fixed_ip_id': 0,
+ 'fixed_ip_id': None,
'fixed_ip': None,
- 'project_id': 'fake',
+ 'project_id': None,
'auto_assigned': False}
- mac_address_fields = {'id': 0,
- 'address': 'DE:AD:BE:EF:00:00',
- 'network_id': 0,
- 'instance_id': 0,
- 'network': FakeModel(network_fields)}
+ virtual_interface_fields = {'id': 0,
+ 'address': 'DE:AD:BE:EF:00:00',
+ 'network_id': 0,
+ 'instance_id': 0,
+ 'network': FakeModel(network_fields)}
fixed_ips = [fixed_ip_fields]
floating_ips = [floating_ip_fields]
- mac_addresses = [mac_address_fields]
+ virtual_interfacees = [virtual_interface_fields]
networks = [network_fields]
def fake_floating_ip_allocate_address(context, project_id):
@@ -108,7 +110,7 @@ def stub_out_db_network_api(stubs):
if not ips:
raise db.NoMoreAddresses()
ips[0]['project_id'] = project_id
- return FakeModel(ips[0]['address'])
+ return FakeModel(ips[0])
def fake_floating_ip_deallocate(context, address):
ips = filter(lambda i: i['address'] == address,
@@ -144,6 +146,9 @@ def stub_out_db_network_api(stubs):
pass
def fake_floating_ip_get_by_address(context, address):
+ if isinstance(address, FakeModel):
+ # NOTE(tr3buchet): yo dawg, i heard you like addresses
+ address = address['address']
ips = filter(lambda i: i['address'] == address,
floating_ips)
if not ips:
@@ -188,13 +193,13 @@ def stub_out_db_network_api(stubs):
if ips:
ips[0]['instance_id'] = None
ips[0]['instance'] = None
- ips[0]['mac_address'] = None
- ips[0]['mac_address_id'] = None
+ ips[0]['virtual_interface'] = None
+ ips[0]['virtual_interface_id'] = None
def fake_fixed_ip_disassociate_all_by_timeout(context, host, time):
return 0
- def fake_fixed_ip_get_all_by_instance(context, instance_id):
+ def fake_fixed_ip_get_by_instance(context, instance_id):
ips = filter(lambda i: i['instance_id'] == instance_id,
fixed_ips)
return [FakeModel(i) for i in ips]
@@ -220,45 +225,46 @@ def stub_out_db_network_api(stubs):
if ips:
for key in values:
ips[0][key] = values[key]
- if key == 'mac_address_id':
- mac = filter(lambda x: x['id'] == values[key],
- mac_addresses)
- if not mac:
+ if key == 'virtual_interface_id':
+ vif = filter(lambda x: x['id'] == values[key],
+ virtual_interfacees)
+ if not vif:
continue
- fixed_ip_fields['mac_address'] = FakeModel(mac[0])
+ fixed_ip_fields['virtual_interface'] = FakeModel(vif[0])
def fake_instance_type_get_by_id(context, id):
if flavor_fields['id'] == id:
return FakeModel(flavor_fields)
- def fake_mac_address_create(context, values):
- mac = dict(mac_address_fields)
- mac['id'] = max([m['id'] for m in mac_addresses] or [-1]) + 1
+ def fake_virtual_interface_create(context, values):
+ vif = dict(virtual_interface_fields)
+ vif['id'] = max([m['id'] for m in virtual_interfacees] or [-1]) + 1
for key in values:
- mac[key] = values[key]
- return FakeModel(mac)
+ vif[key] = values[key]
+ return FakeModel(vif)
- def fake_mac_address_delete_by_instance(context, instance_id):
- addresses = [m for m in mac_addresses \
+ def fake_virtual_interface_delete_by_instance(context, instance_id):
+ addresses = [m for m in virtual_interfacees \
if m['instance_id'] == instance_id]
try:
for address in addresses:
- mac_addresses.remove(address)
+ virtual_interfacees.remove(address)
except ValueError:
pass
- def fake_mac_address_get_all_by_instance(context, instance_id):
- return [FakeModel(m) for m in mac_addresses \
+ def fake_virtual_interface_get_by_instance(context, instance_id):
+ return [FakeModel(m) for m in virtual_interfacees \
if m['instance_id'] == instance_id]
- def fake_mac_address_get_by_instance_and_network(context, instance_id,
- network_id):
- mac = filter(lambda m: m['instance_id'] == instance_id \
- and m['network_id'] == network_id,
- mac_addresses)
- if not mac:
+ def fake_virtual_interface_get_by_instance_and_network(context,
+ instance_id,
+ network_id):
+ vif = filter(lambda m: m['instance_id'] == instance_id and \
+ m['network_id'] == network_id,
+ virtual_interfacees)
+ if not vif:
return None
- return FakeModel(mac[0])
+ return FakeModel(vif[0])
def fake_network_create_safe(context, values):
net = dict(network_fields)
@@ -315,15 +321,15 @@ def stub_out_db_network_api(stubs):
fake_fixed_ip_create,
fake_fixed_ip_disassociate,
fake_fixed_ip_disassociate_all_by_timeout,
- fake_fixed_ip_get_all_by_instance,
+ fake_fixed_ip_get_by_instance,
fake_fixed_ip_get_by_address,
fake_fixed_ip_get_network,
fake_fixed_ip_update,
fake_instance_type_get_by_id,
- fake_mac_address_create,
- fake_mac_address_delete_by_instance,
- fake_mac_address_get_all_by_instance,
- fake_mac_address_get_by_instance_and_network,
+ fake_virtual_interface_create,
+ fake_virtual_interface_delete_by_instance,
+ fake_virtual_interface_get_by_instance,
+ fake_virtual_interface_get_by_instance_and_network,
fake_network_create_safe,
fake_network_get,
fake_network_get_all,
diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py
index 041da1e13..223e7ae57 100644
--- a/nova/tests/image/test_glance.py
+++ b/nova/tests/image/test_glance.py
@@ -60,10 +60,8 @@ class BaseGlanceTest(unittest.TestCase):
NOW_DATETIME = datetime.datetime(2010, 10, 11, 10, 30, 22)
def setUp(self):
- # FIXME(sirp): we can probably use stubs library here rather than
- # dependency injection
self.client = StubGlanceClient(None)
- self.service = glance.GlanceImageService(self.client)
+ self.service = glance.GlanceImageService(client=self.client)
self.context = context.RequestContext(None, None)
def assertDateTimesFilled(self, image_meta):
diff --git a/nova/tests/network/base.py b/nova/tests/network/base.py
index 7123a3cbe..eceb384f2 100644
--- a/nova/tests/network/base.py
+++ b/nova/tests/network/base.py
@@ -43,10 +43,12 @@ class NetworkTestCase(test.TestCase):
self.network = utils.import_object(FLAGS.network_manager)
db_fakes.stub_out_db_network_api(self.stubs)
self.network.db = db
- self.context = context.RequestContext(project=None, user=self.user)
+ self.network.network_api.db = db
+ self.context = context.RequestContext(project='fake', user=self.user)
def tearDown(self):
super(NetworkTestCase, self).tearDown()
+ self.manager.delete_user(self.user.id)
reload(db)
@@ -65,7 +67,7 @@ class TestFuncs(object):
def test_allocate_for_instance(self):
instance_id = 0
- project_id = 0
+ project_id = self.context.project_id
type_id = 0
self.network.set_network_hosts(self.context)
nw = self.network.allocate_for_instance(self.context,
@@ -100,18 +102,18 @@ class TestFuncs(object):
self.network.add_fixed_ip_to_instance(self.context,
instance_id=instance_id,
network_id=network_id)
- ips = db.fixed_ip_get_all_by_instance(self.context, instance_id)
+ ips = db.fixed_ip_get_by_instance(self.context, instance_id)
for ip in ips:
self.assertTrue(ip['allocated'])
self.network.deallocate_for_instance(self.context,
instance_id=instance_id)
- ips = db.fixed_ip_get_all_by_instance(self.context, instance_id)
+ ips = db.fixed_ip_get_by_instance(self.context, instance_id)
for ip in ips:
self.assertFalse(ip['allocated'])
def test_lease_release_fixed_ip(self):
instance_id = 0
- project_id = 0
+ project_id = self.context.project_id
type_id = 0
self.network.set_network_hosts(self.context)
nw = self.network.allocate_for_instance(self.context,
@@ -122,21 +124,21 @@ class TestFuncs(object):
self.assertTrue(nw[0])
network_id = nw[0][0]['id']
- ips = db.fixed_ip_get_all_by_instance(self.context, instance_id)
- mac = db.mac_address_get_by_instance_and_network(self.context,
- instance_id,
- network_id)
+ ips = db.fixed_ip_get_by_instance(self.context, instance_id)
+ vif = db.virtual_interface_get_by_instance_and_network(self.context,
+ instance_id,
+ network_id)
self.assertTrue(ips)
address = ips[0]['address']
db.fixed_ip_associate(self.context, address, instance_id)
db.fixed_ip_update(self.context, address,
- {'mac_address_id': mac['id']})
+ {'virtual_interface_id': vif['id']})
- self.network.lease_fixed_ip(self.context, mac['address'], address)
+ self.network.lease_fixed_ip(self.context, vif['address'], address)
ip = db.fixed_ip_get_by_address(self.context, address)
self.assertTrue(ip['leased'])
- self.network.release_fixed_ip(self.context, mac['address'], address)
+ self.network.release_fixed_ip(self.context, vif['address'], address)
ip = db.fixed_ip_get_by_address(self.context, address)
self.assertFalse(ip['leased'])
diff --git a/nova/tests/scheduler/test_host_filter.py b/nova/tests/scheduler/test_host_filter.py
index 07817cc5a..10eafde08 100644
--- a/nova/tests/scheduler/test_host_filter.py
+++ b/nova/tests/scheduler/test_host_filter.py
@@ -133,11 +133,11 @@ class HostFilterTestCase(test.TestCase):
raw = ['or',
['and',
['<', '$compute.host_memory_free', 30],
- ['<', '$compute.disk_available', 300]
+ ['<', '$compute.disk_available', 300],
],
['and',
['>', '$compute.host_memory_free', 70],
- ['>', '$compute.disk_available', 700]
+ ['>', '$compute.disk_available', 700],
]
]
cooked = json.dumps(raw)
@@ -183,12 +183,12 @@ class HostFilterTestCase(test.TestCase):
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([])))
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({})))
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps(
- ['not', True, False, True, False]
+ ['not', True, False, True, False],
)))
try:
hf.filter_hosts(self.zone_manager, json.dumps(
- 'not', True, False, True, False
+ 'not', True, False, True, False,
))
self.fail("Should give KeyError")
except KeyError, e:
diff --git a/nova/tests/scheduler/test_least_cost_scheduler.py b/nova/tests/scheduler/test_least_cost_scheduler.py
index 506fa62fb..9a5318aee 100644
--- a/nova/tests/scheduler/test_least_cost_scheduler.py
+++ b/nova/tests/scheduler/test_least_cost_scheduler.py
@@ -44,7 +44,7 @@ class WeightedSumTestCase(test.TestCase):
hosts = [
FakeHost(1, 512 * MB, 100),
FakeHost(2, 256 * MB, 400),
- FakeHost(3, 512 * MB, 100)
+ FakeHost(3, 512 * MB, 100),
]
weighted_fns = [
@@ -96,7 +96,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_noop_cost_fn(self):
FLAGS.least_cost_scheduler_cost_functions = [
- 'nova.scheduler.least_cost.noop_cost_fn'
+ 'nova.scheduler.least_cost.noop_cost_fn',
]
FLAGS.noop_cost_fn_weight = 1
@@ -110,7 +110,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_cost_fn_weights(self):
FLAGS.least_cost_scheduler_cost_functions = [
- 'nova.scheduler.least_cost.noop_cost_fn'
+ 'nova.scheduler.least_cost.noop_cost_fn',
]
FLAGS.noop_cost_fn_weight = 2
@@ -124,7 +124,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_fill_first_cost_fn(self):
FLAGS.least_cost_scheduler_cost_functions = [
- 'nova.scheduler.least_cost.fill_first_cost_fn'
+ 'nova.scheduler.least_cost.fill_first_cost_fn',
]
FLAGS.fill_first_cost_fn_weight = 1
diff --git a/nova/tests/scheduler/test_zone_aware_scheduler.py b/nova/tests/scheduler/test_zone_aware_scheduler.py
index 423f28927..998b566a6 100644
--- a/nova/tests/scheduler/test_zone_aware_scheduler.py
+++ b/nova/tests/scheduler/test_zone_aware_scheduler.py
@@ -197,7 +197,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
'instance_properties': {},
'instance_type': {},
'filter_driver': 'nova.scheduler.host_filter.AllHostsFilter',
- 'blob': "Non-None blob data"
+ 'blob': "Non-None blob data",
}
result = sched.schedule_run_instance(None, 1, request_spec)
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index 025ed4723..a37a7d417 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -117,6 +117,19 @@ class CloudTestCase(test.TestCase):
db.floating_ip_destroy(self.context, address)
@test.skip_test("Skipping this pending future merge")
+ def test_allocate_address(self):
+ address = "10.10.10.10"
+ allocate = self.cloud.allocate_address
+ db.floating_ip_create(self.context,
+ {'address': address,
+ 'host': self.network.host})
+ self.assertEqual(allocate(self.context)['publicIp'], address)
+ db.floating_ip_destroy(self.context, address)
+ self.assertRaises(exception.NoMoreFloatingIps,
+ allocate,
+ self.context)
+
+ @test.skip_test("Skipping this pending future merge")
def test_associate_disassociate_address(self):
"""Verifies associate runs cleanly without raising an exception"""
address = "10.10.10.10"
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 195d6909c..91c12e2ac 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -339,6 +339,7 @@ class ComputeTestCase(test.TestCase):
pass
self.stubs.Set(self.compute.driver, 'finish_resize', fake)
+ self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
context = self.context.elevated()
instance_id = self._create_instance()
self.compute.prep_resize(context, instance_id, 1)
diff --git a/nova/tests/test_crypto.py b/nova/tests/test_crypto.py
index 945d78794..6c25b396e 100644
--- a/nova/tests/test_crypto.py
+++ b/nova/tests/test_crypto.py
@@ -16,7 +16,11 @@
Tests for Crypto module.
"""
+import mox
+import stubout
+
from nova import crypto
+from nova import db
from nova import test
@@ -46,3 +50,82 @@ class SymmetricKeyTestCase(test.TestCase):
plain = decrypt(cipher_text)
self.assertEquals(plain_text, plain)
+
+
+class RevokeCertsTest(test.TestCase):
+
+ def setUp(self):
+ super(RevokeCertsTest, self).setUp()
+ self.stubs = stubout.StubOutForTesting()
+
+ def tearDown(self):
+ self.stubs.UnsetAll()
+ super(RevokeCertsTest, self).tearDown()
+
+ def test_revoke_certs_by_user_and_project(self):
+ user_id = 'test_user'
+ project_id = 2
+ file_name = 'test_file'
+
+ def mock_certificate_get_all_by_user_and_project(context,
+ user_id,
+ project_id):
+
+ return [{"user_id": user_id, "project_id": project_id,
+ "file_name": file_name}]
+
+ self.stubs.Set(db, 'certificate_get_all_by_user_and_project',
+ mock_certificate_get_all_by_user_and_project)
+
+ self.mox.StubOutWithMock(crypto, 'revoke_cert')
+ crypto.revoke_cert(project_id, file_name)
+
+ self.mox.ReplayAll()
+
+ crypto.revoke_certs_by_user_and_project(user_id, project_id)
+
+ self.mox.VerifyAll()
+
+ def test_revoke_certs_by_user(self):
+ user_id = 'test_user'
+ project_id = 2
+ file_name = 'test_file'
+
+ def mock_certificate_get_all_by_user(context, user_id):
+
+ return [{"user_id": user_id, "project_id": project_id,
+ "file_name": file_name}]
+
+ self.stubs.Set(db, 'certificate_get_all_by_user',
+ mock_certificate_get_all_by_user)
+
+ self.mox.StubOutWithMock(crypto, 'revoke_cert')
+ crypto.revoke_cert(project_id, mox.IgnoreArg())
+
+ self.mox.ReplayAll()
+
+ crypto.revoke_certs_by_user(user_id)
+
+ self.mox.VerifyAll()
+
+ def test_revoke_certs_by_project(self):
+ user_id = 'test_user'
+ project_id = 2
+ file_name = 'test_file'
+
+ def mock_certificate_get_all_by_project(context, project_id):
+
+ return [{"user_id": user_id, "project_id": project_id,
+ "file_name": file_name}]
+
+ self.stubs.Set(db, 'certificate_get_all_by_project',
+ mock_certificate_get_all_by_project)
+
+ self.mox.StubOutWithMock(crypto, 'revoke_cert')
+ crypto.revoke_cert(project_id, mox.IgnoreArg())
+
+ self.mox.ReplayAll()
+
+ crypto.revoke_certs_by_project(project_id)
+
+ self.mox.VerifyAll()
diff --git a/nova/tests/test_host_filter.py b/nova/tests/test_host_filter.py
index 2ec048497..3361c7b73 100644
--- a/nova/tests/test_host_filter.py
+++ b/nova/tests/test_host_filter.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
"""
-Tests For Scheduler Host Filter Drivers.
+Tests For Scheduler Host Filters.
"""
import json
@@ -31,7 +31,7 @@ class FakeZoneManager:
class HostFilterTestCase(test.TestCase):
- """Test case for host filter drivers."""
+ """Test case for host filters."""
def _host_caps(self, multiplier):
# Returns host capabilities in the following way:
@@ -57,8 +57,8 @@ class HostFilterTestCase(test.TestCase):
'host_name-label': 'xs-%s' % multiplier}
def setUp(self):
- self.old_flag = FLAGS.default_host_filter_driver
- FLAGS.default_host_filter_driver = \
+ self.old_flag = FLAGS.default_host_filter
+ FLAGS.default_host_filter = \
'nova.scheduler.host_filter.AllHostsFilter'
self.instance_type = dict(name='tiny',
memory_mb=50,
@@ -76,51 +76,52 @@ class HostFilterTestCase(test.TestCase):
self.zone_manager.service_states = states
def tearDown(self):
- FLAGS.default_host_filter_driver = self.old_flag
+ FLAGS.default_host_filter = self.old_flag
- def test_choose_driver(self):
- # Test default driver ...
- driver = host_filter.choose_driver()
- self.assertEquals(driver._full_name(),
+ def test_choose_filter(self):
+ # Test default filter ...
+ hf = host_filter.choose_host_filter()
+ self.assertEquals(hf._full_name(),
'nova.scheduler.host_filter.AllHostsFilter')
- # Test valid driver ...
- driver = host_filter.choose_driver(
- 'nova.scheduler.host_filter.FlavorFilter')
- self.assertEquals(driver._full_name(),
- 'nova.scheduler.host_filter.FlavorFilter')
- # Test invalid driver ...
+ # Test valid filter ...
+ hf = host_filter.choose_host_filter(
+ 'nova.scheduler.host_filter.InstanceTypeFilter')
+ self.assertEquals(hf._full_name(),
+ 'nova.scheduler.host_filter.InstanceTypeFilter')
+ # Test invalid filter ...
try:
- host_filter.choose_driver('does not exist')
- self.fail("Should not find driver")
- except exception.SchedulerHostFilterDriverNotFound:
+ host_filter.choose_host_filter('does not exist')
+ self.fail("Should not find host filter.")
+ except exception.SchedulerHostFilterNotFound:
pass
- def test_all_host_driver(self):
- driver = host_filter.AllHostsFilter()
- cooked = driver.instance_type_to_filter(self.instance_type)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ def test_all_host_filter(self):
+ hf = host_filter.AllHostsFilter()
+ cooked = hf.instance_type_to_filter(self.instance_type)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(10, len(hosts))
for host, capabilities in hosts:
self.assertTrue(host.startswith('host'))
- def test_flavor_driver(self):
- driver = host_filter.FlavorFilter()
+ def test_instance_type_filter(self):
+ hf = host_filter.InstanceTypeFilter()
# filter all hosts that can support 50 ram and 500 disk
- name, cooked = driver.instance_type_to_filter(self.instance_type)
- self.assertEquals('nova.scheduler.host_filter.FlavorFilter', name)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ name, cooked = hf.instance_type_to_filter(self.instance_type)
+ self.assertEquals('nova.scheduler.host_filter.InstanceTypeFilter',
+ name)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(6, len(hosts))
just_hosts = [host for host, caps in hosts]
just_hosts.sort()
self.assertEquals('host05', just_hosts[0])
self.assertEquals('host10', just_hosts[5])
- def test_json_driver(self):
- driver = host_filter.JsonFilter()
+ def test_json_filter(self):
+ hf = host_filter.JsonFilter()
# filter all hosts that can support 50 ram and 500 disk
- name, cooked = driver.instance_type_to_filter(self.instance_type)
+ name, cooked = hf.instance_type_to_filter(self.instance_type)
self.assertEquals('nova.scheduler.host_filter.JsonFilter', name)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(6, len(hosts))
just_hosts = [host for host, caps in hosts]
just_hosts.sort()
@@ -132,12 +133,16 @@ class HostFilterTestCase(test.TestCase):
raw = ['or',
['and',
['<', '$compute.host_memory_free', 30],
- ['<', '$compute.disk_available', 300]],
+ ['<', '$compute.disk_available', 300],
+ ],
['and',
['>', '$compute.host_memory_free', 70],
- ['>', '$compute.disk_available', 700]]]
+ ['>', '$compute.disk_available', 700],
+ ],
+ ]
+
cooked = json.dumps(raw)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(5, len(hosts))
just_hosts = [host for host, caps in hosts]
@@ -146,9 +151,10 @@ class HostFilterTestCase(test.TestCase):
self.assertEquals('host%02d' % index, host)
raw = ['not',
- ['=', '$compute.host_memory_free', 30], ]
+ ['=', '$compute.host_memory_free', 30],
+ ]
cooked = json.dumps(raw)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(9, len(hosts))
just_hosts = [host for host, caps in hosts]
@@ -158,7 +164,7 @@ class HostFilterTestCase(test.TestCase):
raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100]
cooked = json.dumps(raw)
- hosts = driver.filter_hosts(self.zone_manager, cooked)
+ hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(5, len(hosts))
just_hosts = [host for host, caps in hosts]
@@ -170,30 +176,30 @@ class HostFilterTestCase(test.TestCase):
raw = ['unknown command', ]
cooked = json.dumps(raw)
try:
- driver.filter_hosts(self.zone_manager, cooked)
+ hf.filter_hosts(self.zone_manager, cooked)
self.fail("Should give KeyError")
except KeyError, e:
pass
- self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps([])))
- self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps({})))
- self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps(
+ self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([])))
+ self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({})))
+ self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps(
['not', True, False, True, False])))
try:
- driver.filter_hosts(self.zone_manager, json.dumps(
+ hf.filter_hosts(self.zone_manager, json.dumps(
'not', True, False, True, False))
self.fail("Should give KeyError")
except KeyError, e:
pass
- self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
- ['=', '$foo', 100])))
- self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
- ['=', '$.....', 100])))
- self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
- ['>', ['and', ['or', ['not', ['<', ['>=',
- ['<=', ['in', ]]]]]]]])))
+ self.assertFalse(hf.filter_hosts(self.zone_manager,
+ json.dumps(['=', '$foo', 100])))
+ self.assertFalse(hf.filter_hosts(self.zone_manager,
+ json.dumps(['=', '$.....', 100])))
+ self.assertFalse(hf.filter_hosts(self.zone_manager,
+ json.dumps(
+ ['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]])))
- self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
- ['=', {}, ['>', '$missing....foo']])))
+ self.assertFalse(hf.filter_hosts(self.zone_manager,
+ json.dumps(['=', {}, ['>', '$missing....foo']])))
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 35a2fe082..43ab406a0 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -73,14 +73,14 @@ def _setup_networking(instance_id, ip='1.2.3.4'):
network_ref = db.project_get_networks(ctxt,
'fake',
associate=True)[0]
- mac_address = {'address': '56:12:12:12:12:12',
- 'network_id': network_ref['id'],
- 'instance_id': instance_id}
- mac_ref = db.mac_address_create(ctxt, mac_address)
+ vif = {'address': '56:12:12:12:12:12',
+ 'network_id': network_ref['id'],
+ 'instance_id': instance_id}
+ vif_ref = db.virtual_interface_create(ctxt, vif)
fixed_ip = {'address': ip,
'network_id': network_ref['id'],
- 'mac_address_id': mac_ref['id']}
+ 'virtual_interface_id': vif_ref['id']}
db.fixed_ip_create(ctxt, fixed_ip)
db.fixed_ip_update(ctxt, ip, {'allocated': True,
'instance_id': instance_id})
@@ -182,7 +182,6 @@ class LibvirtConnTestCase(test.TestCase):
test_instance = {'memory_kb': '1024000',
'basepath': '/some/path',
'bridge_name': 'br100',
- 'mac_address': '02:12:34:46:56:67',
'vcpus': 2,
'project_id': 'fake',
'bridge': 'br101',
@@ -296,23 +295,27 @@ class LibvirtConnTestCase(test.TestCase):
self.assertTrue(params.find('PROJNETV6') > -1)
self.assertTrue(params.find('PROJMASKV6') > -1)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_ramdisk_no_kernel(self):
instance_data = dict(self.test_instance)
self._check_xml_and_uri(instance_data,
expect_kernel=False, expect_ramdisk=False)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_ramdisk(self):
instance_data = dict(self.test_instance)
instance_data['kernel_id'] = 'aki-deadbeef'
self._check_xml_and_uri(instance_data,
expect_kernel=True, expect_ramdisk=False)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_no_kernel(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
self._check_xml_and_uri(instance_data,
expect_kernel=False, expect_ramdisk=False)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
@@ -320,6 +323,7 @@ class LibvirtConnTestCase(test.TestCase):
self._check_xml_and_uri(instance_data,
expect_kernel=True, expect_ramdisk=True)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_xml_and_uri_rescue(self):
instance_data = dict(self.test_instance)
instance_data['ramdisk_id'] = 'ari-deadbeef'
@@ -327,6 +331,7 @@ class LibvirtConnTestCase(test.TestCase):
self._check_xml_and_uri(instance_data, expect_kernel=True,
expect_ramdisk=True, rescue=True)
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_lxc_container_and_uri(self):
instance_data = dict(self.test_instance)
self._check_xml_and_container(instance_data)
@@ -431,13 +436,13 @@ class LibvirtConnTestCase(test.TestCase):
network_ref = db.project_get_networks(context.get_admin_context(),
self.project.id)[0]
- mac_address = {'address': '56:12:12:12:12:12',
- 'network_id': network_ref['id'],
- 'instance_id': instance_ref['id']}
- mac_ref = db.mac_address_create(self.context, mac_address)
+ vif = {'address': '56:12:12:12:12:12',
+ 'network_id': network_ref['id'],
+ 'instance_id': instance_ref['id']}
+ vif_ref = db.virtual_interface_create(self.context, vif)
fixed_ip = {'address': self.test_ip,
'network_id': network_ref['id'],
- 'mac_address_id': mac_ref['id']}
+ 'virtual_interface_id': vif_ref['id']}
ctxt = context.get_admin_context()
fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip)
@@ -881,9 +886,9 @@ class IptablesFirewallTestCase(test.TestCase):
return db.instance_create(self.context,
{'user_id': 'fake',
'project_id': 'fake',
- 'mac_address': '56:12:12:12:12:12',
'instance_type_id': 1})
+ @test.skip_test("skipping libvirt tests depends on get_network_info shim")
def test_static_filters(self):
instance_ref = self._create_instance_ref()
ip = '10.11.12.13'
@@ -891,14 +896,14 @@ class IptablesFirewallTestCase(test.TestCase):
network_ref = db.project_get_networks(self.context,
'fake',
associate=True)[0]
- mac_address = {'address': '56:12:12:12:12:12',
- 'network_id': network_ref['id'],
- 'instance_id': instance_ref['id']}
- mac_ref = db.mac_address_create(self.context, mac_address)
+ vif = {'address': '56:12:12:12:12:12',
+ 'network_id': network_ref['id'],
+ 'instance_id': instance_ref['id']}
+ vif_ref = db.virtual_interface_create(self.context, vif)
fixed_ip = {'address': ip,
'network_id': network_ref['id'],
- 'mac_address_id': mac_ref['id']}
+ 'virtual_interface_id': vif_ref['id']}
admin_ctxt = context.get_admin_context()
db.fixed_ip_create(admin_ctxt, fixed_ip)
db.fixed_ip_update(admin_ctxt, ip, {'allocated': True,
@@ -1165,7 +1170,6 @@ class NWFilterTestCase(test.TestCase):
return db.instance_create(self.context,
{'user_id': 'fake',
'project_id': 'fake',
- 'mac_address': '00:A0:C9:14:C8:29',
'instance_type_id': 1})
def _create_instance_type(self, params={}):
@@ -1260,6 +1264,7 @@ class NWFilterTestCase(test.TestCase):
"fake")
self.assertEquals(len(result), 3)
+ @test.skip_test("skip libvirt test project_get_network no longer exists")
def test_unfilter_instance_undefines_nwfilters(self):
admin_ctxt = context.get_admin_context()
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 948ce0248..15ea501fc 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -83,7 +83,6 @@ class XenAPIVolumeTestCase(test.TestCase):
'kernel_id': 2,
'ramdisk_id': 3,
'instance_type_id': '3', # m1.large
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': 'linux'}
def _create_volume(self, size='0'):
@@ -210,10 +209,23 @@ class XenAPIVMTestCase(test.TestCase):
'kernel_id': 2,
'ramdisk_id': 3,
'instance_type_id': '3', # m1.large
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': 'linux'}
+ network_info = [({'bridge': 'fa0', 'id': 0, 'injected': False},
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00',
+ 'rxtx_cap': 3})]
instance = db.instance_create(self.context, values)
- self.conn.spawn(instance, {})
+ self.conn.spawn(instance, network_info)
gt1 = eventlet.spawn(_do_build, 1, self.project.id, self.user.id)
gt2 = eventlet.spawn(_do_build, 2, self.project.id, self.user.id)
@@ -301,22 +313,22 @@ class XenAPIVMTestCase(test.TestCase):
if check_injection:
xenstore_data = self.vm['xenstore_data']
- key = 'vm-data/networking/aabbccddeeff'
+ key = 'vm-data/networking/DEADBEEF0000'
xenstore_value = xenstore_data[key]
tcpip_data = ast.literal_eval(xenstore_value)
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'}],
- 'mac': 'aa:bb:cc:dd:ee:ff',
- 'dns': ['10.0.0.2'],
- 'gateway': '10.0.0.1',
- 'gateway6': 'fe80::a00:1'})
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00'})
def check_vm_params_for_windows(self):
self.assertEquals(self.vm['platform']['nx'], 'true')
@@ -331,7 +343,7 @@ class XenAPIVMTestCase(test.TestCase):
def check_vm_params_for_linux(self):
self.assertEquals(self.vm['platform']['nx'], 'false')
- self.assertEquals(self.vm['PV_args'], 'clocksource=jiffies')
+ self.assertEquals(self.vm['PV_args'], '')
self.assertEquals(self.vm['PV_bootloader'], 'pygrub')
# check that these are not set
@@ -361,11 +373,24 @@ class XenAPIVMTestCase(test.TestCase):
'kernel_id': kernel_id,
'ramdisk_id': ramdisk_id,
'instance_type_id': instance_type_id,
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': os_type}
if create_record:
instance = db.instance_create(self.context, values)
- self.conn.spawn(instance, None)
+ network_info = [({'bridge': 'fa0', 'id': 0, 'injected': True},
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00',
+ 'rxtx_cap': 3})]
+ self.conn.spawn(instance, network_info)
else:
instance = db.instance_get(self.context, instance_id)
self.create_vm_record(self.conn, os_type, instance_id)
@@ -447,11 +472,11 @@ class XenAPIVMTestCase(test.TestCase):
index = config.index('auto eth0')
self.assertEquals(config[index + 1:index + 8], [
'iface eth0 inet static',
- 'address 10.0.0.3',
+ 'address 192.168.0.100',
'netmask 255.255.255.0',
- 'broadcast 10.0.0.255',
- 'gateway 10.0.0.1',
- 'dns-nameservers 10.0.0.2',
+ 'broadcast 192.168.0.255',
+ 'gateway 192.168.0.1',
+ 'dns-nameservers 192.168.0.1',
''])
self._tee_executed = True
return '', ''
@@ -554,7 +579,7 @@ class XenAPIVMTestCase(test.TestCase):
vif_rec = xenapi_fake.get_record('VIF', vif_ref)
self.assertEquals(vif_rec['qos_algorithm_type'], 'ratelimit')
self.assertEquals(vif_rec['qos_algorithm_params']['kbps'],
- str(4 * 1024))
+ str(3 * 1024))
def test_rescue(self):
self.flags(xenapi_inject_image=False)
@@ -587,10 +612,23 @@ class XenAPIVMTestCase(test.TestCase):
'kernel_id': 2,
'ramdisk_id': 3,
'instance_type_id': '3', # m1.large
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': 'linux'}
instance = db.instance_create(self.context, values)
- self.conn.spawn(instance, None)
+ network_info = [({'bridge': 'fa0', 'id': 0, 'injected': False},
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00',
+ 'rxtx_cap': 3})]
+ self.conn.spawn(instance, network_info)
return instance
@@ -662,7 +700,6 @@ class XenAPIMigrateInstance(test.TestCase):
'ramdisk_id': None,
'local_gb': 5,
'instance_type_id': '3', # m1.large
- 'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': 'linux'}
fake_utils.stub_out_utils_execute(self.stubs)
@@ -687,7 +724,22 @@ class XenAPIMigrateInstance(test.TestCase):
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
stubs.stubout_loopingcall_start(self.stubs)
conn = xenapi_conn.get_connection(False)
- conn.finish_resize(instance, dict(base_copy='hurr', cow='durr'))
+ network_info = [({'bridge': 'fa0', 'id': 0, 'injected': False},
+ {'broadcast': '192.168.0.255',
+ 'dns': ['192.168.0.1'],
+ 'gateway': '192.168.0.1',
+ 'gateway6': 'dead:beef::1',
+ 'ip6s': [{'enabled': '1',
+ 'ip': 'dead:beef::dcad:beff:feef:0',
+ 'netmask': '64'}],
+ 'ips': [{'enabled': '1',
+ 'ip': '192.168.0.100',
+ 'netmask': '255.255.255.0'}],
+ 'label': 'fake',
+ 'mac': 'DE:AD:BE:EF:00:00',
+ 'rxtx_cap': 3})]
+ conn.finish_resize(instance, dict(base_copy='hurr', cow='durr'),
+ network_info)
class XenAPIDetermineDiskImageTestCase(test.TestCase):
diff --git a/nova/virt/images.py b/nova/virt/images.py
index de7ac61df..40bf6107c 100644
--- a/nova/virt/images.py
+++ b/nova/virt/images.py
@@ -23,6 +23,7 @@ Handling of VM disk images.
from nova import context
from nova import flags
+from nova.image import glance as glance_image_service
import nova.image
from nova import log as logging
from nova import utils
@@ -42,13 +43,3 @@ def fetch(image_href, path, _user, _project):
elevated = context.get_admin_context()
metadata = image_service.get(elevated, image_id, image_file)
return metadata
-
-
-# TODO(vish): xenapi should use the glance client code directly instead
-# of retrieving the image using this method.
-def image_url(image):
- if FLAGS.image_service == "nova.image.glance.GlanceImageService":
- return "http://%s:%s/images/%s" % (FLAGS.glance_host,
- FLAGS.glance_port, image)
- return "http://%s:%s/_images/%s/image" % (FLAGS.s3_host, FLAGS.s3_port,
- image)
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 98668e6ae..11da221f2 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -33,6 +33,7 @@ import glance.client
from nova import exception
from nova import flags
import nova.image
+from nova.image import glance as glance_image_service
from nova import log as logging
from nova import utils
from nova.auth.manager import AuthManager
@@ -156,7 +157,6 @@ class VMHelper(HelperBase):
rec['PV_ramdisk'] = ramdisk
else:
# 2. Use kernel within the image
- rec['PV_args'] = 'clocksource=jiffies'
rec['PV_bootloader'] = 'pygrub'
else:
# 3. Using hardware virtualization
@@ -358,10 +358,12 @@ class VMHelper(HelperBase):
os_type = instance.os_type or FLAGS.default_os_type
+ glance_host, glance_port = \
+ glance_image_service.pick_glance_api_server()
params = {'vdi_uuids': vdi_uuids,
'image_id': image_id,
- 'glance_host': FLAGS.glance_host,
- 'glance_port': FLAGS.glance_port,
+ 'glance_host': glance_host,
+ 'glance_port': glance_port,
'sr_path': cls.get_sr_path(session),
'os_type': os_type}
@@ -409,9 +411,11 @@ class VMHelper(HelperBase):
# here (under Python 2.6+) and pass them as arguments
uuid_stack = [str(uuid.uuid4()) for i in xrange(2)]
+ glance_host, glance_port = \
+ glance_image_service.pick_glance_api_server()
params = {'image_id': image,
- 'glance_host': FLAGS.glance_host,
- 'glance_port': FLAGS.glance_port,
+ 'glance_host': glance_host,
+ 'glance_port': glance_port,
'uuid_stack': uuid_stack,
'sr_path': cls.get_sr_path(session)}
@@ -576,7 +580,8 @@ class VMHelper(HelperBase):
Returns: A single filename if image_type is KERNEL_RAMDISK
A list of dictionaries that describe VDIs, otherwise
"""
- url = images.image_url(image)
+ url = "http://%s:%s/_images/%s/image" % (FLAGS.s3_host, FLAGS.s3_port,
+ image)
LOG.debug(_("Asking xapi to fetch %(url)s as %(access)s") % locals())
if image_type == ImageType.KERNEL_RAMDISK:
fn = 'get_kernel'
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 6b2287cab..7931d117d 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -88,11 +88,12 @@ class VMOps(object):
vm_ref = VMHelper.lookup(self._session, instance.name)
self._start(instance, vm_ref)
- def finish_resize(self, instance, disk_info):
+ def finish_resize(self, instance, disk_info, network_info):
vdi_uuid = self.link_disks(instance, disk_info['base_copy'],
disk_info['cow'])
vm_ref = self._create_vm(instance,
- [dict(vdi_type='os', vdi_uuid=vdi_uuid)])
+ [dict(vdi_type='os', vdi_uuid=vdi_uuid)],
+ network_info)
self.resize_instance(instance, vdi_uuid)
self._spawn(instance, vm_ref)
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 764a3a5af..cbd4699ca 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -202,9 +202,9 @@ class XenAPIConnection(driver.ComputeDriver):
"""Reverts a resize, powering back on the instance"""
self._vmops.revert_resize(instance)
- def finish_resize(self, instance, disk_info):
+ def finish_resize(self, instance, disk_info, network_info):
"""Completes a resize, turning on the migrated instance"""
- self._vmops.finish_resize(instance, disk_info)
+ self._vmops.finish_resize(instance, disk_info, network_info)
def snapshot(self, instance, image_id):
""" Create snapshot from a running VM instance """