Align internal image API with volume and network
First part of standardizing the nova internal image API with the API objects for volume and network. This patch creates a nova.image.api.API object that matches the signature of nova.network.api.API and nova.volume.cinder.API for CRUD operations on image records. The existing unit tests were enough to fully cover the new code paths, since much of this patch simply aligned the internal image API calls and API object with that of the other submodules. The next in this patch series will work on cleaning up the remainder of places in nova that directly call on nova.image.glance methods, as well as the untouched download/upload handling. Change-Id: I67e7c9d841e5bad82cdca8f7048eaa57f0cfbb2f Partially-implements: blueprint standardize-nova-image
This commit is contained in:
@@ -903,13 +903,11 @@ class ServersController(wsgi.Controller):
|
||||
img = instance['image_ref']
|
||||
if not img:
|
||||
props = bdms.root_metadata(
|
||||
context, self.compute_api.image_service,
|
||||
context, self.compute_api.image_api,
|
||||
self.compute_api.volume_api)
|
||||
image_meta = {'properties': props}
|
||||
else:
|
||||
src_image = self.compute_api.\
|
||||
image_service.show(context, img)
|
||||
image_meta = dict(src_image)
|
||||
image_meta = self.compute_api.image_api.get(context, img)
|
||||
|
||||
image = self.compute_api.snapshot_volume_backed(
|
||||
context,
|
||||
|
||||
@@ -1439,13 +1439,11 @@ class Controller(wsgi.Controller):
|
||||
img = instance['image_ref']
|
||||
if not img:
|
||||
props = bdms.root_metadata(
|
||||
context, self.compute_api.image_service,
|
||||
context, self.compute_api.image_api,
|
||||
self.compute_api.volume_api)
|
||||
image_meta = {'properties': props}
|
||||
else:
|
||||
src_image = self.compute_api.image_service.\
|
||||
show(context, img)
|
||||
image_meta = dict(src_image)
|
||||
image_meta = self.compute_api.image_api.get(context, img)
|
||||
|
||||
image = self.compute_api.snapshot_volume_backed(
|
||||
context,
|
||||
|
||||
+23
-22
@@ -43,7 +43,7 @@ from nova import crypto
|
||||
from nova.db import base
|
||||
from nova import exception
|
||||
from nova import hooks
|
||||
from nova.image import glance
|
||||
from nova import image
|
||||
from nova import network
|
||||
from nova.network import model as network_model
|
||||
from nova.network.security_group import openstack_driver
|
||||
@@ -240,11 +240,9 @@ def _diff_dict(orig, new):
|
||||
class API(base.Base):
|
||||
"""API for interacting with the compute manager."""
|
||||
|
||||
def __init__(self, image_service=None, network_api=None, volume_api=None,
|
||||
def __init__(self, image_api=None, network_api=None, volume_api=None,
|
||||
security_group_api=None, **kwargs):
|
||||
self.image_service = (image_service or
|
||||
glance.get_default_image_service())
|
||||
|
||||
self.image_api = image_api or image.API()
|
||||
self.network_api = network_api or network.API()
|
||||
self.volume_api = volume_api or volume.API()
|
||||
self.security_group_api = (security_group_api or
|
||||
@@ -462,8 +460,8 @@ class API(base.Base):
|
||||
return self.network_api.validate_networks(context, requested_networks,
|
||||
max_count)
|
||||
|
||||
@staticmethod
|
||||
def _handle_kernel_and_ramdisk(context, kernel_id, ramdisk_id, image):
|
||||
def _handle_kernel_and_ramdisk(self, context, kernel_id, ramdisk_id,
|
||||
image):
|
||||
"""Choose kernel and ramdisk appropriate for the instance.
|
||||
|
||||
The kernel and ramdisk can be chosen in one of three ways:
|
||||
@@ -490,14 +488,19 @@ class API(base.Base):
|
||||
|
||||
# Verify kernel and ramdisk exist (fail-fast)
|
||||
if kernel_id is not None:
|
||||
image_service, kernel_id = glance.get_remote_image_service(
|
||||
context, kernel_id)
|
||||
image_service.show(context, kernel_id)
|
||||
kernel_image = self.image_api.get(context, kernel_id)
|
||||
# kernel_id could have been a URI, not a UUID, so to keep behaviour
|
||||
# from before, which leaked that implementation detail out to the
|
||||
# caller, we return the image UUID of the kernel image and ramdisk
|
||||
# image (below) and not any image URIs that might have been
|
||||
# supplied.
|
||||
# TODO(jaypipes): Get rid of this silliness once we move to a real
|
||||
# Image object and hide all of that stuff within nova.image.api.
|
||||
kernel_id = kernel_image['id']
|
||||
|
||||
if ramdisk_id is not None:
|
||||
image_service, ramdisk_id = glance.get_remote_image_service(
|
||||
context, ramdisk_id)
|
||||
image_service.show(context, ramdisk_id)
|
||||
ramdisk_image = self.image_api.get(context, ramdisk_id)
|
||||
ramdisk_id = ramdisk_image['id']
|
||||
|
||||
return kernel_id, ramdisk_id
|
||||
|
||||
@@ -682,10 +685,8 @@ class API(base.Base):
|
||||
if not image_href:
|
||||
return None, {}
|
||||
|
||||
(image_service, image_id) = glance.get_remote_image_service(
|
||||
context, image_href)
|
||||
image = image_service.show(context, image_id)
|
||||
return image_id, image
|
||||
image = self.image_api.get(context, image_href)
|
||||
return image['id'], image
|
||||
|
||||
def _checks_for_create_and_rebuild(self, context, image_id, image,
|
||||
instance_type, metadata,
|
||||
@@ -869,7 +870,7 @@ class API(base.Base):
|
||||
if bdm.get('image_id'):
|
||||
try:
|
||||
image_id = bdm['image_id']
|
||||
image_meta = self.image_service.show(context, image_id)
|
||||
image_meta = self.image_api.get(context, image_id)
|
||||
return image_meta.get('properties', {})
|
||||
except Exception:
|
||||
raise exception.InvalidBDMImage(id=image_id)
|
||||
@@ -1410,7 +1411,7 @@ class API(base.Base):
|
||||
"from shelved instance..."),
|
||||
snapshot_id, instance=instance)
|
||||
try:
|
||||
self.image_service.delete(context, snapshot_id)
|
||||
self.image_api.delete(context, snapshot_id)
|
||||
except (exception.ImageNotFound,
|
||||
exception.ImageNotAuthorized) as exc:
|
||||
LOG.warning(_("Failed to delete snapshot "
|
||||
@@ -1990,7 +1991,7 @@ class API(base.Base):
|
||||
}
|
||||
image_ref = instance.image_ref
|
||||
sent_meta = compute_utils.get_image_metadata(
|
||||
context, self.image_service, image_ref, instance)
|
||||
context, self.image_api, image_ref, instance)
|
||||
|
||||
sent_meta['name'] = name
|
||||
sent_meta['is_public'] = False
|
||||
@@ -1999,7 +2000,7 @@ class API(base.Base):
|
||||
properties.update(extra_properties or {})
|
||||
sent_meta['properties'].update(properties)
|
||||
|
||||
return self.image_service.create(context, sent_meta)
|
||||
return self.image_api.create(context, sent_meta)
|
||||
|
||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED])
|
||||
def snapshot_volume_backed(self, context, instance, image_meta, name,
|
||||
@@ -2064,7 +2065,7 @@ class API(base.Base):
|
||||
# hence the zero size
|
||||
image_meta['size'] = 0
|
||||
|
||||
return self.image_service.create(context, image_meta, data='')
|
||||
return self.image_api.create(context, image_meta)
|
||||
|
||||
@wrap_check_policy
|
||||
@check_instance_lock
|
||||
|
||||
+11
-21
@@ -56,6 +56,7 @@ from nova import consoleauth
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova import hooks
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova import manager
|
||||
from nova import network
|
||||
@@ -354,8 +355,7 @@ def delete_image_on_error(function):
|
||||
LOG.debug("Cleaning up image %s" % image_id,
|
||||
exc_info=True, instance=instance)
|
||||
try:
|
||||
image_service = glance.get_default_image_service()
|
||||
image_service.delete(context, image_id)
|
||||
self.image_api.delete(context, image_id)
|
||||
except Exception:
|
||||
LOG.exception(_("Error while trying to clean up image %s")
|
||||
% image_id, instance=instance)
|
||||
@@ -419,12 +419,6 @@ def aggregate_object_compat(function):
|
||||
return decorated_function
|
||||
|
||||
|
||||
def _get_image_meta(context, image_ref):
|
||||
image_service, image_id = glance.get_remote_image_service(context,
|
||||
image_ref)
|
||||
return image_service.show(context, image_id)
|
||||
|
||||
|
||||
class InstanceEvents(object):
|
||||
def __init__(self):
|
||||
self._events = {}
|
||||
@@ -575,6 +569,7 @@ class ComputeManager(manager.Manager):
|
||||
self.virtapi = ComputeVirtAPI(self)
|
||||
self.network_api = network.API()
|
||||
self.volume_api = volume.API()
|
||||
self.image_api = image.API()
|
||||
self._last_host_check = 0
|
||||
self._last_bw_usage_poll = 0
|
||||
self._bw_usage_supported = True
|
||||
@@ -2496,13 +2491,14 @@ class ComputeManager(manager.Manager):
|
||||
instance.save()
|
||||
|
||||
if image_ref:
|
||||
image_meta = _get_image_meta(context, image_ref)
|
||||
image_meta = self.image_api.get(context, image_ref)
|
||||
else:
|
||||
image_meta = {}
|
||||
|
||||
# This instance.exists message should contain the original
|
||||
# image_ref, not the new one. Since the DB has been updated
|
||||
# to point to the new one... we have to override it.
|
||||
#TODO(jaypipes): Move generate_image_url() into the nova.image.api
|
||||
orig_image_ref_url = glance.generate_image_url(orig_image_ref)
|
||||
extra_usage_info = {'image_ref_url': orig_image_ref_url}
|
||||
self.conductor_api.notify_usage_exists(context,
|
||||
@@ -2831,13 +2827,12 @@ class ComputeManager(manager.Manager):
|
||||
:param rotation: int representing how many backups to keep around;
|
||||
None if rotation shouldn't be used (as in the case of snapshots)
|
||||
"""
|
||||
image_service = glance.get_default_image_service()
|
||||
filters = {'property-image_type': 'backup',
|
||||
'property-backup_type': backup_type,
|
||||
'property-instance_uuid': instance.uuid}
|
||||
|
||||
images = image_service.detail(context, filters=filters,
|
||||
sort_key='created_at', sort_dir='desc')
|
||||
images = self.image_api.get_all(context, filters=filters,
|
||||
sort_key='created_at', sort_dir='desc')
|
||||
num_images = len(images)
|
||||
LOG.debug("Found %(num_images)d images (rotation: %(rotation)d)",
|
||||
{'num_images': num_images, 'rotation': rotation},
|
||||
@@ -2854,7 +2849,7 @@ class ComputeManager(manager.Manager):
|
||||
image_id = image['id']
|
||||
LOG.debug("Deleting image %s", image_id,
|
||||
instance=instance)
|
||||
image_service.delete(context, image_id)
|
||||
self.image_api.delete(context, image_id)
|
||||
|
||||
@object_compat
|
||||
@wrap_exception()
|
||||
@@ -2954,9 +2949,7 @@ class ComputeManager(manager.Manager):
|
||||
' using instance\'s current image'))
|
||||
rescue_image_ref = instance['image_ref']
|
||||
|
||||
image_service, image_id = glance.get_remote_image_service(
|
||||
context, rescue_image_ref)
|
||||
image_meta = compute_utils.get_image_metadata(context, image_service,
|
||||
image_meta = compute_utils.get_image_metadata(context, self.image_api,
|
||||
rescue_image_ref,
|
||||
instance)
|
||||
# NOTE(belliott) bug #1227350 - xenapi needs the actual image id
|
||||
@@ -3934,8 +3927,7 @@ class ComputeManager(manager.Manager):
|
||||
|
||||
if image:
|
||||
instance.image_ref = shelved_image_ref
|
||||
image_service = glance.get_default_image_service()
|
||||
image_service.delete(context, image['id'])
|
||||
self.image_api.delete(context, image['id'])
|
||||
|
||||
self._unshelve_instance_key_restore(instance, scrubbed_keys)
|
||||
instance.power_state = self._get_power_state(context, instance)
|
||||
@@ -4393,10 +4385,8 @@ class ComputeManager(manager.Manager):
|
||||
% dict(ports=len(network_info)))
|
||||
raise exception.InterfaceAttachFailed(instance=instance)
|
||||
image_ref = instance.get('image_ref')
|
||||
image_service, image_id = glance.get_remote_image_service(
|
||||
context, image_ref)
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
context, image_service, image_ref, instance)
|
||||
context, self.image_api, image_ref, instance)
|
||||
|
||||
self.driver.attach_interface(instance, image_meta, network_info[0])
|
||||
return network_info[0]
|
||||
|
||||
@@ -199,13 +199,14 @@ def _get_unused_letter(used_letters):
|
||||
return letters[0]
|
||||
|
||||
|
||||
def get_image_metadata(context, image_service, image_id, instance):
|
||||
def get_image_metadata(context, image_api, image_id_or_uri, instance):
|
||||
# If the base image is still available, get its metadata
|
||||
try:
|
||||
image = image_service.show(context, image_id)
|
||||
image = image_api.get(context, image_id_or_uri)
|
||||
except Exception as e:
|
||||
LOG.warning(_("Can't access image %(image_id)s: %(error)s"),
|
||||
{"image_id": image_id, "error": e}, instance=instance)
|
||||
{"image_id": image_id_or_uri, "error": e},
|
||||
instance=instance)
|
||||
image_system_meta = {}
|
||||
else:
|
||||
flavor = flavors.extract_flavor(instance)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# 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.
|
||||
|
||||
|
||||
def API():
|
||||
# Needed to prevent circular import...
|
||||
import nova.image.api
|
||||
return nova.image.api.API()
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Main abstraction layer for retrieving and storing information about disk
|
||||
images used by the compute layer.
|
||||
"""
|
||||
|
||||
from nova.image import glance
|
||||
|
||||
|
||||
class API(object):
|
||||
|
||||
"""Responsible for exposing a relatively stable internal API for other
|
||||
modules in Nova to retrieve information about disk images. This API
|
||||
attempts to match the nova.volume.api and nova.network.api calling
|
||||
interface.
|
||||
"""
|
||||
|
||||
def _get_session_and_image_id(self, context, id_or_uri):
|
||||
"""Returns a tuple of (session, image_id). If the supplied `id_or_uri`
|
||||
is an image ID, then the default client session will be returned
|
||||
for the context's user, along with the image ID. If the supplied
|
||||
`id_or_uri` parameter is a URI, then a client session connecting to
|
||||
the URI's image service endpoint will be returned along with a
|
||||
parsed image ID from that URI.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
"""
|
||||
return glance.get_remote_image_service(context, id_or_uri)
|
||||
|
||||
def _get_session(self, _context):
|
||||
"""Returns a client session that can be used to query for image
|
||||
information.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
"""
|
||||
#TODO(jaypipes): Refactor glance.get_remote_image_service and
|
||||
# glance.get_default_image_service into a single
|
||||
# method that takes a context and actually respects
|
||||
# it, returning a real session object that keeps
|
||||
# the context alive...
|
||||
return glance.get_default_image_service()
|
||||
|
||||
def get_all(self, context, **kwargs):
|
||||
"""Retrieves all information records about all disk images available
|
||||
to show to the requesting user. If the requesting user is an admin,
|
||||
all images in an ACTIVE status are returned. If the requesting user
|
||||
is not an admin, the all public images and all private images that
|
||||
are owned by the requesting user in the ACTIVE status are returned.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param **kwargs: A dictionary of filter and pagination values that
|
||||
may be passed to the underlying image info driver.
|
||||
"""
|
||||
session = self._get_session(context)
|
||||
return session.detail(context, **kwargs)
|
||||
|
||||
def get(self, context, id_or_uri):
|
||||
"""Retrieves the information record for a single disk image. If the
|
||||
supplied identifier parameter is a UUID, the default driver will
|
||||
be used to return information about the image. If the supplied
|
||||
identifier is a URI, then the driver that matches that URI endpoint
|
||||
will be used to query for image information.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
"""
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.show(context, image_id)
|
||||
|
||||
def create(self, context, image_info, data=None):
|
||||
"""Creates a new image record, optionally passing the image bits to
|
||||
backend storage.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param image_info: A dict of information about the image that is
|
||||
passed to the image registry.
|
||||
:param data: Optional file handle or bytestream iterator that is
|
||||
passed to backend storage.
|
||||
"""
|
||||
session = self._get_session(context)
|
||||
return session.create(context, image_info, data=data)
|
||||
|
||||
def update(self, context, id_or_uri, image_info,
|
||||
data=None, purge_props=False):
|
||||
"""Update the information about an image, optionally along with a file
|
||||
handle or bytestream iterator for image bits. If the optional file
|
||||
handle for updated image bits is supplied, the image may not have
|
||||
already uploaded bits for the image.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
:param image_info: A dict of information about the image that is
|
||||
passed to the image registry.
|
||||
:param data: Optional file handle or bytestream iterator that is
|
||||
passed to backend storage.
|
||||
:param purge_props: Optional, defaults to True. If set, the backend
|
||||
image registry will clear all image properties
|
||||
and replace them the image properties supplied
|
||||
in the image_info dictionary's 'properties'
|
||||
collection.
|
||||
"""
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.update(context, image_id, image_info, data=data,
|
||||
purge_props=purge_props)
|
||||
|
||||
def delete(self, context, id_or_uri):
|
||||
"""Delete the information about an image and mark the image bits for
|
||||
deletion.
|
||||
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
"""
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.delete(context, image_id)
|
||||
@@ -547,7 +547,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
self.test_boot_volume_metadata(metadata=False)
|
||||
|
||||
def test_boot_image_metadata(self, metadata=True):
|
||||
def image_api_show(*args, **kwargs):
|
||||
def image_api_get(*args, **kwargs):
|
||||
if metadata:
|
||||
return {
|
||||
'properties': {'img_test_key': 'img_test_value'}
|
||||
@@ -555,7 +555,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
else:
|
||||
return {}
|
||||
|
||||
self.stubs.Set(self.compute_api.image_service, 'show', image_api_show)
|
||||
self.stubs.Set(self.compute_api.image_api, 'get', image_api_get)
|
||||
|
||||
block_device_mapping = [{
|
||||
'boot_index': 0,
|
||||
@@ -2007,10 +2007,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
self.assertEqual('some_random_state', inst_obj['vm_state'])
|
||||
|
||||
@mock.patch.object(nova.compute.utils, "get_image_metadata")
|
||||
@mock.patch.object(nova.image.glance, "get_remote_image_service")
|
||||
@mock.patch.object(nova.virt.fake.FakeDriver, "rescue")
|
||||
def test_rescue_with_image_specified(self, mock_rescue,
|
||||
mock_get_remote_image_service, mock_get_image_metadata):
|
||||
mock_get_image_metadata):
|
||||
|
||||
image_ref = "image-ref"
|
||||
rescue_image_meta = {}
|
||||
@@ -2023,16 +2022,12 @@ class ComputeTestCase(BaseTestCase):
|
||||
mock_context.elevated.return_value = ctxt
|
||||
|
||||
mock_get_image_metadata.return_value = rescue_image_meta
|
||||
mock_image_service = "image_service"
|
||||
mock_get_remote_image_service.return_value = (mock_image_service, "id")
|
||||
|
||||
self.compute.rescue_instance(mock_context, instance=instance,
|
||||
rescue_password="password", rescue_image_ref=image_ref)
|
||||
|
||||
mock_get_remote_image_service.assert_called_with(ctxt,
|
||||
image_ref)
|
||||
mock_get_image_metadata.assert_called_with(ctxt,
|
||||
mock_image_service,
|
||||
self.compute.image_api,
|
||||
image_ref, instance)
|
||||
mock_rescue.assert_called_with(ctxt, instance, [],
|
||||
rescue_image_meta, 'password')
|
||||
@@ -2040,11 +2035,9 @@ class ComputeTestCase(BaseTestCase):
|
||||
self._objectify(instance), [], [])
|
||||
|
||||
@mock.patch.object(nova.compute.utils, "get_image_metadata")
|
||||
@mock.patch.object(nova.image.glance, "get_remote_image_service")
|
||||
@mock.patch.object(nova.virt.fake.FakeDriver, "rescue")
|
||||
def test_rescue_with_base_image_when_image_not_specified(self,
|
||||
mock_rescue, mock_get_remote_image_service,
|
||||
mock_get_image_metadata):
|
||||
mock_rescue, mock_get_image_metadata):
|
||||
|
||||
image_ref = "image-ref"
|
||||
system_meta = {"image_base_image_ref": image_ref}
|
||||
@@ -2059,16 +2052,12 @@ class ComputeTestCase(BaseTestCase):
|
||||
mock_context.elevated.return_value = ctxt
|
||||
|
||||
mock_get_image_metadata.return_value = rescue_image_meta
|
||||
mock_image_service = "image_service"
|
||||
mock_get_remote_image_service.return_value = (mock_image_service, "id")
|
||||
|
||||
self.compute.rescue_instance(mock_context, instance=instance,
|
||||
rescue_password="password")
|
||||
|
||||
mock_get_remote_image_service.assert_called_with(ctxt,
|
||||
image_ref)
|
||||
mock_get_image_metadata.assert_called_with(ctxt,
|
||||
mock_image_service,
|
||||
self.compute.image_api,
|
||||
image_ref, instance)
|
||||
mock_rescue.assert_called_with(ctxt, instance, [],
|
||||
rescue_image_meta, 'password')
|
||||
|
||||
@@ -436,20 +436,20 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
migration['source_compute'], fake_quotas.reservations, cast=False)
|
||||
|
||||
def _test_delete_shelved_part(self, inst):
|
||||
image_service = self.compute_api.image_service
|
||||
self.mox.StubOutWithMock(image_service, 'delete')
|
||||
image_api = self.compute_api.image_api
|
||||
self.mox.StubOutWithMock(image_api, 'delete')
|
||||
|
||||
snapshot_id = inst.system_metadata.get('shelved_image_id')
|
||||
if snapshot_id == SHELVED_IMAGE:
|
||||
image_service.delete(self.context, snapshot_id).AndReturn(True)
|
||||
image_api.delete(self.context, snapshot_id).AndReturn(True)
|
||||
elif snapshot_id == SHELVED_IMAGE_NOT_FOUND:
|
||||
image_service.delete(self.context, snapshot_id).AndRaise(
|
||||
image_api.delete(self.context, snapshot_id).AndRaise(
|
||||
exception.ImageNotFound(image_id=snapshot_id))
|
||||
elif snapshot_id == SHELVED_IMAGE_NOT_AUTHORIZED:
|
||||
image_service.delete(self.context, snapshot_id).AndRaise(
|
||||
image_api.delete(self.context, snapshot_id).AndRaise(
|
||||
exception.ImageNotAuthorized(image_id=snapshot_id))
|
||||
elif snapshot_id == SHELVED_IMAGE_EXCEPTION:
|
||||
image_service.delete(self.context, snapshot_id).AndRaise(
|
||||
image_api.delete(self.context, snapshot_id).AndRaise(
|
||||
test.TestingException("Unexpected error"))
|
||||
|
||||
def _test_downed_host_part(self, inst, updates, delete_time, delete_type):
|
||||
@@ -1363,7 +1363,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
extra_props = dict(cow='moo', cat='meow')
|
||||
|
||||
self.mox.StubOutWithMock(compute_utils, 'get_image_metadata')
|
||||
self.mox.StubOutWithMock(self.compute_api.image_service,
|
||||
self.mox.StubOutWithMock(self.compute_api.image_api,
|
||||
'create')
|
||||
self.mox.StubOutWithMock(instance, 'save')
|
||||
self.mox.StubOutWithMock(self.compute_api.compute_rpcapi,
|
||||
@@ -1399,11 +1399,11 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
expected_props['backup_type'] = 'fake-backup-type'
|
||||
|
||||
compute_utils.get_image_metadata(
|
||||
self.context, self.compute_api.image_service,
|
||||
self.context, self.compute_api.image_api,
|
||||
FAKE_IMAGE_REF, instance).AndReturn(expected_meta)
|
||||
|
||||
fake_image = dict(id='fake-image-id')
|
||||
mock_method = self.compute_api.image_service.create(
|
||||
mock_method = self.compute_api.image_api.create(
|
||||
self.context, expected_meta)
|
||||
if create_fails:
|
||||
mock_method.AndRaise(test.TestingException())
|
||||
@@ -1534,7 +1534,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
def fake_get_all_by_instance(context, instance, use_slave=False):
|
||||
return copy.deepcopy(instance_bdms)
|
||||
|
||||
def fake_image_create(context, image_meta, data):
|
||||
def fake_image_create(context, image_meta, data=None):
|
||||
self.assertThat(image_meta, matchers.DictMatches(expect_meta))
|
||||
|
||||
def fake_volume_get(context, volume_id):
|
||||
@@ -1545,7 +1545,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
|
||||
self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
|
||||
fake_get_all_by_instance)
|
||||
self.stubs.Set(self.compute_api.image_service, 'create',
|
||||
self.stubs.Set(self.compute_api.image_api, 'create',
|
||||
fake_image_create)
|
||||
self.stubs.Set(self.compute_api.volume_api, 'get',
|
||||
fake_volume_get)
|
||||
|
||||
@@ -627,8 +627,8 @@ class ComputeGetImageMetadataTestCase(test.TestCase):
|
||||
"properties": {},
|
||||
}
|
||||
|
||||
self.image_service = nova.tests.image.fake._FakeImageService()
|
||||
self.stubs.Set(self.image_service, 'show', self._fake_show)
|
||||
self.mock_image_api = mock.Mock()
|
||||
self.mock_image_api.get.return_value = self.image
|
||||
|
||||
self.ctx = context.RequestContext('fake', 'fake')
|
||||
|
||||
@@ -659,24 +659,19 @@ class ComputeGetImageMetadataTestCase(test.TestCase):
|
||||
self.ctx, instance_obj.Instance(), self.instance,
|
||||
expected_attrs=instance_obj.INSTANCE_DEFAULT_FIELDS)
|
||||
|
||||
def _fake_show(self, ctx, image_id):
|
||||
return self.image
|
||||
|
||||
def test_get_image_meta(self):
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
self.ctx, self.image_service, 'fake-image', self.instance_obj)
|
||||
self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)
|
||||
|
||||
self.image['properties'] = 'DONTCARE'
|
||||
self.assertThat(self.image, matchers.DictMatches(image_meta))
|
||||
|
||||
def test_get_image_meta_no_image(self):
|
||||
def fake_show(ctx, image_id):
|
||||
raise exception.ImageNotFound(image_id='fake-image')
|
||||
|
||||
self.stubs.Set(self.image_service, 'show', fake_show)
|
||||
e = exception.ImageNotFound(image_id='fake-image')
|
||||
self.mock_image_api.get.side_effect = e
|
||||
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
self.ctx, self.image_service, 'fake-image', self.instance_obj)
|
||||
self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)
|
||||
|
||||
self.image['properties'] = 'DONTCARE'
|
||||
# NOTE(danms): The trip through system_metadata will stringify things
|
||||
@@ -690,23 +685,21 @@ class ComputeGetImageMetadataTestCase(test.TestCase):
|
||||
del self.instance['system_metadata'][k]
|
||||
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
self.ctx, self.image_service, 'fake-image', self.instance_obj)
|
||||
self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)
|
||||
|
||||
self.image['properties'] = 'DONTCARE'
|
||||
self.assertThat(self.image, matchers.DictMatches(image_meta))
|
||||
|
||||
def test_get_image_meta_no_image_no_image_system_meta(self):
|
||||
def fake_show(ctx, image_id):
|
||||
raise exception.ImageNotFound(image_id='fake-image')
|
||||
|
||||
self.stubs.Set(self.image_service, 'show', fake_show)
|
||||
e = exception.ImageNotFound(image_id='fake-image')
|
||||
self.mock_image_api.get.side_effect = e
|
||||
|
||||
for k in self.instance['system_metadata'].keys():
|
||||
if k.startswith('image_'):
|
||||
del self.instance['system_metadata'][k]
|
||||
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
self.ctx, self.image_service, 'fake-image', self.instance_obj)
|
||||
self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)
|
||||
|
||||
expected = {'properties': 'DONTCARE'}
|
||||
self.assertThat(expected, matchers.DictMatches(image_meta))
|
||||
|
||||
@@ -374,7 +374,7 @@ class ShelveComputeAPITestCase(test_compute.BaseTestCase):
|
||||
# sets a fake method.
|
||||
self2.images = {}
|
||||
|
||||
def fake_create(self2, ctxt, metadata):
|
||||
def fake_create(self2, ctxt, metadata, data=None):
|
||||
self.assertEqual(metadata['name'], 'vm01-shelved')
|
||||
metadata['id'] = '8b24ed3f-ee57-43bc-bc2e-fb2e9482bc42'
|
||||
return metadata
|
||||
|
||||
@@ -461,7 +461,8 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
flavor = db.flavor_get(self.context, 5)
|
||||
sys_meta = flavors.save_flavor_info({}, flavor)
|
||||
|
||||
nova.tests.image.fake.stub_out_image_service(self.stubs)
|
||||
self.image_service = nova.tests.image.fake.stub_out_image_service(
|
||||
self.stubs)
|
||||
self.test_instance = {
|
||||
'uuid': '32dfcb37-5af1-552b-357c-be8c3aa38310',
|
||||
'memory_kb': '1024000',
|
||||
@@ -2666,9 +2667,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
|
||||
self.flags(snapshots_directory='./', group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign different image_ref from nova/images/fakes for testing ami
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
|
||||
@@ -2682,7 +2680,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2696,7 +2694,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2718,9 +2716,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
virt_type='lxc',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign different image_ref from nova/images/fakes for testing ami
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
|
||||
@@ -2734,7 +2729,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2748,7 +2743,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2768,9 +2763,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
|
||||
self.flags(snapshots_directory='./', group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assuming that base image already exists in image_service
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
properties = {'instance_id': instance_ref['id'],
|
||||
@@ -2780,7 +2772,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2799,7 +2791,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2821,9 +2813,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
virt_type='lxc',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assuming that base image already exists in image_service
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
properties = {'instance_id': instance_ref['id'],
|
||||
@@ -2833,7 +2822,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2852,7 +2841,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2874,9 +2863,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
snapshots_directory='./',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assuming that base image already exists in image_service
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
properties = {'instance_id': instance_ref['id'],
|
||||
@@ -2886,7 +2872,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2900,7 +2886,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2923,9 +2909,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
virt_type='lxc',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assuming that base image already exists in image_service
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
properties = {'instance_id': instance_ref['id'],
|
||||
@@ -2935,7 +2918,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -2949,7 +2932,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -2970,9 +2953,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.flags(snapshots_directory='./',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign different image_ref from nova/images/fakes for
|
||||
# testing different base image
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
@@ -2987,7 +2967,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3000,7 +2980,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -3021,9 +3001,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
virt_type='lxc',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign different image_ref from nova/images/fakes for
|
||||
# testing different base image
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
@@ -3038,7 +3015,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'status': 'creating', 'properties': properties}
|
||||
# Create new image. It will be updated in snapshot method
|
||||
# To work with it from snapshot, the single image_service is needed
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3051,7 +3028,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -3071,9 +3048,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.flags(snapshots_directory='./',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign a non-existent image
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = '661122aa-1234-dede-fefe-babababababa'
|
||||
@@ -3084,7 +3058,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
snapshot_name = 'test-snap'
|
||||
sent_meta = {'name': snapshot_name, 'is_public': False,
|
||||
'status': 'creating', 'properties': properties}
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3097,7 +3071,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -3118,9 +3092,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
virt_type='lxc',
|
||||
group='libvirt')
|
||||
|
||||
# Start test
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign a non-existent image
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = '661122aa-1234-dede-fefe-babababababa'
|
||||
@@ -3131,7 +3102,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
snapshot_name = 'test-snap'
|
||||
sent_meta = {'name': snapshot_name, 'is_public': False,
|
||||
'status': 'creating', 'properties': properties}
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3144,7 +3115,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['status'], 'active')
|
||||
@@ -3164,8 +3135,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.flags(snapshots_directory='./',
|
||||
group='libvirt')
|
||||
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign an image with an architecture defined (x86_64)
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = 'a440c04b-79fa-479c-bed1-0b816eaec379'
|
||||
@@ -3179,7 +3148,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
snapshot_name = 'test-snap'
|
||||
sent_meta = {'name': snapshot_name, 'is_public': False,
|
||||
'status': 'creating', 'properties': properties}
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3192,7 +3161,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['properties']['architecture'], 'fake_arch')
|
||||
@@ -3215,8 +3184,6 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.flags(snapshots_directory='./',
|
||||
group='libvirt')
|
||||
|
||||
image_service = nova.tests.image.fake.FakeImageService()
|
||||
|
||||
# Assign a non-existent image
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["image_ref"] = '661122aa-1234-dede-fefe-babababababa'
|
||||
@@ -3229,7 +3196,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
snapshot_name = 'test-snap'
|
||||
sent_meta = {'name': snapshot_name, 'is_public': False,
|
||||
'status': 'creating', 'properties': properties}
|
||||
recv_meta = image_service.create(context, sent_meta)
|
||||
recv_meta = self.image_service.create(context, sent_meta)
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
@@ -3242,7 +3209,7 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
conn.snapshot(self.context, instance_ref, recv_meta['id'],
|
||||
func_call_matcher.call)
|
||||
|
||||
snapshot = image_service.show(context, recv_meta['id'])
|
||||
snapshot = self.image_service.show(context, recv_meta['id'])
|
||||
self.assertIsNone(func_call_matcher.match())
|
||||
self.assertEqual(snapshot['properties']['image_state'], 'available')
|
||||
self.assertEqual(snapshot['properties']['os_type'],
|
||||
|
||||
+13
-18
@@ -69,7 +69,7 @@ from nova.compute import utils as compute_utils
|
||||
from nova.compute import vm_mode
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.image import glance
|
||||
from nova import image
|
||||
from nova.objects import block_device as block_device_obj
|
||||
from nova.objects import flavor as flavor_obj
|
||||
from nova.objects import instance as instance_obj
|
||||
@@ -415,6 +415,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
self.disk_cachemodes[disk_type] = cache_mode
|
||||
|
||||
self._volume_api = volume.API()
|
||||
self._image_api = image.API()
|
||||
|
||||
@property
|
||||
def disk_cachemode(self):
|
||||
@@ -1478,15 +1479,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
except exception.InstanceNotFound:
|
||||
raise exception.InstanceNotRunning(instance_id=instance['uuid'])
|
||||
|
||||
(image_service, image_id) = glance.get_remote_image_service(
|
||||
context, instance['image_ref'])
|
||||
base_image_ref = instance['image_ref']
|
||||
|
||||
base = compute_utils.get_image_metadata(
|
||||
context, image_service, image_id, instance)
|
||||
context, self._image_api, base_image_ref, instance)
|
||||
|
||||
_image_service = glance.get_remote_image_service(context, image_href)
|
||||
snapshot_image_service, snapshot_image_id = _image_service
|
||||
snapshot = snapshot_image_service.show(context, snapshot_image_id)
|
||||
snapshot = self._image_api.get(context, image_href)
|
||||
|
||||
disk_path = libvirt_utils.find_disk(virt_dom)
|
||||
source_format = libvirt_utils.get_disk_type(disk_path)
|
||||
@@ -1586,10 +1584,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
update_task_state(task_state=task_states.IMAGE_UPLOADING,
|
||||
expected_state=task_states.IMAGE_PENDING_UPLOAD)
|
||||
with libvirt_utils.file_open(out_path) as image_file:
|
||||
image_service.update(context,
|
||||
image_href,
|
||||
metadata,
|
||||
image_file)
|
||||
self._image_api.update(context,
|
||||
image_href,
|
||||
metadata,
|
||||
image_file)
|
||||
LOG.info(_("Snapshot image upload complete"),
|
||||
instance=instance)
|
||||
|
||||
@@ -2083,11 +2081,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
image_meta = utils.get_image_from_system_metadata(system_meta)
|
||||
if not image_meta:
|
||||
image_ref = instance.get('image_ref')
|
||||
service, image_id = glance.get_remote_image_service(context,
|
||||
image_ref)
|
||||
image_meta = compute_utils.get_image_metadata(context,
|
||||
service,
|
||||
image_id,
|
||||
self._image_api,
|
||||
image_ref,
|
||||
instance)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
@@ -3451,10 +3447,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
block_device_info=None, write_to_disk=False):
|
||||
# We should get image metadata every time for generating xml
|
||||
if image_meta is None:
|
||||
(image_service, image_id) = glance.get_remote_image_service(
|
||||
context, instance['image_ref'])
|
||||
image_ref = instance['image_ref']
|
||||
image_meta = compute_utils.get_image_metadata(
|
||||
context, image_service, image_id, instance)
|
||||
context, self._image_api, image_ref, instance)
|
||||
# NOTE(danms): Stringifying a NetworkInfo will take a lock. Do
|
||||
# this ahead of time so that we don't acquire it while also
|
||||
# holding the logging lock.
|
||||
|
||||
Reference in New Issue
Block a user