Remove deprecated nova.image.download hook
In Queens we deprecated the nova.image.download hook, which provided a mechanism to inject custom code into the download path of our glance module. This can now be removed. The one known potential user of this is was a direct-rbd download proposal, which needs further modification of the base glance client in order to work. Thus, this removes the hook point, but not the config option to allow specifying location schemes that should be considered direct by the glance module. This provides a path forward to integrate the direct-rbd code as a proper feature to our glance module, which will mean un-deprecating that config option, but also providing a stable list of potential options for it. Change-Id: I7463af2ba9b74a73ffbb0a6b5fa12dff3fa5cac6
This commit is contained in:
parent
6bc1352744
commit
2fbe8e02d5
@ -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
|
@ -43,7 +43,6 @@ import six.moves.urllib.parse as urlparse
|
||||
|
||||
import nova.conf
|
||||
from nova import exception
|
||||
import nova.image.download as image_xfers
|
||||
from nova import objects
|
||||
from nova.objects import fields
|
||||
from nova import profiler
|
||||
@ -217,24 +216,10 @@ class GlanceImageServiceV2(object):
|
||||
|
||||
def __init__(self, client=None):
|
||||
self._client = client or GlanceClientWrapper()
|
||||
# NOTE(jbresnah) build the table of download handlers at the beginning
|
||||
# so that operators can catch errors at load time rather than whenever
|
||||
# a user attempts to use a module. Note this cannot be done in glance
|
||||
# space when this python module is loaded because the download module
|
||||
# may require configuration options to be parsed.
|
||||
# NOTE(danms): This used to be built from a list of external modules
|
||||
# that were loaded at runtime. Preserve this list for implementations
|
||||
# to be added here.
|
||||
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,
|
||||
show_deleted=True):
|
||||
@ -273,15 +258,12 @@ class GlanceImageServiceV2(object):
|
||||
|
||||
return image
|
||||
|
||||
def _get_transfer_module(self, scheme):
|
||||
def _get_transfer_method(self, scheme):
|
||||
"""Returns a transfer method for scheme, or None."""
|
||||
try:
|
||||
return self._download_handlers[scheme]
|
||||
except KeyError:
|
||||
return None
|
||||
except Exception:
|
||||
LOG.error("Failed to instantiate the download handler "
|
||||
"for %(scheme)s", {'scheme': scheme})
|
||||
return
|
||||
|
||||
def detail(self, context, **kwargs):
|
||||
"""Calls out to Glance for a list of detailed image information."""
|
||||
@ -323,10 +305,10 @@ class GlanceImageServiceV2(object):
|
||||
loc_url = entry['url']
|
||||
loc_meta = entry['metadata']
|
||||
o = urlparse.urlparse(loc_url)
|
||||
xfer_mod = self._get_transfer_module(o.scheme)
|
||||
if xfer_mod:
|
||||
xfer_method = self._get_transfer_method(o.scheme)
|
||||
if xfer_method:
|
||||
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)
|
||||
return
|
||||
except Exception:
|
||||
|
@ -686,7 +686,7 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
|
||||
with testtools.ExpectedException(exception.ImageUnacceptable):
|
||||
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')
|
||||
def test_download_direct_file_uri_v2(self, show_mock, get_tran_mock):
|
||||
self.flags(allowed_direct_url_schemes=['file'], group='glance')
|
||||
@ -712,11 +712,11 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
|
||||
mock.sentinel.image_id,
|
||||
include_locations=True)
|
||||
get_tran_mock.assert_called_once_with('file')
|
||||
tran_mod.download.assert_called_once_with(ctx, mock.ANY,
|
||||
mock.sentinel.dst_path,
|
||||
mock.sentinel.loc_meta)
|
||||
tran_mod.assert_called_once_with(ctx, mock.ANY,
|
||||
mock.sentinel.dst_path,
|
||||
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._safe_fsync')
|
||||
def test_download_direct_exception_fallback_v2(
|
||||
@ -733,9 +733,9 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
|
||||
}
|
||||
]
|
||||
}
|
||||
tran_mod = mock.MagicMock()
|
||||
tran_mod.download.side_effect = Exception
|
||||
get_tran_mock.return_value = tran_mod
|
||||
tran_method = mock.MagicMock()
|
||||
tran_method.side_effect = Exception
|
||||
get_tran_mock.return_value = tran_method
|
||||
client = mock.MagicMock()
|
||||
client.call.return_value = fake_glance_response([1, 2, 3])
|
||||
ctx = mock.sentinel.ctx
|
||||
@ -752,9 +752,9 @@ class TestDownloadNoDirectUri(test.NoDBTestCase):
|
||||
mock.sentinel.image_id,
|
||||
include_locations=True)
|
||||
get_tran_mock.assert_called_once_with('file')
|
||||
tran_mod.download.assert_called_once_with(ctx, mock.ANY,
|
||||
mock.sentinel.dst_path,
|
||||
mock.sentinel.loc_meta)
|
||||
tran_method.assert_called_once_with(ctx, mock.ANY,
|
||||
mock.sentinel.dst_path,
|
||||
mock.sentinel.loc_meta)
|
||||
client.call.assert_called_once_with(
|
||||
ctx, 2, 'data', args=(mock.sentinel.image_id,))
|
||||
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._safe_fsync')
|
||||
def test_download_direct_no_mod_fallback(
|
||||
|
@ -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.
|
Loading…
x
Reference in New Issue
Block a user