Browse Source

Merge "Remove deprecated nova.image.download hook"

changes/12/726512/13
Zuul 2 weeks ago
committed by Gerrit Code Review
parent
commit
7f4d59a674
4 changed files with 25 additions and 92 deletions
  1. +0
    -54
      nova/image/download/__init__.py
  2. +8
    -26
      nova/image/glance.py
  3. +12
    -12
      nova/tests/unit/image/test_glance.py
  4. +5
    -0
      releasenotes/notes/remove-image-download-hook-27b39dca2497446a.yaml

+ 0
- 54
nova/image/download/__init__.py 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

+ 8
- 26
nova/image/glance.py View File

@@ -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:


+ 12
- 12
nova/tests/unit/image/test_glance.py View File

@@ -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(


+ 5
- 0
releasenotes/notes/remove-image-download-hook-27b39dca2497446a.yaml 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.

Loading…
Cancel
Save