diff options
Diffstat (limited to 'ironic')
-rw-r--r-- | ironic/common/glance_service/base_image_service.py | 199 | ||||
-rw-r--r-- | ironic/common/glance_service/image_service.py (renamed from ironic/common/glance_service/v2/image_service.py) | 188 | ||||
-rw-r--r-- | ironic/common/glance_service/v2/__init__.py | 0 | ||||
-rw-r--r-- | ironic/common/image_service.py | 2 | ||||
-rw-r--r-- | ironic/tests/unit/common/test_glance_service.py | 33 | ||||
-rw-r--r-- | ironic/tests/unit/common/test_image_service.py | 2 | ||||
-rw-r--r-- | ironic/tests/unit/common/test_pxe_utils.py | 11 | ||||
-rw-r--r-- | ironic/tests/unit/drivers/modules/test_ipxe.py | 17 | ||||
-rw-r--r-- | ironic/tests/unit/drivers/modules/test_pxe.py | 20 |
9 files changed, 211 insertions, 261 deletions
diff --git a/ironic/common/glance_service/base_image_service.py b/ironic/common/glance_service/base_image_service.py deleted file mode 100644 index 7738edbbc..000000000 --- a/ironic/common/glance_service/base_image_service.py +++ /dev/null @@ -1,199 +0,0 @@ -# Copyright 2010 OpenStack Foundation -# Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -import os -import sys -import time - -from glanceclient import client -from glanceclient import exc as glance_exc -from oslo_log import log -import sendfile -import six -import six.moves.urllib.parse as urlparse - -from ironic.common import exception -from ironic.common.glance_service import service_utils -from ironic.common.i18n import _ -from ironic.common import keystone -from ironic.conf import CONF - - -LOG = log.getLogger(__name__) - -_GLANCE_SESSION = None - - -def _translate_image_exception(image_id, exc_value): - if isinstance(exc_value, (glance_exc.Forbidden, - glance_exc.Unauthorized)): - return exception.ImageNotAuthorized(image_id=image_id) - if isinstance(exc_value, glance_exc.NotFound): - return exception.ImageNotFound(image_id=image_id) - if isinstance(exc_value, glance_exc.BadRequest): - return exception.Invalid(exc_value) - return exc_value - - -def check_image_service(func): - """Creates a glance client if doesn't exists and calls the function.""" - @six.wraps(func) - def wrapper(self, *args, **kwargs): - """Wrapper around methods calls. - - :param image_href: href that describes the location of an image - """ - - if self.client: - return func(self, *args, **kwargs) - - global _GLANCE_SESSION - if not _GLANCE_SESSION: - _GLANCE_SESSION = keystone.get_session('glance') - - # NOTE(pas-ha) glanceclient uses Adapter-based SessionClient, - # so we can pass session and auth separately, makes things easier - service_auth = keystone.get_auth('glance') - - adapter = keystone.get_adapter('glance', session=_GLANCE_SESSION, - auth=service_auth) - self.endpoint = adapter.get_endpoint() - - user_auth = None - # NOTE(pas-ha) our ContextHook removes context.auth_token in noauth - # case, so when ironic is in noauth but glance is not, we will not - # enter the next if-block and use auth from [glance] config section - if self.context.auth_token: - user_auth = keystone.get_service_auth(self.context, self.endpoint, - service_auth) - self.client = client.Client(2, session=_GLANCE_SESSION, - auth=user_auth or service_auth, - endpoint_override=self.endpoint, - global_request_id=self.context.global_id) - return func(self, *args, **kwargs) - - return wrapper - - -class BaseImageService(object): - - def __init__(self, client=None, context=None): - self.client = client - self.context = context - self.endpoint = None - - def call(self, method, *args, **kwargs): - """Call a glance client method. - - If we get a connection error, - retry the request according to CONF.num_retries. - - :param context: The request context, for access checks. - :param method: The method requested to be called. - :param args: A list of positional arguments for the method called - :param kwargs: A dict of keyword arguments for the method called - - :raises: GlanceConnectionFailed - """ - retry_excs = (glance_exc.ServiceUnavailable, - glance_exc.InvalidEndpoint, - glance_exc.CommunicationError) - image_excs = (glance_exc.Forbidden, - glance_exc.Unauthorized, - glance_exc.NotFound, - glance_exc.BadRequest) - num_attempts = 1 + CONF.glance.num_retries - - # TODO(pas-ha) use retrying lib here - for attempt in range(1, num_attempts + 1): - try: - return getattr(self.client.images, method)(*args, **kwargs) - except retry_excs as e: - error_msg = ("Error contacting glance endpoint " - "%(endpoint)s for '%(method)s', attempt " - "%(attempt)s of %(num_attempts)s failed.") - LOG.exception(error_msg, {'endpoint': self.endpoint, - 'num_attempts': num_attempts, - 'attempt': attempt, - 'method': method}) - if attempt == num_attempts: - raise exception.GlanceConnectionFailed( - endpoint=self.endpoint, reason=e) - time.sleep(1) - except image_excs as e: - exc_type, exc_value, exc_trace = sys.exc_info() - new_exc = _translate_image_exception( - args[0], exc_value) - six.reraise(type(new_exc), new_exc, exc_trace) - - @check_image_service - def _show(self, image_href, method='get'): - """Returns a dict with image data for the given opaque image id. - - :param image_href: The opaque image identifier. - :returns: A dict containing image metadata. - - :raises: ImageNotFound - :raises: ImageUnacceptable if the image status is not active - """ - LOG.debug("Getting image metadata from glance. Image: %s", - image_href) - image_id = service_utils.parse_image_id(image_href) - - image = self.call(method, image_id) - - if not service_utils.is_image_active(image): - raise exception.ImageUnacceptable( - image_id=image_id, - reason=_("The image is required to be in an active state.")) - - if not service_utils.is_image_available(self.context, image): - raise exception.ImageNotFound(image_id=image_id) - - base_image_meta = service_utils.translate_from_glance(image) - return base_image_meta - - @check_image_service - def _download(self, image_href, data=None, method='data'): - """Calls out to Glance for data and writes data. - - :param image_href: The opaque image identifier. - :param data: (Optional) File object to write data to. - """ - image_id = service_utils.parse_image_id(image_href) - - if 'file' in CONF.glance.allowed_direct_url_schemes: - location = self._get_location(image_id) - url = urlparse.urlparse(location) - if url.scheme == "file": - with open(url.path, "r") as f: - filesize = os.path.getsize(f.name) - sendfile.sendfile(data.fileno(), f.fileno(), 0, filesize) - return - - image_chunks = self.call(method, image_id) - # NOTE(dtantsur): when using Glance V2, image_chunks is a wrapper - # around real data, so we have to check the wrapped data for None. - if image_chunks.wrapped is None: - raise exception.ImageDownloadFailed( - image_href=image_href, reason=_('image contains no data.')) - - if data is None: - return image_chunks - else: - for chunk in image_chunks: - data.write(chunk) diff --git a/ironic/common/glance_service/v2/image_service.py b/ironic/common/glance_service/image_service.py index 8cd7fe99a..6c926a669 100644 --- a/ironic/common/glance_service/v2/image_service.py +++ b/ironic/common/glance_service/image_service.py @@ -14,15 +14,21 @@ # under the License. import collections +import os import re +import sys import time +from glanceclient import client +from glanceclient import exc as glance_exc +from oslo_log import log from oslo_utils import uuidutils +import sendfile +import six from six.moves.urllib import parse as urlparse from swiftclient import utils as swift_utils -from ironic.common import exception as exc -from ironic.common.glance_service import base_image_service +from ironic.common import exception from ironic.common.glance_service import service_utils from ironic.common.i18n import _ from ironic.common import keystone @@ -33,7 +39,62 @@ TempUrlCacheElement = collections.namedtuple('TempUrlCacheElement', ['url', 'url_expires_at']) -class GlanceImageService(base_image_service.BaseImageService): +LOG = log.getLogger(__name__) +_GLANCE_SESSION = None + + +def _translate_image_exception(image_id, exc_value): + if isinstance(exc_value, (glance_exc.Forbidden, + glance_exc.Unauthorized)): + return exception.ImageNotAuthorized(image_id=image_id) + if isinstance(exc_value, glance_exc.NotFound): + return exception.ImageNotFound(image_id=image_id) + if isinstance(exc_value, glance_exc.BadRequest): + return exception.Invalid(exc_value) + return exc_value + + +def check_image_service(func): + """Creates a glance client if doesn't exists and calls the function.""" + @six.wraps(func) + def wrapper(self, *args, **kwargs): + """Wrapper around methods calls. + + :param image_href: href that describes the location of an image + """ + + if self.client: + return func(self, *args, **kwargs) + + global _GLANCE_SESSION + if not _GLANCE_SESSION: + _GLANCE_SESSION = keystone.get_session('glance') + + # NOTE(pas-ha) glanceclient uses Adapter-based SessionClient, + # so we can pass session and auth separately, makes things easier + service_auth = keystone.get_auth('glance') + + adapter = keystone.get_adapter('glance', session=_GLANCE_SESSION, + auth=service_auth) + self.endpoint = adapter.get_endpoint() + + user_auth = None + # NOTE(pas-ha) our ContextHook removes context.auth_token in noauth + # case, so when ironic is in noauth but glance is not, we will not + # enter the next if-block and use auth from [glance] config section + if self.context.auth_token: + user_auth = keystone.get_service_auth(self.context, self.endpoint, + service_auth) + self.client = client.Client(2, session=_GLANCE_SESSION, + auth=user_auth or service_auth, + endpoint_override=self.endpoint, + global_request_id=self.context.global_id) + return func(self, *args, **kwargs) + + return wrapper + + +class GlanceImageService(object): # A dictionary containing cached temp URLs in namedtuples # in format: @@ -45,11 +106,112 @@ class GlanceImageService(base_image_service.BaseImageService): # } _cache = {} - def show(self, image_id): - return self._show(image_id, method='get') + def __init__(self, client=None, context=None): + self.client = client + self.context = context + self.endpoint = None - def download(self, image_id, data=None): - return self._download(image_id, method='data', data=data) + def call(self, method, *args, **kwargs): + """Call a glance client method. + + If we get a connection error, + retry the request according to CONF.num_retries. + + :param context: The request context, for access checks. + :param method: The method requested to be called. + :param args: A list of positional arguments for the method called + :param kwargs: A dict of keyword arguments for the method called + + :raises: GlanceConnectionFailed + """ + retry_excs = (glance_exc.ServiceUnavailable, + glance_exc.InvalidEndpoint, + glance_exc.CommunicationError) + image_excs = (glance_exc.Forbidden, + glance_exc.Unauthorized, + glance_exc.NotFound, + glance_exc.BadRequest) + num_attempts = 1 + CONF.glance.num_retries + + # TODO(pas-ha) use retrying lib here + for attempt in range(1, num_attempts + 1): + try: + return getattr(self.client.images, method)(*args, **kwargs) + except retry_excs as e: + error_msg = ("Error contacting glance endpoint " + "%(endpoint)s for '%(method)s', attempt " + "%(attempt)s of %(num_attempts)s failed.") + LOG.exception(error_msg, {'endpoint': self.endpoint, + 'num_attempts': num_attempts, + 'attempt': attempt, + 'method': method}) + if attempt == num_attempts: + raise exception.GlanceConnectionFailed( + endpoint=self.endpoint, reason=e) + time.sleep(1) + except image_excs: + exc_type, exc_value, exc_trace = sys.exc_info() + new_exc = _translate_image_exception( + args[0], exc_value) + six.reraise(type(new_exc), new_exc, exc_trace) + + @check_image_service + def show(self, image_href): + """Returns a dict with image data for the given opaque image id. + + :param image_href: The opaque image identifier. + :returns: A dict containing image metadata. + + :raises: ImageNotFound + :raises: ImageUnacceptable if the image status is not active + """ + LOG.debug("Getting image metadata from glance. Image: %s", + image_href) + image_id = service_utils.parse_image_id(image_href) + + image = self.call('get', image_id) + + if not service_utils.is_image_active(image): + raise exception.ImageUnacceptable( + image_id=image_id, + reason=_("The image is required to be in an active state.")) + + if not service_utils.is_image_available(self.context, image): + raise exception.ImageNotFound(image_id=image_id) + + base_image_meta = service_utils.translate_from_glance(image) + return base_image_meta + + @check_image_service + def download(self, image_href, data=None): + """Calls out to Glance for data and writes data. + + :param image_href: The opaque image identifier. + :param data: (Optional) File object to write data to. + """ + image_id = service_utils.parse_image_id(image_href) + + if 'file' in CONF.glance.allowed_direct_url_schemes: + location = self._get_location(image_id) + url = urlparse.urlparse(location) + if url.scheme == "file": + with open(url.path, "r") as f: + filesize = os.path.getsize(f.name) + sendfile.sendfile(data.fileno(), f.fileno(), 0, filesize) + return + + image_chunks = self.call('data', image_id) + # NOTE(dtantsur): when using Glance V2, image_chunks is a wrapper + # around real data, so we have to check the wrapped data for None. + if image_chunks.wrapped is None: + raise exception.ImageDownloadFailed( + image_href=image_href, reason=_('image contains no data.')) + + if data is None: + return image_chunks + else: + for chunk in image_chunks: + data.write(chunk) def _generate_temp_url(self, path, seconds, key, method, endpoint, image_id): @@ -119,7 +281,7 @@ class GlanceImageService(base_image_service.BaseImageService): if ('id' not in image_info or not uuidutils.is_uuid_like(image_info['id'])): - raise exc.ImageUnacceptable(_( + raise exception.ImageUnacceptable(_( 'The given image info does not have a valid image id: %s') % image_info) @@ -138,7 +300,7 @@ class GlanceImageService(base_image_service.BaseImageService): endpoint_url = adapter.get_endpoint() if not endpoint_url: - raise exc.MissingParameterValue(_( + raise exception.MissingParameterValue(_( 'Swift temporary URLs require a Swift endpoint URL, but it ' 'was not found in the service catalog. ' 'You must provide "swift_endpoint_url" as a config option.')) @@ -159,7 +321,7 @@ class GlanceImageService(base_image_service.BaseImageService): key = swift_api.connection.head_account().get(key_header) if not key: - raise exc.MissingParameterValue(_( + raise exception.MissingParameterValue(_( 'Swift temporary URLs require a shared secret to be ' 'created. You must provide "swift_temp_url_key" as a ' 'config option or pre-generate the key on the project ' @@ -183,7 +345,7 @@ class GlanceImageService(base_image_service.BaseImageService): """Validate the required settings for a temporary URL.""" if (CONF.glance.swift_temp_url_duration < CONF.glance.swift_temp_url_expected_download_start_delay): - raise exc.InvalidParameterValue(_( + raise exception.InvalidParameterValue(_( '"swift_temp_url_duration" must be greater than or equal to ' '"[glance]swift_temp_url_expected_download_start_delay" ' 'option, otherwise the Swift temporary URL may expire before ' @@ -191,7 +353,7 @@ class GlanceImageService(base_image_service.BaseImageService): seed_num_chars = CONF.glance.swift_store_multiple_containers_seed if (seed_num_chars is None or seed_num_chars < 0 or seed_num_chars > 32): - raise exc.InvalidParameterValue(_( + raise exception.InvalidParameterValue(_( "An integer value between 0 and 32 is required for" " swift_store_multiple_containers_seed.")) @@ -238,7 +400,7 @@ class GlanceImageService(base_image_service.BaseImageService): image_meta = self.call('get', image_id) if not service_utils.is_image_available(self.context, image_meta): - raise exc.ImageNotFound(image_id=image_id) + raise exception.ImageNotFound(image_id=image_id) return getattr(image_meta, 'direct_url', None) diff --git a/ironic/common/glance_service/v2/__init__.py b/ironic/common/glance_service/v2/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/ironic/common/glance_service/v2/__init__.py +++ /dev/null diff --git a/ironic/common/image_service.py b/ironic/common/image_service.py index 15f0f2cd4..bde9173d0 100644 --- a/ironic/common/image_service.py +++ b/ironic/common/image_service.py @@ -29,7 +29,7 @@ from six.moves import http_client import six.moves.urllib.parse as urlparse from ironic.common import exception -from ironic.common.glance_service.v2 import image_service +from ironic.common.glance_service import image_service from ironic.common.i18n import _ from ironic.common import utils diff --git a/ironic/tests/unit/common/test_glance_service.py b/ironic/tests/unit/common/test_glance_service.py index 86ffd32c9..9e5c93a43 100644 --- a/ironic/tests/unit/common/test_glance_service.py +++ b/ironic/tests/unit/common/test_glance_service.py @@ -27,9 +27,8 @@ import testtools from ironic.common import context from ironic.common import exception -from ironic.common.glance_service import base_image_service +from ironic.common.glance_service import image_service from ironic.common.glance_service import service_utils -from ironic.common.glance_service.v2 import image_service as glance_v2 from ironic.common import image_service as service from ironic.tests import base from ironic.tests.unit import stubs @@ -245,9 +244,9 @@ class TestGlanceImageService(base.TestCase): self.config(allowed_direct_url_schemes=['file'], group='glance') - # patching open in base_image_service module namespace + # patching open in image_service module namespace # to make call-spec assertions - with mock.patch('ironic.common.glance_service.base_image_service.open', + with mock.patch('ironic.common.glance_service.image_service.open', new=mock.mock_open(), create=True) as mock_ironic_open: with open('/whatever/target', 'w') as mock_target_fd: stub_service.download(image_id, mock_target_fd) @@ -356,7 +355,7 @@ class CheckImageServiceTestCase(base.TestCase): region_name='SomeRegion', interface='internal', group='glance') - base_image_service._GLANCE_SESSION = None + image_service._GLANCE_SESSION = None def test_check_image_service_client_already_set(self, mock_gclient, mock_sess, mock_adapter, @@ -366,7 +365,7 @@ class CheckImageServiceTestCase(base.TestCase): self.service.client = True - wrapped_func = base_image_service.check_image_service(func) + wrapped_func = image_service.check_image_service(func) self.assertTrue(wrapped_func(self.service)) self.assertEqual(0, mock_gclient.call_count) self.assertEqual(0, mock_sess.call_count) @@ -393,7 +392,7 @@ class CheckImageServiceTestCase(base.TestCase): uuid = uuidutils.generate_uuid() params = {'image_href': uuid} - wrapped_func = base_image_service.check_image_service(func) + wrapped_func = image_service.check_image_service(func) self.assertEqual(((), params), wrapped_func(self.service, **params)) self._assert_client_call(mock_gclient, 'glance_url') mock_auth.assert_called_once_with('glance') @@ -417,7 +416,7 @@ class CheckImageServiceTestCase(base.TestCase): uuid = uuidutils.generate_uuid() params = {'image_href': uuid} - wrapped_func = base_image_service.check_image_service(func) + wrapped_func = image_service.check_image_service(func) self.assertEqual(((), params), wrapped_func(self.service, **params)) self._assert_client_call(mock_gclient, 'glance_url', user=True) mock_sess.assert_called_once_with('glance') @@ -441,9 +440,9 @@ class CheckImageServiceTestCase(base.TestCase): uuid = uuidutils.generate_uuid() params = {'image_href': uuid} - wrapped_func = base_image_service.check_image_service(func) + wrapped_func = image_service.check_image_service(func) self.assertEqual(((), params), wrapped_func(self.service, **params)) - self.assertEqual('none', base_image_service.CONF.glance.auth_type) + self.assertEqual('none', image_service.CONF.glance.auth_type) self._assert_client_call(mock_gclient, 'foo') mock_sess.assert_called_once_with('glance') mock_adapter.assert_called_once_with('glance', @@ -785,8 +784,8 @@ class TestSwiftTempUrlCache(base.TestCase): {'uuid': fake_image['id'], 'exp_time': exp_time} ) self.glance_service._cache[fake_image['id']] = ( - glance_v2.TempUrlCacheElement(url=temp_url, - url_expires_at=exp_time) + image_service.TempUrlCacheElement(url=temp_url, + url_expires_at=exp_time) ) cleanup_mock = mock.Mock() @@ -813,7 +812,7 @@ class TestSwiftTempUrlCache(base.TestCase): ) query = '?temp_url_sig=hmacsig&temp_url_expires=%s' self.glance_service._cache[fake_image['id']] = ( - glance_v2.TempUrlCacheElement( + image_service.TempUrlCacheElement( url=(CONF.glance.swift_endpoint_url + path + query % old_exp_time), url_expires_at=old_exp_time) @@ -842,21 +841,21 @@ class TestSwiftTempUrlCache(base.TestCase): def test_remove_expired_items_from_cache(self): expired_items = { - uuidutils.generate_uuid(): glance_v2.TempUrlCacheElement( + uuidutils.generate_uuid(): image_service.TempUrlCacheElement( 'fake-url-1', int(time.time()) - 10 ), - uuidutils.generate_uuid(): glance_v2.TempUrlCacheElement( + uuidutils.generate_uuid(): image_service.TempUrlCacheElement( 'fake-url-2', int(time.time()) + 90 # Agent won't be able to start in time ) } valid_items = { - uuidutils.generate_uuid(): glance_v2.TempUrlCacheElement( + uuidutils.generate_uuid(): image_service.TempUrlCacheElement( 'fake-url-3', int(time.time()) + 1000 ), - uuidutils.generate_uuid(): glance_v2.TempUrlCacheElement( + uuidutils.generate_uuid(): image_service.TempUrlCacheElement( 'fake-url-4', int(time.time()) + 2000 ) diff --git a/ironic/tests/unit/common/test_image_service.py b/ironic/tests/unit/common/test_image_service.py index 97c374c04..243d4d90d 100644 --- a/ironic/tests/unit/common/test_image_service.py +++ b/ironic/tests/unit/common/test_image_service.py @@ -23,7 +23,7 @@ import six.moves.builtins as __builtin__ from six.moves import http_client from ironic.common import exception -from ironic.common.glance_service.v2 import image_service as glance_v2_service +from ironic.common.glance_service import image_service as glance_v2_service from ironic.common import image_service from ironic.tests import base diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py index b082a059a..15e3414b4 100644 --- a/ironic/tests/unit/common/test_pxe_utils.py +++ b/ironic/tests/unit/common/test_pxe_utils.py @@ -25,7 +25,7 @@ from oslo_utils import uuidutils import six from ironic.common import exception -from ironic.common.glance_service import base_image_service +from ironic.common.glance_service import image_service from ironic.common import pxe_utils from ironic.common import states from ironic.common import utils @@ -1126,8 +1126,7 @@ class PXEInterfacesTestCase(db_base.DbTestCase): self.assertRaises(exception.MissingParameterValue, pxe_utils.get_image_info, self.node) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def _test_get_instance_image_info(self, show_mock): properties = {'properties': {u'kernel_id': u'instance_kernel_uuid', u'ramdisk_id': u'instance_ramdisk_uuid'}} @@ -1147,8 +1146,7 @@ class PXEInterfacesTestCase(db_base.DbTestCase): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: image_info = pxe_utils.get_instance_image_info(task) - show_mock.assert_called_once_with(mock.ANY, 'glance://image_uuid', - method='get') + show_mock.assert_called_once_with(mock.ANY, 'glance://image_uuid') self.assertEqual(expected_info, image_info) # test with saved info @@ -1183,8 +1181,7 @@ class PXEInterfacesTestCase(db_base.DbTestCase): self.assertEqual({}, image_info) boot_opt_mock.assert_called_once_with(task.node) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_get_instance_image_info_whole_disk_image(self, show_mock): properties = {'properties': None} show_mock.return_value = properties diff --git a/ironic/tests/unit/drivers/modules/test_ipxe.py b/ironic/tests/unit/drivers/modules/test_ipxe.py index e05cdcd47..f8fdb50f7 100644 --- a/ironic/tests/unit/drivers/modules/test_ipxe.py +++ b/ironic/tests/unit/drivers/modules/test_ipxe.py @@ -26,7 +26,7 @@ from ironic.common import boot_devices from ironic.common import boot_modes from ironic.common import dhcp_factory from ironic.common import exception -from ironic.common.glance_service import base_image_service +from ironic.common.glance_service import image_service from ironic.common import pxe_utils from ironic.common import states from ironic.common import utils as common_utils @@ -91,8 +91,7 @@ class iPXEBootTestCase(db_base.DbTestCase): shared=True) as task: self.assertEqual(expected, task.driver.get_properties()) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_good(self, mock_glance): mock_glance.return_value = {'properties': {'kernel_id': 'fake-kernel', 'ramdisk_id': 'fake-initr'}} @@ -100,16 +99,14 @@ class iPXEBootTestCase(db_base.DbTestCase): shared=True) as task: task.driver.boot.validate(task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_good_whole_disk_image(self, mock_glance): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: task.node.driver_internal_info['is_whole_disk_image'] = True task.driver.boot.validate(task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) @mock.patch.object(noop_storage.NoopStorage, 'should_write_image', autospec=True) def test_validate_skip_check_write_image_false(self, mock_write, @@ -178,7 +175,7 @@ class iPXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.InvalidParameterValue, task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_no_image_kernel_ramdisk_props(self, mock_glance): mock_glance.return_value = {'properties': {}} @@ -188,7 +185,7 @@ class iPXEBootTestCase(db_base.DbTestCase): task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_glance_image_doesnt_exists(self, mock_glance): mock_glance.side_effect = exception.ImageNotFound('not found') @@ -197,7 +194,7 @@ class iPXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.InvalidParameterValue, task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_glance_conn_problem(self, mock_glance): exceptions = (exception.GlanceConnectionFailed('connection fail'), diff --git a/ironic/tests/unit/drivers/modules/test_pxe.py b/ironic/tests/unit/drivers/modules/test_pxe.py index 6ab7543ed..bbc49e139 100644 --- a/ironic/tests/unit/drivers/modules/test_pxe.py +++ b/ironic/tests/unit/drivers/modules/test_pxe.py @@ -27,7 +27,7 @@ from ironic.common import boot_devices from ironic.common import boot_modes from ironic.common import dhcp_factory from ironic.common import exception -from ironic.common.glance_service import base_image_service +from ironic.common.glance_service import image_service from ironic.common import pxe_utils from ironic.common import states from ironic.common import utils as common_utils @@ -93,8 +93,7 @@ class PXEBootTestCase(db_base.DbTestCase): shared=True) as task: self.assertEqual(expected, task.driver.get_properties()) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_good(self, mock_glance): mock_glance.return_value = {'properties': {'kernel_id': 'fake-kernel', 'ramdisk_id': 'fake-initr'}} @@ -102,16 +101,14 @@ class PXEBootTestCase(db_base.DbTestCase): shared=True) as task: task.driver.boot.validate(task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_good_whole_disk_image(self, mock_glance): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: task.node.driver_internal_info['is_whole_disk_image'] = True task.driver.boot.validate(task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) @mock.patch.object(noop_storage.NoopStorage, 'should_write_image', autospec=True) def test_validate_skip_check_write_image_false(self, mock_write, @@ -180,8 +177,7 @@ class PXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.InvalidParameterValue, task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_no_image_kernel_ramdisk_props(self, mock_glance): mock_glance.return_value = {'properties': {}} with task_manager.acquire(self.context, self.node.uuid, @@ -190,8 +186,7 @@ class PXEBootTestCase(db_base.DbTestCase): task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_glance_image_doesnt_exists(self, mock_glance): mock_glance.side_effect = exception.ImageNotFound('not found') with task_manager.acquire(self.context, self.node.uuid, @@ -199,8 +194,7 @@ class PXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.InvalidParameterValue, task.driver.boot.validate, task) - @mock.patch.object(base_image_service.BaseImageService, '_show', - autospec=True) + @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_validate_fail_glance_conn_problem(self, mock_glance): exceptions = (exception.GlanceConnectionFailed('connection fail'), exception.ImageNotAuthorized('not authorized'), |