Merge "Remove deprecated nova.image.download hook"

This commit is contained in:
Zuul 2020-06-26 08:53:36 +00:00 committed by Gerrit Code Review
commit 7f4d59a674
4 changed files with 25 additions and 92 deletions

View File

@ -1,54 +0,0 @@
# Copyright 2013 Red Hat, Inc.
# 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.
from oslo_log import log as logging
import stevedore.driver
import stevedore.extension
LOG = logging.getLogger(__name__)
def load_transfer_modules():
module_dictionary = {}
ex = stevedore.extension.ExtensionManager('nova.image.download.modules')
for module_name in ex.names():
mgr = stevedore.driver.DriverManager(
namespace='nova.image.download.modules',
name=module_name,
invoke_on_load=False)
schemes_list = mgr.driver.get_schemes()
for scheme in schemes_list:
if scheme in module_dictionary:
LOG.error('%(scheme)s is registered as a module twice. '
'%(module_name)s is not being used.',
{'scheme': scheme,
'module_name': module_name})
else:
module_dictionary[scheme] = mgr.driver
if module_dictionary:
LOG.warning('The nova.image.download.modules extension point is '
'deprecated for removal starting in the 17.0.0 Queens '
'release and may be removed as early as the 18.0.0 Rocky '
'release. It is not maintained and there is no indication '
'of its use in production clouds. If you are using this '
'extension point, please make the nova development team '
'aware by contacting us in the #openstack-nova freenode '
'IRC channel or on the openstack-discuss mailing list.')
return module_dictionary

View File

@ -43,7 +43,6 @@ import six.moves.urllib.parse as urlparse
import nova.conf import nova.conf
from nova import exception from nova import exception
import nova.image.download as image_xfers
from nova import objects from nova import objects
from nova.objects import fields from nova.objects import fields
from nova import profiler from nova import profiler
@ -217,24 +216,10 @@ class GlanceImageServiceV2(object):
def __init__(self, client=None): def __init__(self, client=None):
self._client = client or GlanceClientWrapper() self._client = client or GlanceClientWrapper()
# NOTE(jbresnah) build the table of download handlers at the beginning # NOTE(danms): This used to be built from a list of external modules
# so that operators can catch errors at load time rather than whenever # that were loaded at runtime. Preserve this list for implementations
# a user attempts to use a module. Note this cannot be done in glance # to be added here.
# space when this python module is loaded because the download module
# may require configuration options to be parsed.
self._download_handlers = {} self._download_handlers = {}
download_modules = image_xfers.load_transfer_modules()
for scheme, mod in download_modules.items():
if scheme not in CONF.glance.allowed_direct_url_schemes:
continue
try:
self._download_handlers[scheme] = mod.get_download_handler()
except Exception as ex:
LOG.error('When loading the module %(module_str)s the '
'following error occurred: %(ex)s',
{'module_str': str(mod), 'ex': ex})
def show(self, context, image_id, include_locations=False, def show(self, context, image_id, include_locations=False,
show_deleted=True): show_deleted=True):
@ -273,15 +258,12 @@ class GlanceImageServiceV2(object):
return image return image
def _get_transfer_module(self, scheme): def _get_transfer_method(self, scheme):
"""Returns a transfer method for scheme, or None."""
try: try:
return self._download_handlers[scheme] return self._download_handlers[scheme]
except KeyError: except KeyError:
return None return None
except Exception:
LOG.error("Failed to instantiate the download handler "
"for %(scheme)s", {'scheme': scheme})
return
def detail(self, context, **kwargs): def detail(self, context, **kwargs):
"""Calls out to Glance for a list of detailed image information.""" """Calls out to Glance for a list of detailed image information."""
@ -323,10 +305,10 @@ class GlanceImageServiceV2(object):
loc_url = entry['url'] loc_url = entry['url']
loc_meta = entry['metadata'] loc_meta = entry['metadata']
o = urlparse.urlparse(loc_url) o = urlparse.urlparse(loc_url)
xfer_mod = self._get_transfer_module(o.scheme) xfer_method = self._get_transfer_method(o.scheme)
if xfer_mod: if xfer_method:
try: try:
xfer_mod.download(context, o, dst_path, loc_meta) xfer_method(context, o, dst_path, loc_meta)
LOG.info("Successfully transferred using %s", o.scheme) LOG.info("Successfully transferred using %s", o.scheme)
return return
except Exception: except Exception:

