diff options
| author | Soren Hansen <soren.hansen@rackspace.com> | 2010-10-12 22:52:10 +0200 |
|---|---|---|
| committer | Soren Hansen <soren.hansen@rackspace.com> | 2010-10-12 22:52:10 +0200 |
| commit | e2b7c99c6266b24dc8b53c47db3587aebd2381fe (patch) | |
| tree | 67120b7a4e14cfc244fe3159447366bb7420e220 /nova | |
| parent | 5be81520196c21aa9b60425bca7bf49935772cd1 (diff) | |
| parent | 4f529fe118283164ccb2756f2001805c69c1cc4a (diff) | |
Merge trunk
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/api/__init__.py | 30 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 13 | ||||
| -rw-r--r-- | nova/api/openstack/__init__.py (renamed from nova/api/rackspace/__init__.py) | 26 | ||||
| -rw-r--r-- | nova/api/openstack/_id_translator.py (renamed from nova/api/rackspace/_id_translator.py) | 0 | ||||
| -rw-r--r-- | nova/api/openstack/auth.py (renamed from nova/api/rackspace/auth.py) | 4 | ||||
| -rw-r--r-- | nova/api/openstack/backup_schedules.py (renamed from nova/api/rackspace/backup_schedules.py) | 3 | ||||
| -rw-r--r-- | nova/api/openstack/context.py (renamed from nova/api/rackspace/context.py) | 0 | ||||
| -rw-r--r-- | nova/api/openstack/faults.py (renamed from nova/api/rackspace/faults.py) | 0 | ||||
| -rw-r--r-- | nova/api/openstack/flavors.py (renamed from nova/api/rackspace/flavors.py) | 8 | ||||
| -rw-r--r-- | nova/api/openstack/images.py (renamed from nova/api/rackspace/images.py) | 16 | ||||
| -rw-r--r-- | nova/api/openstack/notes.txt (renamed from nova/api/rackspace/notes.txt) | 4 | ||||
| -rw-r--r-- | nova/api/openstack/ratelimiting/__init__.py (renamed from nova/api/rackspace/ratelimiting/__init__.py) | 0 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py (renamed from nova/api/rackspace/servers.py) | 38 | ||||
| -rw-r--r-- | nova/api/openstack/sharedipgroups.py (renamed from nova/api/rackspace/sharedipgroups.py) | 0 | ||||
| -rw-r--r-- | nova/auth/manager.py | 5 | ||||
| -rw-r--r-- | nova/compute/manager.py | 2 | ||||
| -rw-r--r-- | nova/db/api.py | 6 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 6 | ||||
| -rw-r--r-- | nova/image/service.py | 16 | ||||
| -rw-r--r-- | nova/objectstore/image.py | 10 | ||||
| -rw-r--r-- | nova/rpc.py | 1 | ||||
| -rw-r--r-- | nova/tests/api/__init__.py | 10 | ||||
| -rw-r--r-- | nova/tests/api/openstack/__init__.py (renamed from nova/tests/api/rackspace/__init__.py) | 4 | ||||
| -rw-r--r-- | nova/tests/api/openstack/fakes.py (renamed from nova/tests/api/rackspace/fakes.py) | 15 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_auth.py (renamed from nova/tests/api/rackspace/test_auth.py) | 8 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_faults.py (renamed from nova/tests/api/rackspace/test_faults.py) | 2 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_flavors.py (renamed from nova/tests/api/rackspace/test_flavors.py) | 4 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_images.py (renamed from nova/tests/api/rackspace/test_images.py) | 4 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_ratelimiting.py (renamed from nova/api/rackspace/ratelimiting/tests.py) | 2 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_servers.py (renamed from nova/tests/api/rackspace/test_servers.py) | 6 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_sharedipgroups.py (renamed from nova/tests/api/rackspace/test_sharedipgroups.py) | 2 | ||||
| -rw-r--r-- | nova/tests/bundle/1mb.manifest.xml | 2 | ||||
| -rw-r--r-- | nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml | 1 | ||||
| -rw-r--r-- | nova/tests/cloud_unittest.py | 2 | ||||
| -rw-r--r-- | nova/tests/objectstore_unittest.py | 29 | ||||
| -rw-r--r-- | nova/tests/virt_unittest.py | 65 | ||||
| -rw-r--r-- | nova/utils.py | 4 | ||||
| -rw-r--r-- | nova/virt/images.py | 1 |
38 files changed, 196 insertions, 153 deletions
diff --git a/nova/api/__init__.py b/nova/api/__init__.py index 744abd621..8ec7094d7 100644 --- a/nova/api/__init__.py +++ b/nova/api/__init__.py @@ -27,16 +27,16 @@ from nova import flags from nova import wsgi from nova.api import cloudpipe from nova.api import ec2 -from nova.api import rackspace +from nova.api import openstack from nova.api.ec2 import metadatarequesthandler -flags.DEFINE_string('rsapi_subdomain', 'rs', - 'subdomain running the RS API') +flags.DEFINE_string('osapi_subdomain', 'api', + 'subdomain running the OpenStack API') flags.DEFINE_string('ec2api_subdomain', 'ec2', 'subdomain running the EC2 API') flags.DEFINE_string('FAKE_subdomain', None, - 'set to rs or ec2 to fake the subdomain of the host for testing') + 'set to api or ec2 to fake the subdomain of the host for testing') FLAGS = flags.FLAGS @@ -44,21 +44,21 @@ class API(wsgi.Router): """Routes top-level requests to the appropriate controller.""" def __init__(self): - rsdomain = {'sub_domain': [FLAGS.rsapi_subdomain]} + osapidomain = {'sub_domain': [FLAGS.osapi_subdomain]} ec2domain = {'sub_domain': [FLAGS.ec2api_subdomain]} - # If someone wants to pretend they're hitting the RS subdomain - # on their local box, they can set FAKE_subdomain to 'rs', which - # removes subdomain restrictions from the RS routes below. - if FLAGS.FAKE_subdomain == 'rs': - rsdomain = {} + # If someone wants to pretend they're hitting the OSAPI subdomain + # on their local box, they can set FAKE_subdomain to 'api', which + # removes subdomain restrictions from the OpenStack API routes below. + if FLAGS.FAKE_subdomain == 'api': + osapidomain = {} elif FLAGS.FAKE_subdomain == 'ec2': ec2domain = {} mapper = routes.Mapper() mapper.sub_domains = True - mapper.connect("/", controller=self.rsapi_versions, - conditions=rsdomain) - mapper.connect("/v1.0/{path_info:.*}", controller=rackspace.API(), - conditions=rsdomain) + mapper.connect("/", controller=self.osapi_versions, + conditions=osapidomain) + mapper.connect("/v1.0/{path_info:.*}", controller=openstack.API(), + conditions=osapidomain) mapper.connect("/", controller=self.ec2api_versions, conditions=ec2domain) @@ -81,7 +81,7 @@ class API(wsgi.Router): super(API, self).__init__(mapper) @webob.dec.wsgify - def rsapi_versions(self, req): + def osapi_versions(self, req): """Respond to a request for all OpenStack API versions.""" response = { "versions": [ diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 65cbe20ea..d7b9280f2 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -258,9 +258,9 @@ class CloudController(object): def delete_security_group(self, context, group_name, **kwargs): return True - def get_console_output(self, context, ec2_id_list, **kwargs): - # ec2_id_list is passed in as a list of instances - ec2_id = ec2_id_list[0] + def get_console_output(self, context, instance_id, **kwargs): + # instance_id is passed in as a list of instances + ec2_id = instance_id[0] internal_id = ec2_id_to_internal_id(ec2_id) instance_ref = db.instance_get_by_internal_id(context, internal_id) output = rpc.call('%s.%s' % (FLAGS.compute_topic, @@ -664,7 +664,12 @@ class CloudController(object): return self._format_run_instances(context, reservation_id) - def terminate_instances(self, context, ec2_id_list, **kwargs): + def terminate_instances(self, context, instance_id, **kwargs): + """Terminate each instance in instance_id, which is a list of ec2 ids. + + instance_id is a kwarg so its name cannot be modified. + """ + ec2_id_list = instance_id logging.debug("Going to start terminating instances") for id_str in ec2_id_list: internal_id = ec2_id_to_internal_id(id_str) diff --git a/nova/api/rackspace/__init__.py b/nova/api/openstack/__init__.py index 89a4693ad..5e81ba2bd 100644 --- a/nova/api/rackspace/__init__.py +++ b/nova/api/openstack/__init__.py @@ -17,7 +17,7 @@ # under the License. """ -WSGI middleware for Rackspace API controllers. +WSGI middleware for OpenStack API controllers. """ import json @@ -31,30 +31,30 @@ import webob from nova import flags from nova import utils from nova import wsgi -from nova.api.rackspace import faults -from nova.api.rackspace import backup_schedules -from nova.api.rackspace import flavors -from nova.api.rackspace import images -from nova.api.rackspace import ratelimiting -from nova.api.rackspace import servers -from nova.api.rackspace import sharedipgroups +from nova.api.openstack import faults +from nova.api.openstack import backup_schedules +from nova.api.openstack import flavors +from nova.api.openstack import images +from nova.api.openstack import ratelimiting +from nova.api.openstack import servers +from nova.api.openstack import sharedipgroups from nova.auth import manager FLAGS = flags.FLAGS flags.DEFINE_string('nova_api_auth', - 'nova.api.rackspace.auth.BasicApiAuthManager', - 'The auth mechanism to use for the Rackspace API implemenation') + 'nova.api.openstack.auth.BasicApiAuthManager', + 'The auth mechanism to use for the OpenStack API implemenation') class API(wsgi.Middleware): - """WSGI entry point for all Rackspace API requests.""" + """WSGI entry point for all OpenStack API requests.""" def __init__(self): app = AuthMiddleware(RateLimitingMiddleware(APIRouter())) super(API, self).__init__(app) class AuthMiddleware(wsgi.Middleware): - """Authorize the rackspace API request or return an HTTP Forbidden.""" + """Authorize the openstack API request or return an HTTP Forbidden.""" def __init__(self, application): self.auth_driver = utils.import_class(FLAGS.nova_api_auth)() @@ -145,7 +145,7 @@ class RateLimitingMiddleware(wsgi.Middleware): class APIRouter(wsgi.Router): """ - Routes requests on the Rackspace API to the appropriate controller + Routes requests on the OpenStack API to the appropriate controller and method. """ diff --git a/nova/api/rackspace/_id_translator.py b/nova/api/openstack/_id_translator.py index 333aa8434..333aa8434 100644 --- a/nova/api/rackspace/_id_translator.py +++ b/nova/api/openstack/_id_translator.py diff --git a/nova/api/rackspace/auth.py b/nova/api/openstack/auth.py index c45156ebd..4c909293e 100644 --- a/nova/api/rackspace/auth.py +++ b/nova/api/openstack/auth.py @@ -11,7 +11,7 @@ from nova import db from nova import flags from nova import manager from nova import utils -from nova.api.rackspace import faults +from nova.api.openstack import faults FLAGS = flags.FLAGS @@ -19,7 +19,7 @@ class Context(object): pass class BasicApiAuthManager(object): - """ Implements a somewhat rudimentary version of Rackspace Auth""" + """ Implements a somewhat rudimentary version of OpenStack Auth""" def __init__(self, host=None, db_driver=None): if not host: diff --git a/nova/api/rackspace/backup_schedules.py b/nova/api/openstack/backup_schedules.py index cb83023bc..76ad6ef87 100644 --- a/nova/api/rackspace/backup_schedules.py +++ b/nova/api/openstack/backup_schedules.py @@ -19,8 +19,7 @@ import time from webob import exc from nova import wsgi -from nova.api.rackspace import _id_translator -from nova.api.rackspace import faults +from nova.api.openstack import faults import nova.image.service class Controller(wsgi.Controller): diff --git a/nova/api/rackspace/context.py b/nova/api/openstack/context.py index 77394615b..77394615b 100644 --- a/nova/api/rackspace/context.py +++ b/nova/api/openstack/context.py diff --git a/nova/api/rackspace/faults.py b/nova/api/openstack/faults.py index 32e5c866f..32e5c866f 100644 --- a/nova/api/rackspace/faults.py +++ b/nova/api/openstack/faults.py diff --git a/nova/api/rackspace/flavors.py b/nova/api/openstack/flavors.py index 916449854..793984a5d 100644 --- a/nova/api/rackspace/flavors.py +++ b/nova/api/openstack/flavors.py @@ -17,13 +17,13 @@ from webob import exc -from nova.api.rackspace import faults +from nova.api.openstack import faults from nova.compute import instance_types from nova import wsgi -import nova.api.rackspace +import nova.api.openstack class Controller(wsgi.Controller): - """Flavor controller for the Rackspace API.""" + """Flavor controller for the OpenStack API.""" _serialization_metadata = { 'application/xml': { @@ -41,7 +41,7 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all flavors in detail.""" items = [self.show(req, id)['flavor'] for id in self._all_ids()] - items = nova.api.rackspace.limited(items, req) + items = nova.api.openstack.limited(items, req) return dict(flavors=items) def show(self, req, id): diff --git a/nova/api/rackspace/images.py b/nova/api/openstack/images.py index d4ab8ce3c..aa438739c 100644 --- a/nova/api/rackspace/images.py +++ b/nova/api/openstack/images.py @@ -20,10 +20,9 @@ from webob import exc from nova import flags from nova import utils from nova import wsgi -from nova.api.rackspace import _id_translator -import nova.api.rackspace +import nova.api.openstack import nova.image.service -from nova.api.rackspace import faults +from nova.api.openstack import faults FLAGS = flags.FLAGS @@ -41,8 +40,6 @@ class Controller(wsgi.Controller): def __init__(self): self._service = utils.import_object(FLAGS.image_service) - self._id_translator = _id_translator.RackspaceAPIIdTranslator( - "image", self._service.__class__.__name__) def index(self, req): """Return all public images in brief.""" @@ -52,17 +49,12 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all public images in detail.""" data = self._service.index() - data = nova.api.rackspace.limited(data, req) - for img in data: - img['id'] = self._id_translator.to_rs_id(img['id']) + data = nova.api.openstack.limited(data, req) return dict(images=data) def show(self, req, id): """Return data about the given image id.""" - opaque_id = self._id_translator.from_rs_id(id) - img = self._service.show(opaque_id) - img['id'] = id - return dict(image=img) + return dict(image=self._service.show(id)) def delete(self, req, id): # Only public images are supported for now. diff --git a/nova/api/rackspace/notes.txt b/nova/api/openstack/notes.txt index e133bf5ea..2330f1002 100644 --- a/nova/api/rackspace/notes.txt +++ b/nova/api/openstack/notes.txt @@ -10,11 +10,11 @@ image ids are URIs. LocalImageService(ImageService): image ids are random strings. -RackspaceAPITranslationStore: +OpenstackAPITranslationStore: translates RS server/images/flavor/etc ids into formats required by a given ImageService strategy. -api.rackspace.images.Controller: +api.openstack.images.Controller: uses an ImageService strategy behind the scenes to do its fetching; it just converts int image id into a strategy-specific image id. diff --git a/nova/api/rackspace/ratelimiting/__init__.py b/nova/api/openstack/ratelimiting/__init__.py index f843bac0f..f843bac0f 100644 --- a/nova/api/rackspace/ratelimiting/__init__.py +++ b/nova/api/openstack/ratelimiting/__init__.py diff --git a/nova/api/rackspace/servers.py b/nova/api/openstack/servers.py index b23867bbf..5d1ed9822 100644 --- a/nova/api/rackspace/servers.py +++ b/nova/api/openstack/servers.py @@ -25,27 +25,15 @@ from nova import rpc from nova import utils from nova import wsgi from nova.api import cloud -from nova.api.rackspace import _id_translator -from nova.api.rackspace import context -from nova.api.rackspace import faults +from nova.api.openstack import context +from nova.api.openstack import faults from nova.compute import instance_types from nova.compute import power_state -import nova.api.rackspace +import nova.api.openstack import nova.image.service FLAGS = flags.FLAGS -def _instance_id_translator(): - """ Helper method for initializing an id translator for Rackspace instance - ids """ - return _id_translator.RackspaceAPIIdTranslator( "instance", 'nova') - -def _image_service(): - """ Helper method for initializing the image id translator """ - service = utils.import_object(FLAGS.image_service) - return (service, _id_translator.RackspaceAPIIdTranslator( - "image", service.__class__.__name__)) - def _filter_params(inst_dict): """ Extracts all updatable parameters for a server update request """ keys = dict(name='name', admin_pass='adminPass') @@ -60,7 +48,7 @@ def _entity_list(entities): return dict(servers=entities) def _entity_detail(inst): - """ Maps everything to Rackspace-like attributes for return""" + """ Maps everything to valid attributes for return""" power_mapping = { power_state.NOSTATE: 'build', power_state.RUNNING: 'active', @@ -90,7 +78,7 @@ def _entity_inst(inst): return dict(server=dict(id=inst['id'], name=inst['server_name'])) class Controller(wsgi.Controller): - """ The Server API controller for the Openstack API """ + """ The Server API controller for the OpenStack API """ _serialization_metadata = { 'application/xml': { @@ -122,7 +110,7 @@ class Controller(wsgi.Controller): """ user_id = req.environ['nova.context']['user']['id'] instance_list = self.db_driver.instance_get_all_by_user(None, user_id) - limited_list = nova.api.rackspace.limited(instance_list, req) + limited_list = nova.api.openstack.limited(instance_list, req) res = [entity_maker(inst)['server'] for inst in limited_list] return _entity_list(res) @@ -182,13 +170,16 @@ class Controller(wsgi.Controller): def action(self, req, id): """ multi-purpose method used to reboot, rebuild, and resize a server """ + user_id = req.environ['nova.context']['user']['id'] input_dict = self._deserialize(req.body, req) try: reboot_type = input_dict['reboot']['type'] except Exception: raise faults.Fault(webob.exc.HTTPNotImplemented()) - opaque_id = _instance_id_translator().from_rs_id(int(id)) - cloud.reboot(opaque_id) + inst_ref = self.db.instance_get_by_internal_id(None, int(id)) + if not inst_ref or (inst_ref and not inst_ref.user_id == user_id): + return faults.Fault(exc.HTTPUnprocessableEntity()) + cloud.reboot(id) def _build_server_instance(self, req, env): """Build instance data structure and save it to the data store.""" @@ -205,16 +196,15 @@ class Controller(wsgi.Controller): image_id = env['server']['imageId'] - img_service, image_id_trans = _image_service() + img_service = utils.import_object(FLAGS.image_service) - opaque_image_id = image_id_trans.to_rs_id(image_id) - image = img_service.show(opaque_image_id) + image = img_service.show(image_id) if not image: raise Exception, "Image not found" inst['server_name'] = env['server']['name'] - inst['image_id'] = opaque_image_id + inst['image_id'] = image_id inst['user_id'] = user_id inst['launch_time'] = ltime inst['mac_address'] = utils.generate_mac() diff --git a/nova/api/rackspace/sharedipgroups.py b/nova/api/openstack/sharedipgroups.py index 4d2d0ede1..4d2d0ede1 100644 --- a/nova/api/rackspace/sharedipgroups.py +++ b/nova/api/openstack/sharedipgroups.py diff --git a/nova/auth/manager.py b/nova/auth/manager.py index ce8a294df..49235c910 100644 --- a/nova/auth/manager.py +++ b/nova/auth/manager.py @@ -653,7 +653,10 @@ class AuthManager(object): zippy.writestr(FLAGS.credential_key_file, private_key) zippy.writestr(FLAGS.credential_cert_file, signed_cert) - (vpn_ip, vpn_port) = self.get_project_vpn_data(project) + try: + (vpn_ip, vpn_port) = self.get_project_vpn_data(project) + except exception.NotFound: + vpn_ip = None if vpn_ip: configfile = open(FLAGS.vpn_client_template, "r") s = string.Template(configfile.read()) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d0d76afc8..e28d5c465 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -67,7 +67,7 @@ class ComputeManager(manager.Manager): def run_instance(self, context, instance_id, **_kwargs): """Launch a new instance with specified options.""" instance_ref = self.db.instance_get(context, instance_id) - if instance_ref['internal_id'] in self.driver.list_instances(): + if instance_ref['name'] in self.driver.list_instances(): raise exception.Error("Instance has already been created") logging.debug("instance %s: starting...", instance_id) project_id = instance_ref['project_id'] diff --git a/nova/db/api.py b/nova/db/api.py index 0d324dc71..2f0879c5a 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -432,7 +432,11 @@ def network_update(context, network_id, values): def project_get_network(context, project_id): - """Return the network associated with the project.""" + """Return the network associated with the project. + + Raises NotFound if no such network can be found. + + """ return IMPL.project_get_network(context, project_id) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index ebcb73413..9809eb7a7 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,7 +25,7 @@ import datetime # TODO(vish): clean up these imports from sqlalchemy.orm import relationship, backref, exc, object_mapper -from sqlalchemy import Column, Integer, String +from sqlalchemy import Column, PickleType, Integer, String from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declarative_base @@ -152,7 +152,7 @@ class Instance(BASE, NovaBase): __tablename__ = 'instances' __prefix__ = 'i' id = Column(Integer, primary_key=True) - internal_id = Column(Integer, unique=True) + internal_id = Column(PickleType(mutable=False), unique=True) admin_pass = Column(String(255)) @@ -169,7 +169,7 @@ class Instance(BASE, NovaBase): @property def name(self): - return self.internal_id + return "instance-%d" % self.internal_id image_id = Column(String(255)) kernel_id = Column(String(255)) diff --git a/nova/image/service.py b/nova/image/service.py index 2e570e8a4..5276e1312 100644 --- a/nova/image/service.py +++ b/nova/image/service.py @@ -225,7 +225,9 @@ class GlanceImageService(BaseImageService): class LocalImageService(BaseImageService): - """Image service storing images to local disk.""" + """Image service storing images to local disk. + + It assumes that image_ids are integers.""" def __init__(self): self._path = "/tmp/nova/images" @@ -234,12 +236,12 @@ class LocalImageService(BaseImageService): except OSError: # exists pass - def _path_to(self, image_id=''): - return os.path.join(self._path, image_id) + def _path_to(self, image_id): + return os.path.join(self._path, str(image_id)) def _ids(self): """The list of all image ids.""" - return os.listdir(self._path) + return [int(i) for i in os.listdir(self._path)] def index(self): return [ self.show(id) for id in self._ids() ] @@ -254,7 +256,7 @@ class LocalImageService(BaseImageService): """ Store the image data and return the new image id. """ - id = ''.join(random.choice(string.letters) for _ in range(20)) + id = random.randint(0, 2**32-1) data['id'] = id self.update(id, data) return id @@ -279,5 +281,5 @@ class LocalImageService(BaseImageService): """ Clears out all images in local directory """ - for f in os.listdir(self._path): - os.unlink(self._path_to(f)) + for id in self._ids(): + os.unlink(self._path_to(id)) diff --git a/nova/objectstore/image.py b/nova/objectstore/image.py index def1b8167..c01b041bb 100644 --- a/nova/objectstore/image.py +++ b/nova/objectstore/image.py @@ -191,14 +191,14 @@ class Image(object): if kernel_id == 'true': image_type = 'kernel' except: - pass + kernel_id = None try: ramdisk_id = manifest.find("machine_configuration/ramdisk_id").text if ramdisk_id == 'true': image_type = 'ramdisk' except: - pass + ramdisk_id = None info = { 'imageId': image_id, @@ -209,6 +209,12 @@ class Image(object): 'imageType' : image_type } + if kernel_id: + info['kernelId'] = kernel_id + + if ramdisk_id: + info['ramdiskId'] = ramdisk_id + def write_state(state): info['imageState'] = state with open(os.path.join(image_path, 'info.json'), "w") as f: diff --git a/nova/rpc.py b/nova/rpc.py index 782c76765..447ad3b93 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -109,6 +109,7 @@ class Consumer(messaging.Consumer): self.failed_connection = True def attach_to_eventlet(self): + """Only needed for unit tests!""" def fetch_repeatedly(): while True: self.fetch(enable_callbacks=True) diff --git a/nova/tests/api/__init__.py b/nova/tests/api/__init__.py index ec76aa827..f051e2390 100644 --- a/nova/tests/api/__init__.py +++ b/nova/tests/api/__init__.py @@ -44,9 +44,9 @@ class Test(unittest.TestCase): req = webob.Request.blank(url, environ_keys) return req.get_response(api.API()) - def test_rackspace(self): - self.stubs.Set(api.rackspace, 'API', APIStub) - result = self._request('/v1.0/cloud', 'rs') + def test_openstack(self): + self.stubs.Set(api.openstack, 'API', APIStub) + result = self._request('/v1.0/cloud', 'api') self.assertEqual(result.body, "/cloud") def test_ec2(self): @@ -56,12 +56,12 @@ class Test(unittest.TestCase): def test_not_found(self): self.stubs.Set(api.ec2, 'API', APIStub) - self.stubs.Set(api.rackspace, 'API', APIStub) + self.stubs.Set(api.openstack, 'API', APIStub) result = self._request('/test/cloud', 'ec2') self.assertNotEqual(result.body, "/cloud") def test_query_api_versions(self): - result = self._request('/', 'rs') + result = self._request('/', 'api') self.assertTrue('CURRENT' in result.body) def test_metadata(self): diff --git a/nova/tests/api/rackspace/__init__.py b/nova/tests/api/openstack/__init__.py index 1834f91b1..b534897f5 100644 --- a/nova/tests/api/rackspace/__init__.py +++ b/nova/tests/api/openstack/__init__.py @@ -17,8 +17,8 @@ import unittest -from nova.api.rackspace import limited -from nova.api.rackspace import RateLimitingMiddleware +from nova.api.openstack import limited +from nova.api.openstack import RateLimitingMiddleware from nova.tests.api.fakes import APIStub from webob import Request diff --git a/nova/tests/api/rackspace/fakes.py b/nova/tests/api/openstack/fakes.py index b5fba2dfa..34bc1f2a9 100644 --- a/nova/tests/api/rackspace/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -27,8 +27,7 @@ from nova import auth from nova import utils from nova import flags from nova import exception as exc -import nova.api.rackspace.auth -import nova.api.rackspace._id_translator +import nova.api.openstack.auth from nova.image import service from nova.wsgi import Router @@ -84,21 +83,21 @@ def stub_out_auth(stubs): def fake_auth_init(self, app): self.application = app - stubs.Set(nova.api.rackspace.AuthMiddleware, + stubs.Set(nova.api.openstack.AuthMiddleware, '__init__', fake_auth_init) - stubs.Set(nova.api.rackspace.AuthMiddleware, + stubs.Set(nova.api.openstack.AuthMiddleware, '__call__', fake_wsgi) def stub_out_rate_limiting(stubs): def fake_rate_init(self, app): - super(nova.api.rackspace.RateLimitingMiddleware, self).__init__(app) + super(nova.api.openstack.RateLimitingMiddleware, self).__init__(app) self.application = app - stubs.Set(nova.api.rackspace.RateLimitingMiddleware, + stubs.Set(nova.api.openstack.RateLimitingMiddleware, '__init__', fake_rate_init) - stubs.Set(nova.api.rackspace.RateLimitingMiddleware, + stubs.Set(nova.api.openstack.RateLimitingMiddleware, '__call__', fake_wsgi) @@ -106,7 +105,7 @@ def stub_out_networking(stubs): def get_my_ip(): return '127.0.0.1' stubs.Set(nova.utils, 'get_my_ip', get_my_ip) - FLAGS.FAKE_subdomain = 'rs' + FLAGS.FAKE_subdomain = 'api' def stub_out_glance(stubs): diff --git a/nova/tests/api/rackspace/test_auth.py b/nova/tests/api/openstack/test_auth.py index 374cfe42b..d2ba80243 100644 --- a/nova/tests/api/rackspace/test_auth.py +++ b/nova/tests/api/openstack/test_auth.py @@ -6,14 +6,14 @@ import webob import webob.dec import nova.api -import nova.api.rackspace.auth +import nova.api.openstack.auth from nova import auth -from nova.tests.api.rackspace import fakes +from nova.tests.api.openstack import fakes class Test(unittest.TestCase): def setUp(self): self.stubs = stubout.StubOutForTesting() - self.stubs.Set(nova.api.rackspace.auth.BasicApiAuthManager, + self.stubs.Set(nova.api.openstack.auth.BasicApiAuthManager, '__init__', fakes.fake_auth_init) fakes.FakeAuthManager.auth_data = {} fakes.FakeAuthDatabase.data = {} @@ -55,7 +55,7 @@ class Test(unittest.TestCase): self.assertEqual(result.headers['X-Storage-Url'], "") token = result.headers['X-Auth-Token'] - self.stubs.Set(nova.api.rackspace, 'APIRouter', + self.stubs.Set(nova.api.openstack, 'APIRouter', fakes.FakeRouter) req = webob.Request.blank('/v1.0/fake') req.headers['X-Auth-Token'] = token diff --git a/nova/tests/api/rackspace/test_faults.py b/nova/tests/api/openstack/test_faults.py index b2931bc98..70a811469 100644 --- a/nova/tests/api/rackspace/test_faults.py +++ b/nova/tests/api/openstack/test_faults.py @@ -3,7 +3,7 @@ import webob import webob.dec import webob.exc -from nova.api.rackspace import faults +from nova.api.openstack import faults class TestFaults(unittest.TestCase): diff --git a/nova/tests/api/rackspace/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index affdd2406..8dd4d1f29 100644 --- a/nova/tests/api/rackspace/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -21,8 +21,8 @@ import stubout import webob import nova.api -from nova.api.rackspace import flavors -from nova.tests.api.rackspace import fakes +from nova.api.openstack import flavors +from nova.tests.api.openstack import fakes class FlavorsTest(unittest.TestCase): diff --git a/nova/tests/api/rackspace/test_images.py b/nova/tests/api/openstack/test_images.py index a7f320b46..505fea3e2 100644 --- a/nova/tests/api/rackspace/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -22,8 +22,8 @@ import stubout from nova import exception from nova import utils -from nova.api.rackspace import images -from nova.tests.api.rackspace import fakes +from nova.api.openstack import images +from nova.tests.api.openstack import fakes class BaseImageServiceTests(): diff --git a/nova/api/rackspace/ratelimiting/tests.py b/nova/tests/api/openstack/test_ratelimiting.py index 4c9510917..ad9e67454 100644 --- a/nova/api/rackspace/ratelimiting/tests.py +++ b/nova/tests/api/openstack/test_ratelimiting.py @@ -4,7 +4,7 @@ import time import unittest import webob -import nova.api.rackspace.ratelimiting as ratelimiting +import nova.api.openstack.ratelimiting as ratelimiting class LimiterTest(unittest.TestCase): diff --git a/nova/tests/api/rackspace/test_servers.py b/nova/tests/api/openstack/test_servers.py index 57040621b..d1ee533b6 100644 --- a/nova/tests/api/rackspace/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -23,12 +23,12 @@ import webob from nova import db from nova import flags -import nova.api.rackspace -from nova.api.rackspace import servers +import nova.api.openstack +from nova.api.openstack import servers import nova.db.api from nova.db.sqlalchemy.models import Instance import nova.rpc -from nova.tests.api.rackspace import fakes +from nova.tests.api.openstack import fakes FLAGS = flags.FLAGS diff --git a/nova/tests/api/rackspace/test_sharedipgroups.py b/nova/tests/api/openstack/test_sharedipgroups.py index 31ce967d0..d199951d8 100644 --- a/nova/tests/api/rackspace/test_sharedipgroups.py +++ b/nova/tests/api/openstack/test_sharedipgroups.py @@ -19,7 +19,7 @@ import unittest import stubout -from nova.api.rackspace import sharedipgroups +from nova.api.openstack import sharedipgroups class SharedIpGroupsTest(unittest.TestCase): diff --git a/nova/tests/bundle/1mb.manifest.xml b/nova/tests/bundle/1mb.manifest.xml index dc3315957..01648a544 100644 --- a/nova/tests/bundle/1mb.manifest.xml +++ b/nova/tests/bundle/1mb.manifest.xml @@ -1 +1 @@ -<?xml version="1.0" ?><manifest><version>2007-10-10</version><bundler><name>euca-tools</name><version>1.2</version><release>31337</release></bundler><machine_configuration><architecture>x86_64</architecture></machine_configuration><image><name>1mb</name><user>42</user><type>machine</type><digest algorithm="SHA1">da39a3ee5e6b4b0d3255bfef95601890afd80709</digest><size>1048576</size><bundled_size>1136</bundled_size><ec2_encrypted_key algorithm="AES-128-CBC">33a2ea00dc64083dd9a10eb5e233635b42a7beb1670ab75452087d9de74c60aba1cd27c136fda56f62beb581de128fb1f10d072b9e556fd25e903107a57827c21f6ee8a93a4ff55b11311fcef217e3eefb07e81f71e88216f43b4b54029c1f2549f2925a839a73947d2d5aeecec4a62ece4af9156d557ae907978298296d9915</ec2_encrypted_key><user_encrypted_key algorithm="AES-128-CBC">4c11147fd8caf92447e90ce339928933d7579244c2f8ffb07cc0ea35f8738da8b90eff6c7a49671a84500e993e9462e4c36d5c19c0b3a2b397d035b4c0cce742b58e12552175d81d129b0425e9f71ebacb9aeb539fa9dd2ac36749fb82876f6902e5fb24b6ec19f35ec4c20acd50437fd30966e99c4d9a0647577970a8fa3023</user_encrypted_key><ec2_encrypted_iv>14bd082c9715f071160c69bbfb070f51d2ba1076775f1d988ccde150e515088156b248e4b5a64e46c4fe064feeeedfe14511f7fde478a51acb89f9b2f6c84b60593e5c3f792ba6b01fed9bf2158fdac03086374883b39d13a3ca74497eeaaf579fc3f26effc73bfd9446a2a8c4061f0874bfaca058905180e22d3d8881551cb3</ec2_encrypted_iv><user_encrypted_iv>8f7606f19f00e4e19535dd234b66b31b77e9c7bad3885d9c9efa75c863631fd4f82a009e17d789066d9cc6032a436f05384832f6d9a3283d3e63eab04fa0da5c8c87db9b17e854e842c3fb416507d067a266b44538125ce732e486098e8ebd1ca91fa3079f007fce7d14957a9b7e57282407ead3c6eb68fe975df3d83190021b</user_encrypted_iv><parts count="2"><part index="0"><filename>1mb.part.0</filename><digest algorithm="SHA1">c4413423cf7a57e71187e19bfd5cd4b514a64283</digest></part><part index="1"><filename>1mb.part.1</filename><digest algorithm="SHA1">9d4262e6589393d09a11a0332af169887bc2e57d</digest></part></parts></image><signature>4e00b5ba28114dda4a9df7eeae94be847ec46117a09a1cbe41e578660642f0660dda1776b39fb3bf826b6cfec019e2a5e9c566728d186b7400ebc989a30670eb1db26ce01e68bd9d3f31290370077a85b81c66b63c1e0d5499bac115c06c17a21a81b6d3a67ebbce6c17019095af7ab07f3796c708cc843e58efc12ddc788c5e</signature></manifest>
\ No newline at end of file +<?xml version="1.0" ?><manifest><version>2007-10-10</version><bundler><name>euca-tools</name><version>1.2</version><release>31337</release></bundler><machine_configuration><architecture>x86_64</architecture><kernel_id>aki-test</kernel_id><ramdisk_id>ari-test</ramdisk_id></machine_configuration><image><name>1mb</name><user>42</user><type>machine</type><digest algorithm="SHA1">da39a3ee5e6b4b0d3255bfef95601890afd80709</digest><size>1048576</size><bundled_size>1136</bundled_size><ec2_encrypted_key algorithm="AES-128-CBC">33a2ea00dc64083dd9a10eb5e233635b42a7beb1670ab75452087d9de74c60aba1cd27c136fda56f62beb581de128fb1f10d072b9e556fd25e903107a57827c21f6ee8a93a4ff55b11311fcef217e3eefb07e81f71e88216f43b4b54029c1f2549f2925a839a73947d2d5aeecec4a62ece4af9156d557ae907978298296d9915</ec2_encrypted_key><user_encrypted_key algorithm="AES-128-CBC">4c11147fd8caf92447e90ce339928933d7579244c2f8ffb07cc0ea35f8738da8b90eff6c7a49671a84500e993e9462e4c36d5c19c0b3a2b397d035b4c0cce742b58e12552175d81d129b0425e9f71ebacb9aeb539fa9dd2ac36749fb82876f6902e5fb24b6ec19f35ec4c20acd50437fd30966e99c4d9a0647577970a8fa3023</user_encrypted_key><ec2_encrypted_iv>14bd082c9715f071160c69bbfb070f51d2ba1076775f1d988ccde150e515088156b248e4b5a64e46c4fe064feeeedfe14511f7fde478a51acb89f9b2f6c84b60593e5c3f792ba6b01fed9bf2158fdac03086374883b39d13a3ca74497eeaaf579fc3f26effc73bfd9446a2a8c4061f0874bfaca058905180e22d3d8881551cb3</ec2_encrypted_iv><user_encrypted_iv>8f7606f19f00e4e19535dd234b66b31b77e9c7bad3885d9c9efa75c863631fd4f82a009e17d789066d9cc6032a436f05384832f6d9a3283d3e63eab04fa0da5c8c87db9b17e854e842c3fb416507d067a266b44538125ce732e486098e8ebd1ca91fa3079f007fce7d14957a9b7e57282407ead3c6eb68fe975df3d83190021b</user_encrypted_iv><parts count="2"><part index="0"><filename>1mb.part.0</filename><digest algorithm="SHA1">c4413423cf7a57e71187e19bfd5cd4b514a64283</digest></part><part index="1"><filename>1mb.part.1</filename><digest algorithm="SHA1">9d4262e6589393d09a11a0332af169887bc2e57d</digest></part></parts></image><signature>4e00b5ba28114dda4a9df7eeae94be847ec46117a09a1cbe41e578660642f0660dda1776b39fb3bf826b6cfec019e2a5e9c566728d186b7400ebc989a30670eb1db26ce01e68bd9d3f31290370077a85b81c66b63c1e0d5499bac115c06c17a21a81b6d3a67ebbce6c17019095af7ab07f3796c708cc843e58efc12ddc788c5e</signature></manifest> diff --git a/nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml b/nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml new file mode 100644 index 000000000..73d7ace00 --- /dev/null +++ b/nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml @@ -0,0 +1 @@ +<?xml version="1.0" ?><manifest><version>2007-10-10</version><bundler><name>euca-tools</name><version>1.2</version><release>31337</release></bundler><machine_configuration><architecture>x86_64</architecture></machine_configuration><image><name>1mb</name><user>42</user><type>machine</type><digest algorithm="SHA1">da39a3ee5e6b4b0d3255bfef95601890afd80709</digest><size>1048576</size><bundled_size>1136</bundled_size><ec2_encrypted_key algorithm="AES-128-CBC">33a2ea00dc64083dd9a10eb5e233635b42a7beb1670ab75452087d9de74c60aba1cd27c136fda56f62beb581de128fb1f10d072b9e556fd25e903107a57827c21f6ee8a93a4ff55b11311fcef217e3eefb07e81f71e88216f43b4b54029c1f2549f2925a839a73947d2d5aeecec4a62ece4af9156d557ae907978298296d9915</ec2_encrypted_key><user_encrypted_key algorithm="AES-128-CBC">4c11147fd8caf92447e90ce339928933d7579244c2f8ffb07cc0ea35f8738da8b90eff6c7a49671a84500e993e9462e4c36d5c19c0b3a2b397d035b4c0cce742b58e12552175d81d129b0425e9f71ebacb9aeb539fa9dd2ac36749fb82876f6902e5fb24b6ec19f35ec4c20acd50437fd30966e99c4d9a0647577970a8fa3023</user_encrypted_key><ec2_encrypted_iv>14bd082c9715f071160c69bbfb070f51d2ba1076775f1d988ccde150e515088156b248e4b5a64e46c4fe064feeeedfe14511f7fde478a51acb89f9b2f6c84b60593e5c3f792ba6b01fed9bf2158fdac03086374883b39d13a3ca74497eeaaf579fc3f26effc73bfd9446a2a8c4061f0874bfaca058905180e22d3d8881551cb3</ec2_encrypted_iv><user_encrypted_iv>8f7606f19f00e4e19535dd234b66b31b77e9c7bad3885d9c9efa75c863631fd4f82a009e17d789066d9cc6032a436f05384832f6d9a3283d3e63eab04fa0da5c8c87db9b17e854e842c3fb416507d067a266b44538125ce732e486098e8ebd1ca91fa3079f007fce7d14957a9b7e57282407ead3c6eb68fe975df3d83190021b</user_encrypted_iv><parts count="2"><part index="0"><filename>1mb.part.0</filename><digest algorithm="SHA1">c4413423cf7a57e71187e19bfd5cd4b514a64283</digest></part><part index="1"><filename>1mb.part.1</filename><digest algorithm="SHA1">9d4262e6589393d09a11a0332af169887bc2e57d</digest></part></parts></image><signature>4e00b5ba28114dda4a9df7eeae94be847ec46117a09a1cbe41e578660642f0660dda1776b39fb3bf826b6cfec019e2a5e9c566728d186b7400ebc989a30670eb1db26ce01e68bd9d3f31290370077a85b81c66b63c1e0d5499bac115c06c17a21a81b6d3a67ebbce6c17019095af7ab07f3796c708cc843e58efc12ddc788c5e</signature></manifest> diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py index 9a7709f9d..a677c56d7 100644 --- a/nova/tests/cloud_unittest.py +++ b/nova/tests/cloud_unittest.py @@ -99,7 +99,7 @@ class CloudTestCase(test.TrialTestCase): 'max_count': max_count } rv = yield self.cloud.run_instances(self.context, **kwargs) instance_id = rv['instancesSet'][0]['instanceId'] - output = yield self.cloud.get_console_output(self.context, [instance_id]) + output = yield self.cloud.get_console_output(context=self.context, instance_id=[instance_id]) self.assertEquals(b64decode(output['output']), 'FAKE CONSOLE OUTPUT') rv = yield self.cloud.terminate_instances(self.context, [instance_id]) diff --git a/nova/tests/objectstore_unittest.py b/nova/tests/objectstore_unittest.py index 5a599ff3a..eb2ee0406 100644 --- a/nova/tests/objectstore_unittest.py +++ b/nova/tests/objectstore_unittest.py @@ -133,13 +133,22 @@ class ObjectStoreTestCase(test.TrialTestCase): self.assertRaises(NotFound, objectstore.bucket.Bucket, 'new_bucket') def test_images(self): + self.do_test_images('1mb.manifest.xml', True, + 'image_bucket1', 'i-testing1') + + def test_images_no_kernel_or_ramdisk(self): + self.do_test_images('1mb.no_kernel_or_ramdisk.manifest.xml', + False, 'image_bucket2', 'i-testing2') + + def do_test_images(self, manifest_file, expect_kernel_and_ramdisk, + image_bucket, image_name): "Test the image API." self.context.user = self.auth_manager.get_user('user1') self.context.project = self.auth_manager.get_project('proj1') # create a bucket for our bundle - objectstore.bucket.Bucket.create('image_bucket', self.context) - bucket = objectstore.bucket.Bucket('image_bucket') + objectstore.bucket.Bucket.create(image_bucket, self.context) + bucket = objectstore.bucket.Bucket(image_bucket) # upload an image manifest/parts bundle_path = os.path.join(os.path.dirname(__file__), 'bundle') @@ -147,18 +156,28 @@ class ObjectStoreTestCase(test.TrialTestCase): bucket[os.path.basename(path)] = open(path, 'rb').read() # register an image - image.Image.register_aws_image('i-testing', - 'image_bucket/1mb.manifest.xml', + image.Image.register_aws_image(image_name, + '%s/%s' % (image_bucket, manifest_file), self.context) # verify image - my_img = image.Image('i-testing') + my_img = image.Image(image_name) result_image_file = os.path.join(my_img.path, 'image') self.assertEqual(os.stat(result_image_file).st_size, 1048576) sha = hashlib.sha1(open(result_image_file).read()).hexdigest() self.assertEqual(sha, '3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3') + if expect_kernel_and_ramdisk: + # Verify the default kernel and ramdisk are set + self.assertEqual(my_img.metadata['kernelId'], 'aki-test') + self.assertEqual(my_img.metadata['ramdiskId'], 'ari-test') + else: + # Verify that the default kernel and ramdisk (the one from FLAGS) + # doesn't get embedded in the metadata + self.assertFalse('kernelId' in my_img.metadata) + self.assertFalse('ramdiskId' in my_img.metadata) + # verify image permissions self.context.user = self.auth_manager.get_user('user2') self.context.project = self.auth_manager.get_project('proj2') diff --git a/nova/tests/virt_unittest.py b/nova/tests/virt_unittest.py index 2aab16809..730928f39 100644 --- a/nova/tests/virt_unittest.py +++ b/nova/tests/virt_unittest.py @@ -14,36 +14,52 @@ # License for the specific language governing permissions and limitations # under the License. +from xml.etree.ElementTree import fromstring as parseXml + from nova import flags from nova import test +from nova.auth import manager +# Needed to get FLAGS.instances_path defined: +from nova.compute import manager as compute_manager from nova.virt import libvirt_conn FLAGS = flags.FLAGS - class LibvirtConnTestCase(test.TrialTestCase): + def setUp(self): + self.manager = manager.AuthManager() + self.user = self.manager.create_user('fake', 'fake', 'fake', admin=True) + self.project = self.manager.create_project('fake', 'fake', 'fake') + FLAGS.instances_path = '' + def test_get_uri_and_template(self): - class MockDataModel(object): - def __init__(self): - self.datamodel = { 'name' : 'i-cafebabe', - 'memory_kb' : '1024000', - 'basepath' : '/some/path', - 'bridge_name' : 'br100', - 'mac_address' : '02:12:34:46:56:67', - 'vcpus' : 2 } + instance = { 'name' : 'i-cafebabe', + 'id' : 'i-cafebabe', + 'memory_kb' : '1024000', + 'basepath' : '/some/path', + 'bridge_name' : 'br100', + 'mac_address' : '02:12:34:46:56:67', + 'vcpus' : 2, + 'project_id' : 'fake', + 'ip_address' : '10.11.12.13', + 'bridge' : 'br101', + 'instance_type' : 'm1.small'} type_uri_map = { 'qemu' : ('qemu:///system', - [lambda s: '<domain type=\'qemu\'>' in s, - lambda s: 'type>hvm</type' in s, - lambda s: 'emulator>/usr/bin/kvm' not in s]), + [(lambda t: t.find('.').tag, 'domain'), + (lambda t: t.find('.').get('type'), 'qemu'), + (lambda t: t.find('./os/type').text, 'hvm'), + (lambda t: t.find('./devices/emulator'), None)]), 'kvm' : ('qemu:///system', - [lambda s: '<domain type=\'kvm\'>' in s, - lambda s: 'type>hvm</type' in s, - lambda s: 'emulator>/usr/bin/qemu<' not in s]), + [(lambda t: t.find('.').tag, 'domain'), + (lambda t: t.find('.').get('type'), 'kvm'), + (lambda t: t.find('./os/type').text, 'hvm'), + (lambda t: t.find('./devices/emulator'), None)]), 'uml' : ('uml:///system', - [lambda s: '<domain type=\'uml\'>' in s, - lambda s: 'type>uml</type' in s]), - } + [(lambda t: t.find('.').tag, 'domain'), + (lambda t: t.find('.').get('type'), 'uml'), + (lambda t: t.find('./os/type').text, 'uml')]), + } for (libvirt_type,(expected_uri, checks)) in type_uri_map.iteritems(): FLAGS.libvirt_type = libvirt_type @@ -52,9 +68,12 @@ class LibvirtConnTestCase(test.TrialTestCase): uri, template = conn.get_uri_and_template() self.assertEquals(uri, expected_uri) - for i, check in enumerate(checks): - xml = conn.toXml(MockDataModel()) - self.assertTrue(check(xml), '%s failed check %d' % (xml, i)) + xml = conn.to_xml(instance) + tree = parseXml(xml) + for i, (check, expected_result) in enumerate(checks): + self.assertEqual(check(tree), + expected_result, + '%s failed check %d' % (xml, i)) # Deliberately not just assigning this string to FLAGS.libvirt_uri and # checking against that later on. This way we make sure the @@ -67,3 +86,7 @@ class LibvirtConnTestCase(test.TrialTestCase): uri, template = conn.get_uri_and_template() self.assertEquals(uri, testuri) + + def tearDown(self): + self.manager.delete_project(self.project) + self.manager.delete_user(self.user) diff --git a/nova/utils.py b/nova/utils.py index b1699bda8..12afd388f 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -128,9 +128,7 @@ def runthis(prompt, cmd, check_exit_code = True): def generate_uid(topic, size=8): if topic == "i": # Instances have integer internal ids. - #TODO(gundlach): We should make this more than 32 bits, but we need to - #figure out how to make the DB happy with 64 bit integers. - return random.randint(0, 2**32-1) + return random.randint(0, 2**64-1) else: characters = '01234567890abcdefghijklmnopqrstuvwxyz' choices = [random.choice(characters) for x in xrange(size)] diff --git a/nova/virt/images.py b/nova/virt/images.py index a60bcc4c1..dc50764d9 100644 --- a/nova/virt/images.py +++ b/nova/virt/images.py @@ -29,6 +29,7 @@ from nova import flags from nova import process from nova.auth import manager from nova.auth import signer +from nova.objectstore import image FLAGS = flags.FLAGS |
