Merge "Remove 'nova.image.api' module"
This commit is contained in:
commit
d6450879c7
|
@ -24,7 +24,7 @@ from nova.api.openstack import wsgi
|
|||
from nova.api import validation
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
import nova.image
|
||||
from nova.image import glance
|
||||
|
||||
|
||||
class ImageMetadataController(wsgi.Controller):
|
||||
|
@ -32,7 +32,7 @@ class ImageMetadataController(wsgi.Controller):
|
|||
|
||||
def __init__(self):
|
||||
super(ImageMetadataController, self).__init__()
|
||||
self.image_api = nova.image.API()
|
||||
self.image_api = glance.API()
|
||||
|
||||
def _get_image(self, context, image_id):
|
||||
try:
|
||||
|
|
|
@ -22,8 +22,7 @@ from nova.api.openstack.compute.views import images as views_images
|
|||
from nova.api.openstack import wsgi
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
import nova.image
|
||||
import nova.utils
|
||||
from nova.image import glance
|
||||
|
||||
|
||||
SUPPORTED_FILTERS = {
|
||||
|
@ -44,7 +43,7 @@ class ImagesController(wsgi.Controller):
|
|||
|
||||
def __init__(self):
|
||||
super(ImagesController, self).__init__()
|
||||
self._image_api = nova.image.API()
|
||||
self._image_api = glance.API()
|
||||
|
||||
def _get_filters(self, req):
|
||||
"""Return a dictionary of query param filters from the request.
|
||||
|
|
|
@ -40,7 +40,7 @@ import nova.conf
|
|||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.image import api as image_api
|
||||
from nova.image import glance
|
||||
from nova.network import neutron
|
||||
from nova import objects
|
||||
from nova.policies import servers as server_policies
|
||||
|
@ -1237,7 +1237,7 @@ class ServersController(wsgi.Controller):
|
|||
|
||||
# build location of newly-created image entity
|
||||
image_id = str(image['id'])
|
||||
image_ref = image_api.API().generate_image_url(image_id, context)
|
||||
image_ref = glance.API().generate_image_url(image_id, context)
|
||||
|
||||
resp = webob.Response(status_int=202)
|
||||
resp.headers['Location'] = image_ref
|
||||
|
|
|
@ -59,7 +59,7 @@ from nova import exception
|
|||
from nova import exception_wrapper
|
||||
from nova import hooks
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.network import constants
|
||||
from nova.network import model as network_model
|
||||
from nova.network import neutron
|
||||
|
@ -289,7 +289,7 @@ class API(base.Base):
|
|||
|
||||
def __init__(self, image_api=None, network_api=None, volume_api=None,
|
||||
**kwargs):
|
||||
self.image_api = image_api or image.API()
|
||||
self.image_api = image_api or glance.API()
|
||||
self.network_api = network_api or neutron.API()
|
||||
self.volume_api = volume_api or cinder.API()
|
||||
self._placementclient = None # Lazy-load on first access.
|
||||
|
@ -462,7 +462,7 @@ class API(base.Base):
|
|||
# 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.
|
||||
# Image object and hide all of that stuff within nova.image.glance
|
||||
kernel_id = kernel_image['id']
|
||||
|
||||
if ramdisk_id is not None:
|
||||
|
|
|
@ -74,7 +74,7 @@ from nova import exception
|
|||
from nova import exception_wrapper
|
||||
from nova import hooks
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova import manager
|
||||
from nova.network import model as network_model
|
||||
from nova.network import neutron
|
||||
|
@ -569,7 +569,7 @@ class ComputeManager(manager.Manager):
|
|||
self.virtapi = ComputeVirtAPI(self)
|
||||
self.network_api = neutron.API()
|
||||
self.volume_api = cinder.API()
|
||||
self.image_api = image.API()
|
||||
self.image_api = glance.API()
|
||||
self._last_bw_usage_poll = 0
|
||||
self._bw_usage_supported = True
|
||||
self.compute_api = compute.API()
|
||||
|
|
|
@ -1226,7 +1226,7 @@ def create_image(context, instance, name, image_type, image_api,
|
|||
:param instance: nova.objects.instance.Instance object
|
||||
:param name: string for name of the snapshot
|
||||
:param image_type: snapshot | backup
|
||||
:param image_api: instance of nova.image.API
|
||||
:param image_api: instance of nova.image.glance.API
|
||||
:param extra_properties: dict of extra image properties to include
|
||||
|
||||
"""
|
||||
|
|
|
@ -20,7 +20,7 @@ import oslo_messaging as messaging
|
|||
from nova import baserpc
|
||||
from nova.conductor import rpcapi
|
||||
import nova.conf
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
|
@ -84,7 +84,7 @@ class ComputeTaskAPI(object):
|
|||
|
||||
def __init__(self):
|
||||
self.conductor_compute_rpcapi = rpcapi.ComputeTaskAPI()
|
||||
self.image_api = image.API()
|
||||
self.image_api = glance.API()
|
||||
|
||||
# TODO(stephenfin): Remove the 'reservations' parameter since we don't use
|
||||
# reservations anymore
|
||||
|
|
|
@ -45,7 +45,7 @@ from nova import context as nova_context
|
|||
from nova.db import base
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova import manager
|
||||
from nova.network import neutron
|
||||
from nova import notifications
|
||||
|
@ -239,7 +239,7 @@ class ComputeTaskManager(base.Base):
|
|||
super(ComputeTaskManager, self).__init__()
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self.volume_api = cinder.API()
|
||||
self.image_api = image.API()
|
||||
self.image_api = glance.API()
|
||||
self.network_api = neutron.API()
|
||||
self.servicegroup_api = servicegroup.API()
|
||||
self.query_client = query.SchedulerQueryClient()
|
||||
|
|
|
@ -28,7 +28,7 @@ from nova import conf
|
|||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image as nova_image
|
||||
from nova.image import glance
|
||||
from nova.network import constants as neutron_constants
|
||||
from nova.network import neutron
|
||||
from nova import objects
|
||||
|
@ -401,7 +401,7 @@ class PrepResizeAtSourceTask(base.TaskBase):
|
|||
:param migration: Migration object from the source cell
|
||||
:param request_spec: RequestSpec object for the resize operation
|
||||
:param compute_rpcapi: instance of nova.compute.rpcapi.ComputeAPI
|
||||
:param image_api: instance of nova.image.api.API
|
||||
:param image_api: instance of nova.image.glance.API
|
||||
"""
|
||||
super(PrepResizeAtSourceTask, self).__init__(context, instance)
|
||||
self.migration = migration
|
||||
|
@ -636,7 +636,7 @@ class CrossCellMigrationTask(base.TaskBase):
|
|||
|
||||
self.network_api = neutron.API()
|
||||
self.volume_api = cinder.API()
|
||||
self.image_api = nova_image.API()
|
||||
self.image_api = glance.API()
|
||||
|
||||
# Keep an ordered dict of the sub-tasks completed so we can call their
|
||||
# rollback routines if something fails.
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# 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()
|
|
@ -1,199 +0,0 @@
|
|||
# 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
|
||||
from nova import profiler
|
||||
|
||||
|
||||
@profiler.trace_cls("nova_image")
|
||||
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()
|
||||
|
||||
@staticmethod
|
||||
def generate_image_url(image_ref, context):
|
||||
"""Generate an image URL from an image_ref.
|
||||
|
||||
:param image_ref: The image ref to generate URL
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
"""
|
||||
return "%s/images/%s" % (next(glance.get_api_servers(context)),
|
||||
image_ref)
|
||||
|
||||
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, include_locations=False,
|
||||
show_deleted=True):
|
||||
"""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.
|
||||
:param include_locations: (Optional) include locations in the returned
|
||||
dict of information if the image service API
|
||||
supports it. If the image service API does
|
||||
not support the locations attribute, it will
|
||||
still be included in the returned dict, as an
|
||||
empty list.
|
||||
:param show_deleted: (Optional) show the image even the status of
|
||||
image is deleted.
|
||||
"""
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.show(context, image_id,
|
||||
include_locations=include_locations,
|
||||
show_deleted=show_deleted)
|
||||
|
||||
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 False. 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)
|
||||
|
||||
def download(self, context, id_or_uri, data=None, dest_path=None,
|
||||
trusted_certs=None):
|
||||
"""Transfer image bits from Glance or a known source location to the
|
||||
supplied destination filepath.
|
||||
|
||||
:param context: The `nova.context.RequestContext` object for the
|
||||
request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
:param data: A file object to use in downloading image data.
|
||||
:param dest_path: Filepath to transfer image bits to.
|
||||
:param trusted_certs: A 'nova.objects.trusted_certs.TrustedCerts'
|
||||
object with a list of trusted image certificate
|
||||
IDs.
|
||||
|
||||
Note that because of the poor design of the
|
||||
`glance.ImageService.download` method, the function returns different
|
||||
things depending on what arguments are passed to it. If a data argument
|
||||
is supplied but no dest_path is specified (only done in the XenAPI virt
|
||||
driver's image.utils module) then None is returned from the method. If
|
||||
the data argument is not specified but a destination path *is*
|
||||
specified, then a writeable file handle to the destination path is
|
||||
constructed in the method and the image bits written to that file, and
|
||||
again, None is returned from the method. If no data argument is
|
||||
supplied and no dest_path argument is supplied (VMWare and XenAPI virt
|
||||
drivers), then the method returns an iterator to the image bits that
|
||||
the caller uses to write to wherever location it wants. Finally, if the
|
||||
allow_direct_url_schemes CONF option is set to something, then the
|
||||
nova.image.download modules are used to attempt to do an SCP copy of
|
||||
the image bits from a file location to the dest_path and None is
|
||||
returned after retrying one or more download locations (libvirt and
|
||||
Hyper-V virt drivers through nova.virt.images.fetch).
|
||||
|
||||
I think the above points to just how hacky/wacky all of this code is,
|
||||
and the reason it needs to be cleaned up and standardized across the
|
||||
virt driver callers.
|
||||
"""
|
||||
# TODO(jaypipes): Deprecate and remove this method entirely when we
|
||||
# move to a system that simply returns a file handle
|
||||
# to a bytestream iterator and allows the caller to
|
||||
# handle streaming/copying/zero-copy as they see fit.
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.download(context, image_id, data=data,
|
||||
dst_path=dest_path,
|
||||
trusted_certs=trusted_certs)
|
|
@ -48,6 +48,7 @@ from nova import exception
|
|||
import nova.image.download as image_xfers
|
||||
from nova import objects
|
||||
from nova.objects import fields
|
||||
from nova import profiler
|
||||
from nova import service_auth
|
||||
from nova import utils
|
||||
|
||||
|
@ -1012,7 +1013,181 @@ class UpdateGlanceImage(object):
|
|||
self.image_stream = stream
|
||||
|
||||
def start(self):
|
||||
image_service, image_id = (
|
||||
get_remote_image_service(self.context, self.image_id))
|
||||
image_service, image_id = get_remote_image_service(
|
||||
self.context, self.image_id)
|
||||
image_service.update(self.context, image_id, self.metadata,
|
||||
self.image_stream, purge_props=False)
|
||||
|
||||
|
||||
@profiler.trace_cls("nova_image")
|
||||
class API(object):
|
||||
"""API for interacting with the image service."""
|
||||
|
||||
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 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 get_remote_image_service and
|
||||
# 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 get_default_image_service()
|
||||
|
||||
@staticmethod
|
||||
def generate_image_url(image_ref, context):
|
||||
"""Generate an image URL from an image_ref.
|
||||
|
||||
:param image_ref: The image ref to generate URL
|
||||
:param context: The `nova.context.Context` object for the request
|
||||
"""
|
||||
return "%s/images/%s" % (next(get_api_servers(context)), image_ref)
|
||||
|
||||
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, include_locations=False,
|
||||
show_deleted=True):
|
||||
"""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.
|
||||
:param include_locations: (Optional) include locations in the returned
|
||||
dict of information if the image service API
|
||||
supports it. If the image service API does
|
||||
not support the locations attribute, it will
|
||||
still be included in the returned dict, as an
|
||||
empty list.
|
||||
:param show_deleted: (Optional) show the image even the status of
|
||||
image is deleted.
|
||||
"""
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.show(context, image_id,
|
||||
include_locations=include_locations,
|
||||
show_deleted=show_deleted)
|
||||
|
||||
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 False. 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)
|
||||
|
||||
def download(self, context, id_or_uri, data=None, dest_path=None,
|
||||
trusted_certs=None):
|
||||
"""Transfer image bits from Glance or a known source location to the
|
||||
supplied destination filepath.
|
||||
|
||||
:param context: The `nova.context.RequestContext` object for the
|
||||
request
|
||||
:param id_or_uri: A UUID identifier or an image URI to look up image
|
||||
information for.
|
||||
:param data: A file object to use in downloading image data.
|
||||
:param dest_path: Filepath to transfer image bits to.
|
||||
:param trusted_certs: A 'nova.objects.trusted_certs.TrustedCerts'
|
||||
object with a list of trusted image certificate
|
||||
IDs.
|
||||
|
||||
Note that because of the poor design of the
|
||||
`glance.ImageService.download` method, the function returns different
|
||||
things depending on what arguments are passed to it. If a data argument
|
||||
is supplied but no dest_path is specified (only done in the XenAPI virt
|
||||
driver's image.utils module) then None is returned from the method. If
|
||||
the data argument is not specified but a destination path *is*
|
||||
specified, then a writeable file handle to the destination path is
|
||||
constructed in the method and the image bits written to that file, and
|
||||
again, None is returned from the method. If no data argument is
|
||||
supplied and no dest_path argument is supplied (VMWare and XenAPI virt
|
||||
drivers), then the method returns an iterator to the image bits that
|
||||
the caller uses to write to wherever location it wants. Finally, if the
|
||||
allow_direct_url_schemes CONF option is set to something, then the
|
||||
nova.image.download modules are used to attempt to do an SCP copy of
|
||||
the image bits from a file location to the dest_path and None is
|
||||
returned after retrying one or more download locations (libvirt and
|
||||
Hyper-V virt drivers through nova.virt.images.fetch).
|
||||
|
||||
I think the above points to just how hacky/wacky all of this code is,
|
||||
and the reason it needs to be cleaned up and standardized across the
|
||||
virt driver callers.
|
||||
"""
|
||||
# TODO(jaypipes): Deprecate and remove this method entirely when we
|
||||
# move to a system that simply returns a file handle
|
||||
# to a bytestream iterator and allows the caller to
|
||||
# handle streaming/copying/zero-copy as they see fit.
|
||||
session, image_id = self._get_session_and_image_id(context, id_or_uri)
|
||||
return session.download(context, image_id, data=data,
|
||||
dst_path=dest_path,
|
||||
trusted_certs=trusted_certs)
|
||||
|
|
|
@ -28,7 +28,7 @@ from oslo_utils import timeutils
|
|||
import nova.conf
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova import image as image_api
|
||||
from nova.image import glance
|
||||
from nova.network import model as network_model
|
||||
from nova.network import neutron
|
||||
from nova.notifications.objects import base as notification_base
|
||||
|
@ -370,7 +370,7 @@ def info_from_instance(context, instance, network_info,
|
|||
# NOTE(mriedem): We can eventually drop this when we no longer
|
||||
# support legacy notifications since versioned notifications don't
|
||||
# use this.
|
||||
image_ref_url = image_api.API().generate_image_url(
|
||||
image_ref_url = glance.API().generate_image_url(
|
||||
instance.image_ref, context)
|
||||
|
||||
except ks_exc.EndpointNotFound:
|
||||
|
|
|
@ -194,7 +194,7 @@ class BootFromVolumeLargeRequestTest(test.TestCase,
|
|||
self.useFixture(nova_fixtures.NoopConductorFixture())
|
||||
# NOTE(gibi): Do not use 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' image
|
||||
# as that is defined with a separate kernel image, leading to one extra
|
||||
# call to nova.image.api.API.get from compute.api
|
||||
# call to nova.image.glance.API.get from compute.api
|
||||
# _handle_kernel_and_ramdisk()
|
||||
image1 = 'a2459075-d96c-40d5-893e-577ff92e721c'
|
||||
image2 = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
|
||||
|
@ -217,7 +217,7 @@ class BootFromVolumeLargeRequestTest(test.TestCase,
|
|||
|
||||
# Wrap the image service get method to check how many times it was
|
||||
# called.
|
||||
with mock.patch('nova.image.api.API.get',
|
||||
with mock.patch('nova.image.glance.API.get',
|
||||
wraps=self.image_service.show) as mock_image_get:
|
||||
self.api.post_server({'server': server})
|
||||
# Assert that there was caching of the GET /v2/images/{image_id}
|
||||
|
|
|
@ -42,7 +42,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
super(ImageMetaDataTestV21, self).setUp()
|
||||
self.controller = self.controller_class()
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_index(self, get_all_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata')
|
||||
res_dict = self.controller.index(req, '123')
|
||||
|
@ -50,7 +50,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertEqual(res_dict, expected)
|
||||
get_all_mocked.assert_called_once_with(mock.ANY, '123')
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_show(self, get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
res_dict = self.controller.show(req, '123', 'key1')
|
||||
|
@ -59,13 +59,13 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertEqual('value1', res_dict['meta']['key1'])
|
||||
get_mocked.assert_called_once_with(mock.ANY, '123')
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_show_not_found(self, _get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key9')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show, req, '123', 'key9')
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id='100'))
|
||||
def test_show_image_not_found(self, _get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '100/metadata/key1')
|
||||
|
@ -73,8 +73,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.controller.show, req, '100', 'key9')
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_create(self, get_mocked, update_mocked, quota_mocked):
|
||||
mock_result = copy.deepcopy(get_image_123())
|
||||
mock_result['properties']['key7'] = 'value7'
|
||||
|
@ -99,8 +99,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertEqual(expected_output, res)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id='100'))
|
||||
def test_create_image_not_found(self, _get_mocked, update_mocked,
|
||||
quota_mocked):
|
||||
|
@ -116,8 +116,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertFalse(update_mocked.called)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_update_all(self, get_mocked, update_mocked, quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata')
|
||||
req.method = 'PUT'
|
||||
|
@ -138,7 +138,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertEqual(expected_output, res)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id='100'))
|
||||
def test_update_all_image_not_found(self, _get_mocked, quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '100/metadata')
|
||||
|
@ -152,8 +152,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertFalse(quota_mocked.called)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_update_item(self, _get_mocked, update_mocked, quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
req.method = 'PUT'
|
||||
|
@ -173,7 +173,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertEqual(res, expected_output)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id='100'))
|
||||
def test_update_item_image_not_found(self, _get_mocked, quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '100/metadata/key1')
|
||||
|
@ -188,8 +188,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertFalse(quota_mocked.called)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get')
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get')
|
||||
def test_update_item_bad_body(self, get_mocked, update_mocked,
|
||||
quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
|
@ -207,8 +207,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
|
||||
@mock.patch(CHK_QUOTA_STR,
|
||||
side_effect=webob.exc.HTTPBadRequest())
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get')
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get')
|
||||
def test_update_item_too_many_keys(self, get_mocked, update_mocked,
|
||||
_quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
|
@ -224,8 +224,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertFalse(update_mocked.called)
|
||||
|
||||
@mock.patch(CHK_QUOTA_STR)
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_update_item_body_uri_mismatch(self, _get_mocked, update_mocked,
|
||||
quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/bad')
|
||||
|
@ -240,8 +240,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertFalse(quota_mocked.called)
|
||||
self.assertFalse(update_mocked.called)
|
||||
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_delete(self, _get_mocked, update_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
req.method = 'DELETE'
|
||||
|
@ -253,7 +253,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
|
||||
self.assertIsNone(res)
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_delete_not_found(self, _get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/blah')
|
||||
req.method = 'DELETE'
|
||||
|
@ -261,7 +261,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete, req, '123', 'blah')
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id='100'))
|
||||
def test_delete_image_not_found(self, _get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '100/metadata/key1')
|
||||
|
@ -272,8 +272,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
|
||||
@mock.patch(CHK_QUOTA_STR,
|
||||
side_effect=webob.exc.HTTPForbidden(explanation=''))
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_too_many_metadata_items_on_create(self, _get_mocked,
|
||||
update_mocked, _quota_mocked):
|
||||
body = {"metadata": {"foo": "bar"}}
|
||||
|
@ -288,8 +288,8 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
|
||||
@mock.patch(CHK_QUOTA_STR,
|
||||
side_effect=webob.exc.HTTPForbidden(explanation=''))
|
||||
@mock.patch('nova.image.api.API.update')
|
||||
@mock.patch('nova.image.api.API.get', return_value=get_image_123())
|
||||
@mock.patch('nova.image.glance.API.update')
|
||||
@mock.patch('nova.image.glance.API.get', return_value=get_image_123())
|
||||
def test_too_many_metadata_items_on_put(self, _get_mocked,
|
||||
update_mocked, _quota_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/blah')
|
||||
|
@ -303,7 +303,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
body=body)
|
||||
self.assertFalse(update_mocked.called)
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotAuthorized(image_id='123'))
|
||||
def test_image_not_authorized_update(self, _get_mocked):
|
||||
req = fakes.HTTPRequest.blank(self.base_path + '123/metadata/key1')
|
||||
|
@ -316,7 +316,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.controller.update, req, '123', 'key1',
|
||||
body=body)
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotAuthorized(image_id='123'))
|
||||
def test_image_not_authorized_update_all(self, _get_mocked):
|
||||
image_id = 131
|
||||
|
@ -333,7 +333,7 @@ class ImageMetaDataTestV21(test.NoDBTestCase):
|
|||
self.controller.update_all, req, image_id,
|
||||
body=body)
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotAuthorized(image_id='123'))
|
||||
def test_image_not_authorized_create(self, _get_mocked):
|
||||
image_id = 131
|
||||
|
|
|
@ -144,7 +144,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
},
|
||||
}
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=IMAGE_FIXTURES[0])
|
||||
@mock.patch('nova.image.glance.API.get', return_value=IMAGE_FIXTURES[0])
|
||||
def test_get_image(self, get_mocked):
|
||||
request = self.http_request.blank(self.url_base + 'images/123')
|
||||
actual_image = self.controller.show(request, '123')
|
||||
|
@ -152,7 +152,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
matchers.DictMatches(self.expected_image_123))
|
||||
get_mocked.assert_called_once_with(mock.ANY, '123')
|
||||
|
||||
@mock.patch('nova.image.api.API.get', return_value=IMAGE_FIXTURES[1])
|
||||
@mock.patch('nova.image.glance.API.get', return_value=IMAGE_FIXTURES[1])
|
||||
def test_get_image_with_custom_prefix(self, _get_mocked):
|
||||
self.flags(compute_link_prefix='https://zoo.com:42',
|
||||
glance_link_prefix='http://circus.com:34',
|
||||
|
@ -176,14 +176,14 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
|
||||
self.assertThat(actual_image, matchers.DictMatches(expected_image))
|
||||
|
||||
@mock.patch('nova.image.api.API.get',
|
||||
@mock.patch('nova.image.glance.API.get',
|
||||
side_effect=exception.ImageNotFound(image_id=''))
|
||||
def test_get_image_404(self, _get_mocked):
|
||||
fake_req = self.http_request.blank(self.url_base + 'images/unknown')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show, fake_req, 'unknown')
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all', return_value=IMAGE_FIXTURES)
|
||||
@mock.patch('nova.image.glance.API.get_all', return_value=IMAGE_FIXTURES)
|
||||
def test_get_image_details(self, get_all_mocked):
|
||||
request = self.http_request.blank(self.url_base + 'images/detail')
|
||||
response = self.controller.detail(request)
|
||||
|
@ -270,14 +270,14 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
|
||||
self.assertThat(expected, matchers.DictListMatches(response_list))
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all')
|
||||
@mock.patch('nova.image.glance.API.get_all')
|
||||
def test_get_image_details_with_limit(self, get_all_mocked):
|
||||
request = self.http_request.blank(self.url_base +
|
||||
'images/detail?limit=2')
|
||||
self.controller.detail(request)
|
||||
get_all_mocked.assert_called_once_with(mock.ANY, limit=2, filters={})
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all')
|
||||
@mock.patch('nova.image.glance.API.get_all')
|
||||
def test_get_image_details_with_limit_and_page_size(self, get_all_mocked):
|
||||
request = self.http_request.blank(
|
||||
self.url_base + 'images/detail?limit=2&page_size=1')
|
||||
|
@ -285,7 +285,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
get_all_mocked.assert_called_once_with(mock.ANY, limit=2, filters={},
|
||||
page_size=1)
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all')
|
||||
@mock.patch('nova.image.glance.API.get_all')
|
||||
def _detail_request(self, filters, request, get_all_mocked):
|
||||
self.controller.detail(request)
|
||||
get_all_mocked.assert_called_once_with(mock.ANY, filters=filters)
|
||||
|
@ -344,7 +344,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
request = self.http_request.blank(self.url_base + 'images/detail')
|
||||
self._detail_request(filters, request)
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all', side_effect=exception.Invalid)
|
||||
@mock.patch('nova.image.glance.API.get_all', side_effect=exception.Invalid)
|
||||
def test_image_detail_invalid_marker(self, _get_all_mocked):
|
||||
request = self.http_request.blank(self.url_base + '?marker=invalid')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.detail,
|
||||
|
@ -360,7 +360,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
def _check_response(self, controller_method, response, expected_code):
|
||||
self.assertEqual(expected_code, controller_method.wsgi_code)
|
||||
|
||||
@mock.patch('nova.image.api.API.delete')
|
||||
@mock.patch('nova.image.glance.API.delete')
|
||||
def test_delete_image(self, delete_mocked):
|
||||
request = self.http_request.blank(self.url_base + 'images/124')
|
||||
request.method = 'DELETE'
|
||||
|
@ -369,7 +369,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
self._check_response(delete_method, response, 204)
|
||||
delete_mocked.assert_called_once_with(mock.ANY, '124')
|
||||
|
||||
@mock.patch('nova.image.api.API.delete',
|
||||
@mock.patch('nova.image.glance.API.delete',
|
||||
side_effect=exception.ImageNotAuthorized(image_id='123'))
|
||||
def test_delete_deleted_image(self, _delete_mocked):
|
||||
# If you try to delete a deleted image, you get back 403 Forbidden.
|
||||
|
@ -378,7 +378,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete,
|
||||
request, '123')
|
||||
|
||||
@mock.patch('nova.image.api.API.delete',
|
||||
@mock.patch('nova.image.glance.API.delete',
|
||||
side_effect=exception.ImageNotFound(image_id='123'))
|
||||
def test_delete_image_not_found(self, _delete_mocked):
|
||||
request = self.http_request.blank(self.url_base + 'images/300')
|
||||
|
@ -386,7 +386,8 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete, request, '300')
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all', return_value=[IMAGE_FIXTURES[0]])
|
||||
@mock.patch('nova.image.glance.API.get_all',
|
||||
return_value=[IMAGE_FIXTURES[0]])
|
||||
def test_get_image_next_link(self, get_all_mocked):
|
||||
request = self.http_request.blank(
|
||||
self.url_base + 'imagesl?limit=1')
|
||||
|
@ -398,7 +399,8 @@ class ImagesControllerTestV21(test.NoDBTestCase):
|
|||
self.assertThat({'limit': ['1'], 'marker': [IMAGE_FIXTURES[0]['id']]},
|
||||
matchers.DictMatches(params))
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all', return_value=[IMAGE_FIXTURES[0]])
|
||||
@mock.patch('nova.image.glance.API.get_all',
|
||||
return_value=[IMAGE_FIXTURES[0]])
|
||||
def test_get_image_details_next_link(self, get_all_mocked):
|
||||
request = self.http_request.blank(
|
||||
self.url_base + 'images/detail?limit=1')
|
||||
|
|
|
@ -25,7 +25,6 @@ from nova.compute import task_states
|
|||
from nova.compute import vm_states
|
||||
import nova.conf
|
||||
from nova import exception
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova import objects
|
||||
from nova import test
|
||||
|
@ -85,7 +84,7 @@ class ServerActionsControllerTestV21(test.TestCase):
|
|||
project_id=fakes.FAKE_PROJECT_ID)
|
||||
self.context = self.req.environ['nova.context']
|
||||
|
||||
self.image_api = image.API()
|
||||
self.image_api = glance.API()
|
||||
# Assume that anything that hits the compute API and looks for a
|
||||
# RequestSpec doesn't care about it, since testing logic that deep
|
||||
# should be done in nova.tests.unit.compute.test_compute_api.
|
||||
|
|
|
@ -58,7 +58,7 @@ from nova.console import type as ctype
|
|||
from nova import context
|
||||
from nova.db import api as db
|
||||
from nova import exception
|
||||
from nova.image import api as image_api
|
||||
from nova.image import glance as image_api
|
||||
from nova.network import model as network_model
|
||||
from nova import objects
|
||||
from nova.objects import block_device as block_device_obj
|
||||
|
@ -724,7 +724,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
|||
else:
|
||||
return {}
|
||||
|
||||
self.stub_out('nova.image.api.API.get', image_api_get)
|
||||
self.stub_out('nova.image.glance.API.get', image_api_get)
|
||||
|
||||
block_device_mapping = [{
|
||||
'boot_index': 0,
|
||||
|
@ -3558,8 +3558,8 @@ class ComputeTestCase(BaseTestCase,
|
|||
self.assertEqual(state_dict['power_state'],
|
||||
instances[0]['power_state'])
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all')
|
||||
@mock.patch('nova.image.api.API.delete')
|
||||
@mock.patch('nova.image.glance.API.get_all')
|
||||
@mock.patch('nova.image.glance.API.delete')
|
||||
def test_rotate_backups(self, mock_delete, mock_get_all_images):
|
||||
instance = self._create_fake_instance_obj()
|
||||
instance_uuid = instance['uuid']
|
||||
|
@ -3604,7 +3604,7 @@ class ComputeTestCase(BaseTestCase,
|
|||
rotation=1)
|
||||
self.assertEqual(2, mock_delete.call_count)
|
||||
|
||||
@mock.patch('nova.image.api.API.get_all')
|
||||
@mock.patch('nova.image.glance.API.get_all')
|
||||
def test_rotate_backups_with_image_delete_failed(self,
|
||||
mock_get_all_images):
|
||||
instance = self._create_fake_instance_obj()
|
||||
|
@ -3664,7 +3664,7 @@ class ComputeTestCase(BaseTestCase,
|
|||
if image_id == uuids.image_id_4:
|
||||
raise exception.ImageDeleteConflict(reason='image is in use')
|
||||
|
||||
with mock.patch.object(nova.image.api.API, 'delete',
|
||||
with mock.patch.object(nova.image.glance.API, 'delete',
|
||||
side_effect=_check_image_id) as mock_delete:
|
||||
# Fake images 4,3,2 should be rotated in sequence
|
||||
self.compute._rotate_backups(self.context, instance=instance,
|
||||
|
|
|
@ -41,7 +41,7 @@ import nova.conf
|
|||
from nova import context
|
||||
from nova.db import api as db
|
||||
from nova import exception
|
||||
from nova.image import api as image_api
|
||||
from nova.image import glance as image_api
|
||||
from nova.network import constants
|
||||
from nova.network import model
|
||||
from nova.network import neutron as neutron_api
|
||||
|
@ -3100,7 +3100,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||
self.stub_out('nova.objects.BlockDeviceMappingList'
|
||||
'.get_by_instance_uuid',
|
||||
fake_bdm_list_get_by_instance_uuid)
|
||||
self.stub_out('nova.image.api.API.create', fake_image_create)
|
||||
self.stub_out('nova.image.glance.API.create', fake_image_create)
|
||||
self.stub_out('nova.volume.cinder.API.get',
|
||||
lambda self, context, volume_id:
|
||||
{'id': volume_id, 'display_description': ''})
|
||||
|
|
|
@ -8956,7 +8956,7 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
|
|||
migration.id = 0
|
||||
|
||||
@mock.patch('nova.compute.utils.notify_about_instance_action')
|
||||
@mock.patch('nova.image.api.API.generate_image_url',
|
||||
@mock.patch('nova.image.glance.API.generate_image_url',
|
||||
return_value='fake-url')
|
||||
@mock.patch.object(objects.Migration, 'get_by_id',
|
||||
return_value=migration)
|
||||
|
|
|
@ -42,7 +42,7 @@ from nova.db import api as db
|
|||
from nova.db.sqlalchemy import api as db_api
|
||||
from nova.db.sqlalchemy import api_models
|
||||
from nova import exception as exc
|
||||
from nova.image import api as image_api
|
||||
from nova.image import glance as image_api
|
||||
from nova import objects
|
||||
from nova.objects import base as obj_base
|
||||
from nova.objects import block_device as block_device_obj
|
||||
|
|
|
@ -86,7 +86,7 @@ class TestSendInstanceUpdateNotification(test.NoDBTestCase):
|
|||
mock.sentinel.ctxt, mock.sentinel.instance, None,
|
||||
populate_image_ref_url=True)
|
||||
|
||||
@mock.patch('nova.image.api.API.generate_image_url',
|
||||
@mock.patch('nova.image.glance.API.generate_image_url',
|
||||
side_effect=ks_exc.EndpointNotFound)
|
||||
def test_info_from_instance_image_api_endpoint_not_found_no_token(
|
||||
self, mock_gen_image_url):
|
||||
|
@ -105,7 +105,7 @@ class TestSendInstanceUpdateNotification(test.NoDBTestCase):
|
|||
self.assertEqual(instance.image_ref, payload['image_ref_url'])
|
||||
mock_gen_image_url.assert_called_once_with(instance.image_ref, ctxt)
|
||||
|
||||
@mock.patch('nova.image.api.API.generate_image_url',
|
||||
@mock.patch('nova.image.glance.API.generate_image_url',
|
||||
side_effect=ks_exc.EndpointNotFound)
|
||||
def test_info_from_instance_image_api_endpoint_not_found_with_token(
|
||||
self, mock_gen_image_url):
|
||||
|
@ -121,7 +121,7 @@ class TestSendInstanceUpdateNotification(test.NoDBTestCase):
|
|||
populate_image_ref_url=True)
|
||||
mock_gen_image_url.assert_called_once_with(instance.image_ref, ctxt)
|
||||
|
||||
@mock.patch('nova.image.api.API.generate_image_url')
|
||||
@mock.patch('nova.image.glance.API.generate_image_url')
|
||||
def test_info_from_instance_not_call_generate_image_url(
|
||||
self, mock_gen_image_url):
|
||||
ctxt = nova_context.get_admin_context()
|
||||
|
|
|
@ -54,7 +54,7 @@ class TestProfiler(test.NoDBTestCase):
|
|||
'nova.conductor.manager.ConductorManager',
|
||||
'nova.conductor.rpcapi.ComputeTaskAPI',
|
||||
'nova.conductor.rpcapi.ConductorAPI',
|
||||
'nova.image.api.API',
|
||||
'nova.image.glance.API',
|
||||
'nova.network.neutron.ClientWrapper',
|
||||
'nova.scheduler.manager.SchedulerManager',
|
||||
'nova.scheduler.rpcapi.SchedulerAPI',
|
||||
|
|
|
@ -171,7 +171,7 @@ class TestLocalDisk(test.NoDBTestCase):
|
|||
mock_upload_image.assert_called_once_with(
|
||||
'context', 'instance', mock_image_meta)
|
||||
|
||||
@mock.patch('nova.image.api.API.download')
|
||||
@mock.patch('nova.image.glance.API.download')
|
||||
@mock.patch('nova.virt.powervm.disk.driver.IterableToFileAdapter')
|
||||
@mock.patch('pypowervm.tasks.storage.upload_new_vdisk')
|
||||
@mock.patch('nova.virt.powervm.disk.driver.DiskAdapter._get_disk_name')
|
||||
|
|
|
@ -164,7 +164,7 @@ class TestSSPDiskAdapter(test.NoDBTestCase):
|
|||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('pypowervm.util.sanitize_file_name_for_api', autospec=True)
|
||||
@mock.patch('pypowervm.tasks.storage.crt_lu', autospec=True)
|
||||
@mock.patch('nova.image.api.API.download')
|
||||
@mock.patch('nova.image.glance.API.download')
|
||||
@mock.patch('nova.virt.powervm.disk.driver.IterableToFileAdapter',
|
||||
autospec=True)
|
||||
def test_create_disk_from_image(self, mock_it2f, mock_dl, mock_crt_lu,
|
||||
|
|
|
@ -82,7 +82,7 @@ class TestPowerVMDriver(test.NoDBTestCase):
|
|||
self.assertTrue(self.drv.capabilities['supports_extend_volume'])
|
||||
self.assertFalse(self.drv.capabilities['supports_multiattach'])
|
||||
|
||||
@mock.patch('nova.image.API')
|
||||
@mock.patch('nova.image.glance.API')
|
||||
@mock.patch('pypowervm.tasks.storage.ComprehensiveScrub', autospec=True)
|
||||
@mock.patch('oslo_utils.importutils.import_object_ns', autospec=True)
|
||||
@mock.patch('pypowervm.wrappers.managed_system.System', autospec=True)
|
||||
|
|
|
@ -25,7 +25,7 @@ from nova.virt.powervm import image
|
|||
class TestImage(test.TestCase):
|
||||
|
||||
@mock.patch('nova.utils.temporary_chown', autospec=True)
|
||||
@mock.patch('nova.image.api.API', autospec=True)
|
||||
@mock.patch('nova.image.glance.API', autospec=True)
|
||||
def test_stream_blockdev_to_glance(self, mock_api, mock_chown):
|
||||
mock_open = mock.mock_open()
|
||||
with mock.patch.object(six.moves.builtins, 'open', new=mock_open):
|
||||
|
@ -36,7 +36,7 @@ class TestImage(test.TestCase):
|
|||
mock_api.update.assert_called_with('context', 'image_id', 'metadata',
|
||||
mock_open.return_value)
|
||||
|
||||
@mock.patch('nova.image.api.API', autospec=True)
|
||||
@mock.patch('nova.image.glance.API', autospec=True)
|
||||
def test_generate_snapshot_metadata(self, mock_api):
|
||||
mock_api.get.return_value = {'name': 'image_name'}
|
||||
mock_instance = mock.Mock()
|
||||
|
|
|
@ -383,7 +383,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
def test_get_datacenter_ref_and_name_with_no_datastore(self):
|
||||
self._test_get_datacenter_ref_and_name()
|
||||
|
||||
@mock.patch('nova.image.api.API.get')
|
||||
@mock.patch('nova.image.glance.API.get')
|
||||
@mock.patch.object(vm_util, 'power_off_instance')
|
||||
@mock.patch.object(ds_util, 'disk_copy')
|
||||
@mock.patch.object(vm_util, 'get_vm_ref', return_value='fake-ref')
|
||||
|
@ -1138,7 +1138,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_attach_cdrom_to_vm.assert_called_once_with(
|
||||
vm_ref, self._instance, self._ds.ref, str(upload_iso_path))
|
||||
|
||||
@mock.patch('nova.image.api.API.get')
|
||||
@mock.patch('nova.image.glance.API.get')
|
||||
@mock.patch.object(vmops.LOG, 'debug')
|
||||
@mock.patch.object(vmops.VMwareVMOps, '_fetch_image_if_missing')
|
||||
@mock.patch.object(vmops.VMwareVMOps, '_get_vm_config_info')
|
||||
|
@ -1650,7 +1650,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock.patch.object(uuidutils, 'generate_uuid',
|
||||
return_value='tmp-uuid'),
|
||||
mock.patch.object(images, 'fetch_image'),
|
||||
mock.patch('nova.image.api.API.get'),
|
||||
mock.patch('nova.image.glance.API.get'),
|
||||
mock.patch.object(vutil, 'get_inventory_path',
|
||||
return_value=self._dc_info.name),
|
||||
mock.patch.object(self._vmops, '_get_extra_specs',
|
||||
|
|
|
@ -20,7 +20,7 @@ from os_xenapi.client import image
|
|||
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.image.api import API as image_api
|
||||
from nova.image.glance import API as image_api
|
||||
from nova.tests.unit.virt.xenapi import stubs
|
||||
from nova.virt.xenapi.image import utils
|
||||
from nova.virt.xenapi.image import vdi_stream
|
||||
|
|
|
@ -32,13 +32,13 @@ from nova.compute import utils as compute_utils
|
|||
import nova.conf
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
import nova.privsep.qemu
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
QEMU_IMG_LIMITS = processutils.ProcessLimits(
|
||||
cpu_time=30,
|
||||
|
|
|
@ -87,7 +87,7 @@ from nova import crypto
|
|||
from nova.db import constants as db_const
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.network import model as network_model
|
||||
from nova import objects
|
||||
from nova.objects import diagnostics as diagnostics_obj
|
||||
|
@ -379,7 +379,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
self.disk_cachemodes[disk_type] = cache_mode
|
||||
|
||||
self._volume_api = cinder.API()
|
||||
self._image_api = image.API()
|
||||
self._image_api = glance.API()
|
||||
|
||||
# The default choice for the sysinfo_serial config option is "unique"
|
||||
# which does not have a special function since the value is just the
|
||||
|
|
|
@ -34,7 +34,7 @@ import six
|
|||
import nova.conf
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
import nova.privsep.libvirt
|
||||
import nova.privsep.path
|
||||
from nova import utils
|
||||
|
@ -50,7 +50,7 @@ from nova.virt.libvirt import utils as libvirt_utils
|
|||
CONF = nova.conf.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
|
||||
# NOTE(neiljerram): Don't worry if this fails. This sometimes happens, with
|
||||
|
|
|
@ -24,13 +24,13 @@ from pypowervm.wrappers import virtual_io_server as pvm_vios
|
|||
|
||||
from nova import conf
|
||||
from nova import exception
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.virt.powervm.disk import driver as disk_dvr
|
||||
from nova.virt.powervm import vm
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = conf.CONF
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
|
||||
class LocalStorage(disk_dvr.DiskAdapter):
|
||||
|
|
|
@ -26,13 +26,13 @@ import pypowervm.wrappers.cluster as pvm_clust
|
|||
import pypowervm.wrappers.storage as pvm_stg
|
||||
|
||||
from nova import exception
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.virt.powervm.disk import driver as disk_drv
|
||||
from nova.virt.powervm import vm
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
|
||||
class SSPDiskAdapter(disk_drv.DiskAdapter):
|
||||
|
|
|
@ -34,7 +34,7 @@ from nova import conf as cfg
|
|||
from nova.console import type as console_type
|
||||
from nova import exception as exc
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.virt import configdrive
|
||||
from nova.virt import driver
|
||||
from nova.virt.powervm import host as pvm_host
|
||||
|
@ -118,7 +118,7 @@ class PowerVMDriver(driver.ComputeDriver):
|
|||
self.disk_dvr = importutils.import_object_ns(
|
||||
DISK_ADPT_NS, DISK_ADPT_MAPPINGS[CONF.powervm.disk_driver.lower()],
|
||||
self.adapter, self.host_wrapper.uuid)
|
||||
self.image_api = image.API()
|
||||
self.image_api = glance.API()
|
||||
|
||||
LOG.info("The PowerVM compute driver has been initialized.")
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ from oslo_vmware import rw_handles
|
|||
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova.objects import fields
|
||||
from nova.virt.vmwareapi import constants
|
||||
from nova.virt.vmwareapi import vm_util
|
||||
|
@ -45,7 +45,7 @@ from nova.virt.vmwareapi import vm_util
|
|||
CONF = cfg.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
QUEUE_BUFFER_SIZE = 10
|
||||
NFC_LEASE_UPDATE_PERIOD = 60 # update NFC lease every 60sec.
|
||||
|
|
|
@ -19,11 +19,11 @@ import tarfile
|
|||
from oslo_utils import importutils
|
||||
|
||||
from nova import exception
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
|
||||
_VDI_FORMAT_RAW = 1
|
||||
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
IMAGE_HANDLERS = {'direct_vhd': 'glance.GlanceStore',
|
||||
'vdi_local_dev': 'vdi_through_dev.VdiThroughDevStore',
|
||||
'vdi_remote_stream': 'vdi_stream.VdiStreamStore'}
|
||||
|
|
|
@ -22,7 +22,7 @@ from oslo_log import log as logging
|
|||
|
||||
import nova.conf
|
||||
from nova import exception
|
||||
from nova import image
|
||||
from nova.image import glance
|
||||
from nova import utils as nova_utils
|
||||
from nova.virt.xenapi.image import utils
|
||||
from nova.virt.xenapi import vm_utils
|
||||
|
@ -30,7 +30,7 @@ from nova.virt.xenapi import vm_utils
|
|||
CONF = nova.conf.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
IMAGE_API = image.API()
|
||||
IMAGE_API = glance.API()
|
||||
|
||||
|
||||
class VdiStreamStore(object):
|
||||
|
|
Loading…
Reference in New Issue