From f4289df0e58080d6d9fa381915bbd0d29f3b9751 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 15:05:48 -0800 Subject: We're not using prefix matching on AMQP, so fakerabbit shouldn't be doing it! --- nova/fakerabbit.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nova/fakerabbit.py b/nova/fakerabbit.py index dd82a9366..a7dee8caf 100644 --- a/nova/fakerabbit.py +++ b/nova/fakerabbit.py @@ -48,7 +48,6 @@ class Exchange(object): nm = self.name LOG.debug(_('(%(nm)s) publish (key: %(routing_key)s)' ' %(message)s') % locals()) - routing_key = routing_key.split('.')[0] if routing_key in self._routes: for f in self._routes[routing_key]: LOG.debug(_('Publishing to route %s'), f) -- cgit From e8a3f461319c1ee20a18f3a375af5e1e958af05e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 15:50:42 -0800 Subject: Missing import for nova.exceptions (!) --- nova/network/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nova/network/api.py b/nova/network/api.py index bf43acb51..4ee1148cb 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -21,6 +21,7 @@ Handles all requests relating to instances (guest vms). """ from nova import db +from nova import exception from nova import flags from nova import log as logging from nova import quota -- cgit From ab6b11b0399655ccdd9619be00470eda464cf2a7 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 16:09:41 -0800 Subject: Don't blindly concatenate queue name if second portiion is None --- nova/db/sqlalchemy/api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 2697fac73..009ed1f06 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1209,7 +1209,9 @@ def project_get_network_v6(context, project_id): def queue_get_for(_context, topic, physical_node_id): # FIXME(ja): this should be servername? - return "%s.%s" % (topic, physical_node_id) + if physical_node_id: + return "%s.%s" % (topic, physical_node_id) + return topic ################### -- cgit From b6254db80ca9841361775a92b85f88db7251f857 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 17:45:38 -0800 Subject: Refactoring nova-api to be a service, so that we can reuse it in tests --- bin/nova-api | 50 ++++---------------------------- nova/apiservice.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 45 deletions(-) create mode 100644 nova/apiservice.py diff --git a/bin/nova-api b/bin/nova-api index d5efb4687..99417e6c6 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -36,57 +36,17 @@ gettext.install('nova', unicode=1) from nova import flags from nova import log as logging -from nova import version +from nova import apiservice +from nova import utils from nova import wsgi -LOG = logging.getLogger('nova.api') - FLAGS = flags.FLAGS -flags.DEFINE_string('ec2_listen', "0.0.0.0", - 'IP address for EC2 API to listen') -flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') -flags.DEFINE_string('osapi_listen', "0.0.0.0", - 'IP address for OpenStack API to listen') -flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') - -API_ENDPOINTS = ['ec2', 'osapi'] - - -def run_app(paste_config_file): - LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file) - apps = [] - for api in API_ENDPOINTS: - config = wsgi.load_paste_configuration(paste_config_file, api) - if config is None: - LOG.debug(_("No paste configuration for app: %s"), api) - continue - LOG.debug(_("App Config: %(api)s\n%(config)r") % locals()) - LOG.info(_("Running %s API"), api) - app = wsgi.load_paste_app(paste_config_file, api) - apps.append((app, getattr(FLAGS, "%s_listen_port" % api), - getattr(FLAGS, "%s_listen" % api))) - if len(apps) == 0: - LOG.error(_("No known API applications configured in %s."), - paste_config_file) - return - - server = wsgi.Server() - for app in apps: - server.start(*app) - server.wait() - if __name__ == '__main__': FLAGS(sys.argv) logging.setup() - LOG.audit(_("Starting nova-api node (version %s)"), - version.version_string_with_vcs()) - LOG.debug(_("Full set of FLAGS:")) - for flag in FLAGS: - flag_get = FLAGS.get(flag, None) - LOG.debug("%(flag)s : %(flag_get)s" % locals()) conf = wsgi.paste_config_file('nova-api.conf') - if conf: - run_app(conf) - else: + if not conf: LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf') + else: + apiservice.serve(conf) diff --git a/nova/apiservice.py b/nova/apiservice.py new file mode 100644 index 000000000..7b453e19f --- /dev/null +++ b/nova/apiservice.py @@ -0,0 +1,85 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Wrapper for API service, makes it look more like the non-WSGI services +""" + +from nova import flags +from nova import log as logging +from nova import version +from nova import wsgi + + +LOG = logging.getLogger('nova.api') + +FLAGS = flags.FLAGS +flags.DEFINE_string('ec2_listen', "0.0.0.0", + 'IP address for EC2 API to listen') +flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') +flags.DEFINE_string('osapi_listen', "0.0.0.0", + 'IP address for OpenStack API to listen') +flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') + +API_ENDPOINTS = ['ec2', 'osapi'] + + +def _run_app(paste_config_file): + LOG.debug(_("Using paste.deploy config at: %s"), paste_config_file) + apps = [] + for api in API_ENDPOINTS: + config = wsgi.load_paste_configuration(paste_config_file, api) + if config is None: + LOG.debug(_("No paste configuration for app: %s"), api) + continue + LOG.debug(_("App Config: %(api)s\n%(config)r") % locals()) + LOG.info(_("Running %s API"), api) + app = wsgi.load_paste_app(paste_config_file, api) + apps.append((app, getattr(FLAGS, "%s_listen_port" % api), + getattr(FLAGS, "%s_listen" % api))) + if len(apps) == 0: + LOG.error(_("No known API applications configured in %s."), + paste_config_file) + return + + server = wsgi.Server() + for app in apps: + server.start(*app) + server.wait() + + +class ApiService(object): + """Base class for workers that run on hosts.""" + + def __init__(self, conf): + self.conf = conf + + def start(self): + _run_app(self.conf) + + +def serve(conf): + LOG.audit(_("Starting nova-api node (version %s)"), + version.version_string_with_vcs()) + LOG.debug(_("Full set of FLAGS:")) + for flag in FLAGS: + flag_get = FLAGS.get(flag, None) + LOG.debug("%(flag)s : %(flag_get)s" % locals()) + + service = ApiService(conf) + service.start() -- cgit From 79f6c437b486262bab3faacb59197a5cae30b2bd Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 17:50:26 -0800 Subject: Added create static method to ApiService --- nova/apiservice.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nova/apiservice.py b/nova/apiservice.py index 7b453e19f..1914b9e59 100644 --- a/nova/apiservice.py +++ b/nova/apiservice.py @@ -72,6 +72,11 @@ class ApiService(object): def start(self): _run_app(self.conf) + @staticmethod + def create(): + conf = wsgi.paste_config_file('nova-api.conf') + return serve(conf) + def serve(conf): LOG.audit(_("Starting nova-api node (version %s)"), @@ -83,3 +88,5 @@ def serve(conf): service = ApiService(conf) service.start() + + return service -- cgit From e37e7b91a9fb5664ad50c1ff38e95f1a2d655c06 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 17:58:01 -0800 Subject: Support service-like wait behaviour for API service --- bin/nova-api | 3 ++- nova/apiservice.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index 99417e6c6..ccb7701ae 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -49,4 +49,5 @@ if __name__ == '__main__': if not conf: LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf') else: - apiservice.serve(conf) + service = apiservice.serve(conf) + service.wait() diff --git a/nova/apiservice.py b/nova/apiservice.py index 1914b9e59..14239f196 100644 --- a/nova/apiservice.py +++ b/nova/apiservice.py @@ -60,7 +60,7 @@ def _run_app(paste_config_file): server = wsgi.Server() for app in apps: server.start(*app) - server.wait() + return server class ApiService(object): @@ -68,9 +68,13 @@ class ApiService(object): def __init__(self, conf): self.conf = conf + self.wsgi_app = None def start(self): - _run_app(self.conf) + self.wsgi_app = _run_app(self.conf) + + def wait(self): + self.wsgi_app.wait() @staticmethod def create(): -- cgit From 7c8c325f475926724f3243344803841e24d5cb84 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 18:15:29 -0800 Subject: Make static create method behave more like other services --- nova/apiservice.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/apiservice.py b/nova/apiservice.py index 14239f196..693bc9a63 100644 --- a/nova/apiservice.py +++ b/nova/apiservice.py @@ -79,7 +79,10 @@ class ApiService(object): @staticmethod def create(): conf = wsgi.paste_config_file('nova-api.conf') - return serve(conf) + LOG.audit(_("Starting nova-api node (version %s)"), + version.version_string_with_vcs()) + service = ApiService(conf) + return service def serve(conf): -- cgit From dd6b9c21d3ad493051f25ce632fb327ed7fc7b73 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 18:57:04 -0800 Subject: Exit with exit code 1 if conf cannot be read --- bin/nova-api | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/nova-api b/bin/nova-api index ccb7701ae..d03be85e3 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -48,6 +48,7 @@ if __name__ == '__main__': conf = wsgi.paste_config_file('nova-api.conf') if not conf: LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf') + sys.exit(1) else: service = apiservice.serve(conf) service.wait() -- cgit From 50e71cef14c3bd079fbc2d2c203b0e0f76ee869e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 22 Feb 2011 18:59:23 -0800 Subject: Removed unused import & formatting cleanups --- bin/nova-api | 1 - nova/apiservice.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index d03be85e3..96c784624 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -37,7 +37,6 @@ gettext.install('nova', unicode=1) from nova import flags from nova import log as logging from nova import apiservice -from nova import utils from nova import wsgi FLAGS = flags.FLAGS diff --git a/nova/apiservice.py b/nova/apiservice.py index 693bc9a63..6340e9b9b 100644 --- a/nova/apiservice.py +++ b/nova/apiservice.py @@ -16,9 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Wrapper for API service, makes it look more like the non-WSGI services -""" +"""Wrapper for API service, makes it look more like the non-WSGI services""" from nova import flags from nova import log as logging @@ -28,6 +26,7 @@ from nova import wsgi LOG = logging.getLogger('nova.api') + FLAGS = flags.FLAGS flags.DEFINE_string('ec2_listen', "0.0.0.0", 'IP address for EC2 API to listen') @@ -36,6 +35,7 @@ flags.DEFINE_string('osapi_listen', "0.0.0.0", 'IP address for OpenStack API to listen') flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') + API_ENDPOINTS = ['ec2', 'osapi'] -- cgit From fbfc2b21657a2878ab97138c133a253f7c88303e Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 23 Feb 2011 15:17:32 -0800 Subject: Alphabetize imports --- bin/nova-api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-api b/bin/nova-api index 96c784624..933202dc8 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -34,9 +34,9 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import apiservice from nova import flags from nova import log as logging -from nova import apiservice from nova import wsgi FLAGS = flags.FLAGS -- cgit From 861a7f2b53f02af2ef196411171182394edd7e17 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 23 Feb 2011 15:31:40 -0800 Subject: Changed create from a @staticmethod to a @classmethod --- nova/apiservice.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/apiservice.py b/nova/apiservice.py index 6340e9b9b..03aa781fb 100644 --- a/nova/apiservice.py +++ b/nova/apiservice.py @@ -76,12 +76,12 @@ class ApiService(object): def wait(self): self.wsgi_app.wait() - @staticmethod - def create(): + @classmethod + def create(cls): conf = wsgi.paste_config_file('nova-api.conf') LOG.audit(_("Starting nova-api node (version %s)"), version.version_string_with_vcs()) - service = ApiService(conf) + service = cls(conf) return service -- cgit From 503fe37427247b2728051426d3c40266de69bd71 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Wed, 23 Feb 2011 15:59:54 -0800 Subject: Reverted bad-fix to sqlalchemy code --- nova/db/sqlalchemy/api.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 53498fbc5..d8751bef4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1209,9 +1209,7 @@ def project_get_network_v6(context, project_id): def queue_get_for(_context, topic, physical_node_id): # FIXME(ja): this should be servername? - if physical_node_id: - return "%s.%s" % (topic, physical_node_id) - return topic + return "%s.%s" % (topic, physical_node_id) ################### -- cgit From 7c6638cc5effc7d727087ed4354c180d75476d1a Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 25 Feb 2011 13:40:15 -0800 Subject: API changed to new style class --- nova/scheduler/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 8491bf3a9..2405f1343 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -25,7 +25,7 @@ FLAGS = flags.FLAGS LOG = logging.getLogger('nova.scheduler.api') -class API: +class API(object): """API for interacting with the scheduler.""" def _call_scheduler(self, method, context, params=None): -- cgit From 58ac632f8e08b248d234deffdb56fe3a33a25130 Mon Sep 17 00:00:00 2001 From: Masanori Itoh Date: Thu, 3 Mar 2011 00:12:48 +0900 Subject: Port Todd's lp720157 fix to the current trunk, rev 752. --- nova/api/ec2/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 5adc2c075..5a63dc8da 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -198,6 +198,12 @@ class Requestify(wsgi.Middleware): try: # Raise KeyError if omitted action = req.params['Action'] + # Fix bug lp:720157 for older (version 1) clients + version = req.params['SignatureVersion'] + if int(version) == 1: + non_args.remove('SignatureMethod') + if 'SignatureMethod' in args: + args.pop('SignatureMethod') for non_arg in non_args: # Remove, but raise KeyError if omitted args.pop(non_arg) -- cgit From f79220a1f6a12621463b410d26e31e29a9e6ea3e Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Mon, 7 Mar 2011 15:41:37 -0600 Subject: cleaned up virt.xenapi.vmops._get_vm_opaque_ref. more reliable approach to checking if param is an opaque ref. code is cleaner --- nova/virt/xenapi/vmops.py | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index b862c9de9..b1671fde4 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -188,30 +188,32 @@ class VMOps(object): """Refactored out the common code of many methods that receive either a vm name or a vm instance, and want a vm instance in return. """ - vm = None - try: - if instance_or_vm.startswith("OpaqueRef:"): - # Got passed an opaque ref; return it + # if instance_or_vm is a string it must be opaque ref or instance name + if isinstance(instance_or_vm, str): + vm_rec = self._session.get_xenapi().VM.get_record(instance_or_vm) + if vm_rec != None: + # an opaque ref was passed in, return it return instance_or_vm else: - # Must be the instance name + # it must be an instance name instance_name = instance_or_vm - except (AttributeError, KeyError): - # Note the the KeyError will only happen with fakes.py - # Not a string; must be an ID or a vm instance - if isinstance(instance_or_vm, (int, long)): - ctx = context.get_admin_context() - try: - instance_obj = db.instance_get(ctx, instance_or_vm) - instance_name = instance_obj.name - except exception.NotFound: - # The unit tests screw this up, as they use an integer for - # the vm name. I'd fix that up, but that's a matter for - # another bug report. So for now, just try with the passed - # value - instance_name = instance_or_vm - else: - instance_name = instance_or_vm.name + + # if instance_or_vm is an int/long it must be instance id + elif isinstance(instance_or_vm, (int, long)): + ctx = context.get_admin_context() + try: + instance_obj = db.instance_get(ctx, instance_or_vm) + instance_name = instance_obj.name + except exception.NotFound: + # The unit tests screw this up, as they use an integer for + # the vm name. I'd fix that up, but that's a matter for + # another bug report. So for now, just try with the passed + # value + instance_name = instance_or_vm + + # otherwise instance_or_vm is an instance object + else: + instance_name = instance_or_vm.name vm = VMHelper.lookup(self._session, instance_name) if vm is None: raise exception.NotFound( -- cgit From 59f73e3180731cec644b590d448e0da74711ae03 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Mon, 7 Mar 2011 16:11:10 -0600 Subject: virt.xenapi.vmops._get_vm_opaque_ref exception caught properly --- nova/virt/xenapi/vmops.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index b1671fde4..ae4609418 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -190,13 +190,16 @@ class VMOps(object): """ # if instance_or_vm is a string it must be opaque ref or instance name if isinstance(instance_or_vm, str): - vm_rec = self._session.get_xenapi().VM.get_record(instance_or_vm) - if vm_rec != None: - # an opaque ref was passed in, return it - return instance_or_vm - else: - # it must be an instance name - instance_name = instance_or_vm + ref = None + try: + ref = self._session.get_xenapi().VM.get_record(instance_or_vm) + if ref != None: + # an opaque ref was passed in, return it + return instance_or_vm + except: + pass + # wasn't an opaque ref, must be an instance name + instance_name = instance_or_vm # if instance_or_vm is an int/long it must be instance id elif isinstance(instance_or_vm, (int, long)): -- cgit From 3fc6b8cbbd1be5baffc300112a0e39a807209c36 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Mon, 7 Mar 2011 16:34:59 -0600 Subject: virt.xenapi.vmops._get_vm_opaque_ref checks for basestring instance instead of str --- nova/virt/xenapi/vmops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index ae4609418..30fa5bdd7 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -189,7 +189,7 @@ class VMOps(object): a vm name or a vm instance, and want a vm instance in return. """ # if instance_or_vm is a string it must be opaque ref or instance name - if isinstance(instance_or_vm, str): + if isinstance(instance_or_vm, basestring): ref = None try: ref = self._session.get_xenapi().VM.get_record(instance_or_vm) -- cgit From 88c5555e867c730065c18541a35b161eb861b502 Mon Sep 17 00:00:00 2001 From: Cerberus Date: Mon, 7 Mar 2011 16:40:19 -0600 Subject: First part of the bug fix --- nova/compute/manager.py | 4 +--- nova/virt/xenapi/vmops.py | 8 +++++++- nova/virt/xenapi_conn.py | 9 +++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b3e864154..b35216dd3 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -510,9 +510,7 @@ class ComputeManager(manager.Manager): instance_ref = self.db.instance_get(context, migration_ref['instance_id']) - # this may get passed into the following spawn instead - new_disk_info = self.driver.attach_disk(instance_ref, disk_info) - self.driver.spawn(instance_ref, disk=new_disk_info) + self.driver.finish_resize(instance_ref, disk_info) self.db.migration_update(context, migration_id, {'status': 'finished', }) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index b862c9de9..37f513599 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -72,7 +72,13 @@ class VMOps(object): LOG.debug(_("Starting instance %s"), instance.name) self._session.call_xenapi('VM.start', vm_ref, False, False) - def spawn(self, instance, disk): + def spawn(self, instance): + self._spawn(instance, disk=None) + + def spawn_with_disk(self, instance, disk): + self._spawn(instance, disk=disk) + + def _spawn(self, instance, disk): """Create VM instance""" instance_name = instance.name vm = VMHelper.lookup(self._session, instance_name) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 62e17e851..7e8f825e9 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -154,9 +154,14 @@ class XenAPIConnection(object): """List VM instances""" return self._vmops.list_instances() - def spawn(self, instance, disk=None): + def spawn(self, instance): """Create VM instance""" - self._vmops.spawn(instance, disk) + self._vmops.spawn(instance) + + def finish_resize(self, instance, disk_info) + """Completes a resize, turning on the migrated instance""" + new_disk_info = self.attach_disk(instance, disk_info) + self._vmops.spawn_with_disk(instance, new_disk_info) def snapshot(self, instance, image_id): """ Create snapshot from a running VM instance """ -- cgit From ede88283729663f11d913cc54bcf8ee08028d98f Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 7 Mar 2011 14:42:36 -0800 Subject: A few formatting niceties --- nova/service.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nova/service.py b/nova/service.py index 8fdaca0a5..389a6b2df 100644 --- a/nova/service.py +++ b/nova/service.py @@ -42,6 +42,7 @@ from nova import utils from nova import version from nova import wsgi + FLAGS = flags.FLAGS flags.DEFINE_integer('report_interval', 10, 'seconds between nodes reporting state to datastore', @@ -271,6 +272,11 @@ def serve(*services): x.start() +def wait(): + while True: + greenthread.sleep(5) + + def serve_wsgi(cls, conf): try: service = cls.create(conf) @@ -290,11 +296,6 @@ def serve_wsgi(cls, conf): return service -def wait(): - while True: - greenthread.sleep(5) - - def _run_wsgi(paste_config_file, apis): logging.debug(_("Using paste.deploy config at: %s"), paste_config_file) apps = [] -- cgit From 5c7ee13b058fb954fd9bbc4a3550716b8faa0b97 Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Mon, 7 Mar 2011 22:50:35 +0000 Subject: And unit tests --- nova/tests/test_xenapi.py | 5 +++++ nova/tests/xenapi/stubs.py | 4 ++++ nova/virt/xenapi_conn.py | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 7f437c2b8..6e458558d 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -383,6 +383,11 @@ class XenAPIMigrateInstance(test.TestCase): conn = xenapi_conn.get_connection(False) conn.attach_disk(instance, {'base_copy': 'hurr', 'cow': 'durr'}) + def test_finish_resize(self): + instance = db.instance_create(self.values) + stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests) + conn = xenapi_conn.get_connection(False) + conn.finish_resize(instance, dict(base_copy='hurr', cow='durr')) class XenAPIDetermineDiskImageTestCase(test.TestCase): """ diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 11e89c9b4..28037c2ba 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -251,6 +251,9 @@ def stub_out_migration_methods(stubs): def fake_destroy(*args, **kwargs): pass + def fake_spawn_with_disk(*args, **kwargs): + pass + stubs.Set(vmops.VMOps, '_destroy', fake_destroy) stubs.Set(vm_utils.VMHelper, 'scan_default_sr', fake_sr) stubs.Set(vm_utils.VMHelper, 'scan_sr', fake_sr) @@ -259,3 +262,4 @@ def stub_out_migration_methods(stubs): stubs.Set(xenapi_conn.XenAPISession, 'wait_for_task', lambda x, y, z: None) stubs.Set(vm_utils.VMHelper, 'get_sr_path', fake_get_sr_path) stubs.Set(vmops.VMOps, '_shutdown', fake_shutdown) + stubs.Set(vmops.VMOps, 'spawn_with_disk', fake_spawn_with_disk) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 7e8f825e9..3991496b2 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -158,7 +158,7 @@ class XenAPIConnection(object): """Create VM instance""" self._vmops.spawn(instance) - def finish_resize(self, instance, disk_info) + def finish_resize(self, instance, disk_info): """Completes a resize, turning on the migrated instance""" new_disk_info = self.attach_disk(instance, disk_info) self._vmops.spawn_with_disk(instance, new_disk_info) -- cgit From 2f0845b7b80081d18ee268b94fe38326f3c5401e Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Mon, 7 Mar 2011 23:07:05 +0000 Subject: A few more changes --- nova/tests/test_xenapi.py | 6 ------ nova/virt/xenapi/vmops.py | 10 +++++----- nova/virt/xenapi_conn.py | 9 +++------ 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 6e458558d..f5b154a51 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -377,12 +377,6 @@ class XenAPIMigrateInstance(test.TestCase): conn = xenapi_conn.get_connection(False) conn.migrate_disk_and_power_off(instance, '127.0.0.1') - def test_attach_disk(self): - instance = db.instance_create(self.values) - stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests) - conn = xenapi_conn.get_connection(False) - conn.attach_disk(instance, {'base_copy': 'hurr', 'cow': 'durr'}) - def test_finish_resize(self): instance = db.instance_create(self.values) stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 37f513599..e658de7f3 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -75,8 +75,8 @@ class VMOps(object): def spawn(self, instance): self._spawn(instance, disk=None) - def spawn_with_disk(self, instance, disk): - self._spawn(instance, disk=disk) + def spawn_with_disk(self, instance, vdi_uuid): + self._spawn(instance, disk=vdi_uuid) def _spawn(self, instance, disk): """Create VM instance""" @@ -343,14 +343,14 @@ class VMOps(object): # sensible so we don't need to blindly pass around dictionaries return {'base_copy': base_copy_uuid, 'cow': cow_uuid} - def attach_disk(self, instance, disk_info): + def attach_disk(self, instance, base_copy_uuid, cow_uuid): """Links the base copy VHD to the COW via the XAPI plugin""" vm_ref = VMHelper.lookup(self._session, instance.name) new_base_copy_uuid = str(uuid.uuid4()) new_cow_uuid = str(uuid.uuid4()) params = {'instance_id': instance.id, - 'old_base_copy_uuid': disk_info['base_copy'], - 'old_cow_uuid': disk_info['cow'], + 'old_base_copy_uuid': base_copy_uuid, + 'old_cow_uuid': cow_uuid, 'new_base_copy_uuid': new_base_copy_uuid, 'new_cow_uuid': new_cow_uuid, 'sr_path': VMHelper.get_sr_path(self._session), } diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 3991496b2..9965accad 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -160,8 +160,9 @@ class XenAPIConnection(object): def finish_resize(self, instance, disk_info): """Completes a resize, turning on the migrated instance""" - new_disk_info = self.attach_disk(instance, disk_info) - self._vmops.spawn_with_disk(instance, new_disk_info) + cow_uuid = self._vmops.attach_disk(instance, disk_info['base_copy'], + disk_info['cow']) + self._vmops.spawn_with_disk(instance, cow_uuid) def snapshot(self, instance, image_id): """ Create snapshot from a running VM instance """ @@ -202,10 +203,6 @@ class XenAPIConnection(object): off the instance copies over the COW disk""" return self._vmops.migrate_disk_and_power_off(instance, dest) - def attach_disk(self, instance, disk_info): - """Moves the copied VDIs into the SR""" - return self._vmops.attach_disk(instance, disk_info) - def suspend(self, instance, callback): """suspend the specified instance""" self._vmops.suspend(instance, callback) -- cgit From 8e0fd37ddfbe88df296cf45583f0b3e4fa4d7a75 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 7 Mar 2011 15:22:59 -0800 Subject: Converted tabs to spaces in bin/nova-api --- bin/nova-api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-api b/bin/nova-api index 2d2ef6d0c..c921ec45c 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -62,5 +62,5 @@ if __name__ == '__main__': LOG.error(_("No paste configuration found for: %s"), 'nova-api.conf') sys.exit(1) else: - service = service.serve_wsgi(service.ApiService, conf) + service = service.serve_wsgi(service.ApiService, conf) service.wait() -- cgit From e69c802aaf40f3b90789aeef8bf3ef5dcbbcb2f3 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 7 Mar 2011 15:36:04 -0800 Subject: Moved FLAGS.paste_config to its re-usable location --- bin/nova-api | 14 +++----------- nova/service.py | 10 +++++++--- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/bin/nova-api b/bin/nova-api index f48dbe5a5..85ca4eefd 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -45,9 +45,6 @@ from nova import wsgi LOG = logging.getLogger('nova.api') FLAGS = flags.FLAGS -flags.DEFINE_string('paste_config', "api-paste.ini", - 'File name for the paste.deploy config for nova-api') - if __name__ == '__main__': utils.default_flagfile() @@ -59,11 +56,6 @@ if __name__ == '__main__': for flag in FLAGS: flag_get = FLAGS.get(flag, None) LOG.debug("%(flag)s : %(flag_get)s" % locals()) - conf = wsgi.paste_config_file(FLAGS.paste_config) - if not conf: - LOG.error(_("No paste configuration found for: %s"), - FLAGS.paste_config) - sys.exit(1) - else: - service = service.serve_wsgi(service.ApiService, conf) - service.wait() + + service = service.serve_wsgi(service.ApiService) + service.wait() diff --git a/nova/service.py b/nova/service.py index 389a6b2df..5a8d58695 100644 --- a/nova/service.py +++ b/nova/service.py @@ -56,6 +56,8 @@ flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') flags.DEFINE_string('osapi_listen', "0.0.0.0", 'IP address for OpenStack API to listen') flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') +flags.DEFINE_string('paste_config', "api-paste.ini", + 'File name for the paste.deploy config for nova-api') class Service(object): @@ -238,9 +240,11 @@ class ApiService(WsgiService): @classmethod def create(cls, conf=None): if not conf: - conf = wsgi.paste_config_file('nova-api.conf') + conf = wsgi.paste_config_file(FLAGS.paste_config) if not conf: - raise exception.Error(_("Cannot load nova-api.conf")) + message = (_("No paste configuration found for: %s"), + FLAGS.paste_config) + raise exception.Error(message) api_endpoints = ['ec2', 'osapi'] service = cls(conf, api_endpoints) return service @@ -277,7 +281,7 @@ def wait(): greenthread.sleep(5) -def serve_wsgi(cls, conf): +def serve_wsgi(cls, conf=None): try: service = cls.create(conf) except Exception: -- cgit From e39995def6a2a11cdd430b0e6f603b493be5542b Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Mon, 7 Mar 2011 23:51:20 +0000 Subject: Some more refactoring and a tighter unit test --- nova/tests/test_xenapi.py | 14 ++++++++++---- nova/tests/xenapi/stubs.py | 15 +++++++++++++-- nova/virt/xenapi/vmops.py | 30 ++++++++++++++---------------- nova/virt/xenapi_conn.py | 4 ++-- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index f5b154a51..919a38c06 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -360,16 +360,22 @@ class XenAPIMigrateInstance(test.TestCase): db_fakes.stub_out_db_instance_api(self.stubs) stubs.stub_out_get_target(self.stubs) xenapi_fake.reset() + self.manager = manager.AuthManager() + self.user = self.manager.create_user('fake', 'fake', 'fake', + admin=True) + self.project = self.manager.create_project('fake', 'fake', 'fake') self.values = {'name': 1, 'id': 1, - 'project_id': 'fake', - 'user_id': 'fake', + 'project_id': self.project.id, + 'user_id': self.user.id, 'image_id': 1, - 'kernel_id': 2, - 'ramdisk_id': 3, + 'kernel_id': None, + 'ramdisk_id': None, 'instance_type': 'm1.large', 'mac_address': 'aa:bb:cc:dd:ee:ff', } stubs.stub_out_migration_methods(self.stubs) + glance_stubs.stubout_glance_client(self.stubs, + glance_stubs.FakeGlance) def test_migrate_disk_and_power_off(self): instance = db.instance_create(self.values) diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 28037c2ba..d8e358611 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -225,6 +225,17 @@ class FakeSessionForMigrationTests(fake.SessionBase): def __init__(self, uri): super(FakeSessionForMigrationTests, self).__init__(uri) + def VDI_get_by_uuid(*args): + return 'hurr' + + def VM_start(self, _1, ref, _2, _3): + vm = fake.get_record('VM', ref) + if vm['power_state'] != 'Halted': + raise fake.Failure(['VM_BAD_POWER_STATE', ref, 'Halted', + vm['power_state']]) + vm['power_state'] = 'Running' + vm['is_a_template'] = False + vm['is_control_domain'] = False def stub_out_migration_methods(stubs): def fake_get_snapshot(self, instance): @@ -251,7 +262,7 @@ def stub_out_migration_methods(stubs): def fake_destroy(*args, **kwargs): pass - def fake_spawn_with_disk(*args, **kwargs): + def fake_reset_network(*args, **kwargs): pass stubs.Set(vmops.VMOps, '_destroy', fake_destroy) @@ -261,5 +272,5 @@ def stub_out_migration_methods(stubs): stubs.Set(vm_utils.VMHelper, 'get_vdi_for_vm_safely', fake_get_vdi) stubs.Set(xenapi_conn.XenAPISession, 'wait_for_task', lambda x, y, z: None) stubs.Set(vm_utils.VMHelper, 'get_sr_path', fake_get_sr_path) + stubs.Set(vmops.VMOps, 'reset_network', fake_reset_network) stubs.Set(vmops.VMOps, '_shutdown', fake_shutdown) - stubs.Set(vmops.VMOps, 'spawn_with_disk', fake_spawn_with_disk) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index e658de7f3..7fe1f6ff0 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -72,13 +72,19 @@ class VMOps(object): LOG.debug(_("Starting instance %s"), instance.name) self._session.call_xenapi('VM.start', vm_ref, False, False) - def spawn(self, instance): - self._spawn(instance, disk=None) - - def spawn_with_disk(self, instance, vdi_uuid): - self._spawn(instance, disk=vdi_uuid) + def create_disk(self, instance): + user = AuthManager().get_user(instance.user_id) + project = AuthManager().get_project(instance.project_id) + disk_image_type = VMHelper.determine_disk_image_type(instance) + vdi_uuid = VMHelper.fetch_image(self._session, instance.id, + instance.image_id, user, project, disk_image_type) + return vdi_uuid - def _spawn(self, instance, disk): + def spawn(self, instance): + vdi_uuid = self.create_disk(instance) + self._spawn_with_disk(instance, vdi_uuid=vdi_uuid) + + def _spawn_with_disk(self, instance, vdi_uuid): """Create VM instance""" instance_name = instance.name vm = VMHelper.lookup(self._session, instance_name) @@ -101,17 +107,9 @@ class VMOps(object): vdi_ref = kernel = ramdisk = pv_kernel = None # Are we building from a pre-existing disk? - if not disk: - #if kernel is not present we must download a raw disk - - disk_image_type = VMHelper.determine_disk_image_type(instance) - vdi_uuid = VMHelper.fetch_image(self._session, instance.id, - instance.image_id, user, project, disk_image_type) - vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) - - else: - vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', disk) + vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) + disk_image_type = VMHelper.determine_disk_image_type(instance) if disk_image_type == ImageType.DISK_RAW: # Have a look at the VDI and see if it has a PV kernel pv_kernel = VMHelper.lookup_image(self._session, instance.id, diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 9965accad..b63a5f8c3 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -160,9 +160,9 @@ class XenAPIConnection(object): def finish_resize(self, instance, disk_info): """Completes a resize, turning on the migrated instance""" - cow_uuid = self._vmops.attach_disk(instance, disk_info['base_copy'], + vdi_uuid = self._vmops.attach_disk(instance, disk_info['base_copy'], disk_info['cow']) - self._vmops.spawn_with_disk(instance, cow_uuid) + self._vmops._spawn_with_disk(instance, vdi_uuid) def snapshot(self, instance, image_id): """ Create snapshot from a running VM instance """ -- cgit From 5ec9cbcdee3de3868a47ca5ec351a9a2594ceea2 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Mon, 7 Mar 2011 18:05:27 -0600 Subject: virt.xenapi.vmops._get_vm_opaque_ref assumes VM.get_record raises --- nova/virt/xenapi/vmops.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 30fa5bdd7..c0fbf96fc 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -192,14 +192,12 @@ class VMOps(object): if isinstance(instance_or_vm, basestring): ref = None try: + # check for opaque ref ref = self._session.get_xenapi().VM.get_record(instance_or_vm) - if ref != None: - # an opaque ref was passed in, return it - return instance_or_vm - except: - pass - # wasn't an opaque ref, must be an instance name - instance_name = instance_or_vm + return instance_or_vm + except self.XenAPI.Failure: + # wasn't an opaque ref, must be an instance name + instance_name = instance_or_vm # if instance_or_vm is an int/long it must be instance id elif isinstance(instance_or_vm, (int, long)): -- cgit From 4e8b6a14324ef2d1f550233cbcfc94c6363533d8 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Mon, 7 Mar 2011 18:46:44 -0600 Subject: virt.xenapi.vmops._get_vm_opaque_ref changed vm to vm_ref and ref to obj --- nova/virt/xenapi/vmops.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c0fbf96fc..0adabe7f5 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -190,10 +190,10 @@ class VMOps(object): """ # if instance_or_vm is a string it must be opaque ref or instance name if isinstance(instance_or_vm, basestring): - ref = None + obj = None try: # check for opaque ref - ref = self._session.get_xenapi().VM.get_record(instance_or_vm) + obj = self._session.get_xenapi().VM.get_record(instance_or_vm) return instance_or_vm except self.XenAPI.Failure: # wasn't an opaque ref, must be an instance name @@ -215,11 +215,11 @@ class VMOps(object): # otherwise instance_or_vm is an instance object else: instance_name = instance_or_vm.name - vm = VMHelper.lookup(self._session, instance_name) - if vm is None: + vm_ref = VMHelper.lookup(self._session, instance_name) + if vm_ref is None: raise exception.NotFound( _('Instance not present %s') % instance_name) - return vm + return vm_ref def _acquire_bootlock(self, vm): """Prevent an instance from booting""" -- cgit From 1caceddf431a1ad1ef22235c2206bccf39fde5c5 Mon Sep 17 00:00:00 2001 From: Cerberus Date: Tue, 8 Mar 2011 14:24:01 -0600 Subject: Nits --- nova/virt/xenapi/vmops.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 7fe1f6ff0..86dbf251b 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -90,7 +90,7 @@ class VMOps(object): vm = VMHelper.lookup(self._session, instance_name) if vm is not None: raise exception.Duplicate(_('Attempted to create' - ' non-unique name %s') % instance_name) + ' non-unique name %s') % instance_name) #ensure enough free memory is available if not VMHelper.ensure_free_mem(self._session, instance): @@ -104,7 +104,7 @@ class VMOps(object): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) - vdi_ref = kernel = ramdisk = pv_kernel = None + kernel = ramdisk = pv_kernel = None # Are we building from a pre-existing disk? vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) -- cgit From dd2f0019297d01fe5d6b3dae4efc72946191be75 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Tue, 8 Mar 2011 22:14:25 +0000 Subject: Use disk_format and container_format instead of image type --- nova/api/openstack/servers.py | 2 +- nova/virt/xenapi/vm_utils.py | 18 ++++++++++-------- plugins/xenserver/xenapi/etc/xapi.d/plugins/glance | 14 +++++++++++--- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index c2bf42b72..85999764f 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -450,7 +450,7 @@ class Controller(wsgi.Controller): _("Cannot build from image %(image_id)s, status not active") % locals()) - if image['type'] != 'machine': + if image['disk_format'] != 'ami': return None, None try: diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 80b7540d4..ce081a2d6 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -467,19 +467,21 @@ class VMHelper(HelperBase): "%(image_id)s, instance %(instance_id)s") % locals()) def determine_from_glance(): - glance_type2nova_type = {'machine': ImageType.DISK, - 'raw': ImageType.DISK_RAW, - 'vhd': ImageType.DISK_VHD, - 'kernel': ImageType.KERNEL_RAMDISK, - 'ramdisk': ImageType.KERNEL_RAMDISK} + glance_disk_format2nova_type = { + 'ami': ImageType.DISK, + 'aki': ImageType.KERNEL_RAMDISK, + 'ari': ImageType.KERNEL_RAMDISK, + 'raw': ImageType.DISK_RAW, + 'vhd': ImageType.DISK_VHD} client = glance.client.Client(FLAGS.glance_host, FLAGS.glance_port) meta = client.get_image_meta(instance.image_id) - type_ = meta['type'] + disk_format = meta['disk_format'] try: - return glance_type2nova_type[type_] + return glance_disk_format2nova_type[disk_format] except KeyError: raise exception.NotFound( - _("Unrecognized image type '%(type_)s'") % locals()) + _("Unrecognized disk_format '%(disk_format)s'") + % locals()) def determine_from_instance(): if instance.kernel_id: diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance index aa12d432a..201b99fda 100644 --- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance @@ -201,13 +201,21 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port): # to request conn.putrequest('PUT', '/images/%s' % image_id) - # TODO(sirp): make `store` configurable + # NOTE(sirp): There is some confusion around OVF. Here's a summary of + # where we currently stand: + # 1. OVF as a container format is misnamed. We really should be using + # OVA since that is the name for the container format; OVF is the + # standard applied to the manifest file contained within. + # 2. We're currently uploading a vanilla tarball. In order to be OVF/OVA + # compliant, we'll need to embed a minimal OVF manifest as the first + # file. headers = { 'content-type': 'application/octet-stream', 'transfer-encoding': 'chunked', - 'x-image-meta-is_public': 'True', + 'x-image-meta-is-public': 'True', 'x-image-meta-status': 'queued', - 'x-image-meta-type': 'vhd'} + 'x-image-meta-disk-format': 'vhd', + 'x-image-meta-container-format': 'ovf'} for header, value in headers.iteritems(): conn.putheader(header, value) conn.endheaders() -- cgit From 7a6833c883a04fd7920bff7367c9e28a35858d8d Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Tue, 8 Mar 2011 23:17:50 +0000 Subject: Accidentally left some bad data around --- nova/tests/test_xenapi.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 919a38c06..916555af3 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -376,6 +376,11 @@ class XenAPIMigrateInstance(test.TestCase): stubs.stub_out_migration_methods(self.stubs) glance_stubs.stubout_glance_client(self.stubs, glance_stubs.FakeGlance) + def tearDown(self): + super(XenAPIMigrateInstance, self).tearDown() + self.manager.delete_project(self.project) + self.manager.delete_user(self.user) + self.stubs.UnsetAll() def test_migrate_disk_and_power_off(self): instance = db.instance_create(self.values) -- cgit From 698398fdc2a05a0930591d3f3d386ad24a322359 Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Tue, 8 Mar 2011 23:24:19 +0000 Subject: Pep8 fixes --- nova/tests/test_xenapi.py | 2 ++ nova/tests/xenapi/stubs.py | 1 + nova/virt/xenapi/vmops.py | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 916555af3..c26dc8639 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -376,6 +376,7 @@ class XenAPIMigrateInstance(test.TestCase): stubs.stub_out_migration_methods(self.stubs) glance_stubs.stubout_glance_client(self.stubs, glance_stubs.FakeGlance) + def tearDown(self): super(XenAPIMigrateInstance, self).tearDown() self.manager.delete_project(self.project) @@ -394,6 +395,7 @@ class XenAPIMigrateInstance(test.TestCase): conn = xenapi_conn.get_connection(False) conn.finish_resize(instance, dict(base_copy='hurr', cow='durr')) + class XenAPIDetermineDiskImageTestCase(test.TestCase): """ Unit tests for code that detects the ImageType diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index d8e358611..70d46a1fb 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -237,6 +237,7 @@ class FakeSessionForMigrationTests(fake.SessionBase): vm['is_a_template'] = False vm['is_control_domain'] = False + def stub_out_migration_methods(stubs): def fake_get_snapshot(self, instance): return 'foo', 'bar' diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 43c23806e..562ecd4d5 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -83,7 +83,7 @@ class VMOps(object): def spawn(self, instance): vdi_uuid = self.create_disk(instance) self._spawn_with_disk(instance, vdi_uuid=vdi_uuid) - + def _spawn_with_disk(self, instance, vdi_uuid): """Create VM instance""" instance_name = instance.name -- cgit From 6207abe3068964c586d06bb0e3740b8bad922dca Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Tue, 8 Mar 2011 23:26:33 +0000 Subject: Fixing tests --- nova/tests/glance/stubs.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/nova/tests/glance/stubs.py b/nova/tests/glance/stubs.py index 3ff8d7ce5..5872552ec 100644 --- a/nova/tests/glance/stubs.py +++ b/nova/tests/glance/stubs.py @@ -35,23 +35,28 @@ class FakeGlance(object): IMAGE_FIXTURES = { IMAGE_MACHINE: { 'image_meta': {'name': 'fakemachine', 'size': 0, - 'type': 'machine'}, + 'disk_format': 'ami', + 'container_format': 'ami'}, 'image_data': StringIO.StringIO('')}, IMAGE_KERNEL: { 'image_meta': {'name': 'fakekernel', 'size': 0, - 'type': 'kernel'}, + 'disk_format': 'aki', + 'container_format': 'aki'}, 'image_data': StringIO.StringIO('')}, IMAGE_RAMDISK: { 'image_meta': {'name': 'fakeramdisk', 'size': 0, - 'type': 'ramdisk'}, + 'disk_format': 'ari', + 'container_format': 'ari'}, 'image_data': StringIO.StringIO('')}, IMAGE_RAW: { 'image_meta': {'name': 'fakeraw', 'size': 0, - 'type': 'raw'}, + 'disk_format': 'raw', + 'container_format': 'bare'}, 'image_data': StringIO.StringIO('')}, IMAGE_VHD: { 'image_meta': {'name': 'fakevhd', 'size': 0, - 'type': 'vhd'}, + 'disk_format': 'vhd', + 'container_format': 'ovf'}, 'image_data': StringIO.StringIO('')}} def __init__(self, host, port=None, use_ssl=False): -- cgit From a4830f83afd78cdb96dc3e474eb4efc167de7737 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 8 Mar 2011 16:45:20 -0800 Subject: Sorted imports correctly --- bin/nova-api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-api b/bin/nova-api index 85ca4eefd..06bb855cb 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -34,9 +34,9 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) -from nova import service from nova import flags from nova import log as logging +from nova import service from nova import utils from nova import version from nova import wsgi -- cgit From e8c8fd3f232371625f0924410c4c09c32339b113 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 8 Mar 2011 16:47:43 -0800 Subject: Renamed FLAG.paste_config -> FLAG.api_paste_config --- nova/service.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/service.py b/nova/service.py index 5a8d58695..460f36f7a 100644 --- a/nova/service.py +++ b/nova/service.py @@ -56,7 +56,7 @@ flags.DEFINE_integer('ec2_listen_port', 8773, 'port for ec2 api to listen') flags.DEFINE_string('osapi_listen', "0.0.0.0", 'IP address for OpenStack API to listen') flags.DEFINE_integer('osapi_listen_port', 8774, 'port for os api to listen') -flags.DEFINE_string('paste_config', "api-paste.ini", +flags.DEFINE_string('api_paste_config', "api-paste.ini", 'File name for the paste.deploy config for nova-api') @@ -240,10 +240,10 @@ class ApiService(WsgiService): @classmethod def create(cls, conf=None): if not conf: - conf = wsgi.paste_config_file(FLAGS.paste_config) + conf = wsgi.paste_config_file(FLAGS.api_paste_config) if not conf: message = (_("No paste configuration found for: %s"), - FLAGS.paste_config) + FLAGS.api_paste_config) raise exception.Error(message) api_endpoints = ['ec2', 'osapi'] service = cls(conf, api_endpoints) @@ -315,7 +315,7 @@ def _run_wsgi(paste_config_file, apis): getattr(FLAGS, "%s_listen" % api))) if len(apps) == 0: logging.error(_("No known API applications configured in %s."), - paste_config_file) + paste_config_file) return server = wsgi.Server() -- cgit From 59fa70102a06dce9f86b9b29825245bc54c01598 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 8 Mar 2011 16:51:05 -0800 Subject: Added documentation about needed flags --- nova/service.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nova/service.py b/nova/service.py index 460f36f7a..af20db01c 100644 --- a/nova/service.py +++ b/nova/service.py @@ -221,7 +221,12 @@ class Service(object): class WsgiService(object): - """Base class for WSGI based services.""" + """Base class for WSGI based services. + + For each api you define, you must also define these flags: + :_listen: The address on which to listen + :_listen_port: The port on which to listen + """ def __init__(self, conf, apis): self.conf = conf -- cgit