View File

@ -686,7 +686,7 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
with testtools.ExpectedException(exception.ImageUnacceptable): with testtools.ExpectedException(exception.ImageUnacceptable):
service.download(ctx, mock.sentinel.image_id) service.download(ctx, mock.sentinel.image_id)
@mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_module') @mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_method')
@mock.patch('nova.image.glance.GlanceImageServiceV2.show') @mock.patch('nova.image.glance.GlanceImageServiceV2.show')
def test_download_direct_file_uri_v2(self, show_mock, get_tran_mock): def test_download_direct_file_uri_v2(self, show_mock, get_tran_mock):
self.flags(allowed_direct_url_schemes=['file'], group='glance') self.flags(allowed_direct_url_schemes=['file'], group='glance')
@ -712,11 +712,11 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
mock.sentinel.image_id, mock.sentinel.image_id,
include_locations=True) include_locations=True)
get_tran_mock.assert_called_once_with('file') get_tran_mock.assert_called_once_with('file')
tran_mod.download.assert_called_once_with(ctx, mock.ANY, tran_mod.assert_called_once_with(ctx, mock.ANY,
mock.sentinel.dst_path, mock.sentinel.dst_path,
mock.sentinel.loc_meta) mock.sentinel.loc_meta)
@mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_module') @mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_method')
@mock.patch('nova.image.glance.GlanceImageServiceV2.show') @mock.patch('nova.image.glance.GlanceImageServiceV2.show')
@mock.patch('nova.image.glance.GlanceImageServiceV2._safe_fsync') @mock.patch('nova.image.glance.GlanceImageServiceV2._safe_fsync')
def test_download_direct_exception_fallback_v2( def test_download_direct_exception_fallback_v2(
@ -733,9 +733,9 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
} }
] ]
} }
tran_mod = mock.MagicMock() tran_method = mock.MagicMock()
tran_mod.download.side_effect = Exception tran_method.side_effect = Exception
get_tran_mock.return_value = tran_mod get_tran_mock.return_value = tran_method
client = mock.MagicMock() client = mock.MagicMock()
client.call.return_value = fake_glance_response([1, 2, 3]) client.call.return_value = fake_glance_response([1, 2, 3])
ctx = mock.sentinel.ctx ctx = mock.sentinel.ctx
@ -752,9 +752,9 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
mock.sentinel.image_id, mock.sentinel.image_id,
include_locations=True) include_locations=True)
get_tran_mock.assert_called_once_with('file') get_tran_mock.assert_called_once_with('file')
tran_mod.download.assert_called_once_with(ctx, mock.ANY, tran_method.assert_called_once_with(ctx, mock.ANY,
mock.sentinel.dst_path, mock.sentinel.dst_path,
mock.sentinel.loc_meta) mock.sentinel.loc_meta)
client.call.assert_called_once_with( client.call.assert_called_once_with(
ctx, 2, 'data', args=(mock.sentinel.image_id,)) ctx, 2, 'data', args=(mock.sentinel.image_id,))
fsync_mock.assert_called_once_with(writer) fsync_mock.assert_called_once_with(writer)
@ -771,7 +771,7 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
] ]
) )
@mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_module') @mock.patch('nova.image.glance.GlanceImageServiceV2._get_transfer_method')
@mock.patch('nova.image.glance.GlanceImageServiceV2.show') @mock.patch('nova.image.glance.GlanceImageServiceV2.show')
@mock.patch('nova.image.glance.GlanceImageServiceV2._safe_fsync') @mock.patch('nova.image.glance.GlanceImageServiceV2._safe_fsync')
def test_download_direct_no_mod_fallback( def test_download_direct_no_mod_fallback(

View File

@ -0,0 +1,5 @@
---
upgrade:
- |
The ``nova.image.download`` entry point hook has been removed, per the deprecation
announcement in the 17.0.0 (Queens) release.