conf: remove deprecated image url options

Change-Id: I7687cc89545a7a8b295dd6535b4ccebc913a2e0e
Implements: blueprint centralize-config-options-pike
This commit is contained in:
Maciej Szankin 2016-11-15 09:42:33 -06:00
parent fb693f07f0
commit ff8dcf6dcd
7 changed files with 10 additions and 366 deletions

View File

@ -41,7 +41,6 @@ from nova.conf import floating_ips
from nova.conf import glance
from nova.conf import guestfs
from nova.conf import hyperv
from nova.conf import image_file_url
from nova.conf import ipv6
from nova.conf import ironic
from nova.conf import key_manager
@ -99,7 +98,6 @@ glance.register_opts(CONF)
guestfs.register_opts(CONF)
hyperv.register_opts(CONF)
mks.register_opts(CONF)
image_file_url.register_opts(CONF)
ipv6.register_opts(CONF)
ironic.register_opts(CONF)
key_manager.register_opts(CONF)

View File

@ -1,84 +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_config import cfg
image_file_url_group = cfg.OptGroup(
'image_file_url',
title='Image File URL Options')
filesystems = cfg.ListOpt(
name='filesystems',
default=[],
deprecated_for_removal=True,
deprecated_since="14.0.0",
deprecated_reason="""
The feature to download images from glance via filesystem is not used and will
be removed in the future.
""",
help="""
List of file systems that are configured in this file in the
image_file_url:<list entry name> sections
""")
# NOTE(jbresnah) because the group under which these options are added is
# dynamically determined these options need to stay out of global space
# or they will confuse generate_sample.sh
filesystem_opts = [
cfg.StrOpt('id',
deprecated_for_removal=True,
deprecated_since="14.0.0",
deprecated_reason="""
The feature to download images from glance via filesystem is not used and will
be removed in the future.
""",
help="""
A unique ID given to each file system. This is value is set in Glance and
agreed upon here so that the operator knowns they are dealing with the same
file system.
"""),
cfg.StrOpt('mountpoint',
deprecated_for_removal=True,
deprecated_since="14.0.0",
deprecated_reason="""
The feature to download images from glance via filesystem is not used and will
be removed in the future.
""",
help="""
The path at which the file system is mounted.
"""),
]
ALL_OPTS = [filesystems]
def register_opts(conf):
conf.register_group(image_file_url_group)
conf.register_opts(ALL_OPTS, group=image_file_url_group)
for fs in conf.image_file_url.filesystems:
group_name = 'image_file_url:' + fs
conf.register_opts(filesystem_opts, group=group_name)
def list_opts():
# NOTE(markus_z): As the "filesystem" opt has an empty list as a default
# value and this value is necessary for a correct group name, we cannot
# list the "filesystem_opts" for the "nova.conf.sample" file here. A
# follow up patch will deprecate those. Due to their dynamic creation
# they never got shown in "nova.conf.sample" nor the config reference
# manual. I see no need to change this here with a dummy group or something
# like that.
return {image_file_url_group: ALL_OPTS}

View File

@ -1,23 +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 nova import exception
class TransferBase(object):
def download(self, context, url_parts, dst_path, metadata, **kwargs):
raise exception.ImageDownloadModuleNotImplementedError(
method_name='download')

View File

@ -1,145 +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 nova.conf
from nova import exception
from nova.i18n import _, _LI
import nova.image.download.base as xfer_base
import nova.virt.libvirt.utils as lv_utils
CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
# This module extends the configuration options for nova.conf. If the user
# wishes to use the specific configuration settings the following needs to
# be added to nova.conf:
# [image_file_url]
# filesystem = <a list of strings referencing a config section>
#
# For each entry in the filesystem list a new configuration section must be
# added with the following format:
# [image_file_url:<list entry>]
# id = <string>
# mountpoint = <string>
#
# id:
# An opaque string. In order for this module to know that the remote
# FS is the same one that is mounted locally it must share information
# with the glance deployment. Both glance and nova-compute must be
# configured with a unique matching string. This ensures that the
# file:// advertised URL is describing a file system that is known
# to nova-compute
# mountpoint:
# The location at which the file system is locally mounted. Glance
# may mount a shared file system on a different path than nova-compute.
# This value will be compared against the metadata advertised with
# glance and paths will be adjusted to ensure that the correct file
# file is copied.
#
# If these values are not added to nova.conf and the file module is in the
# allowed_direct_url_schemes list, then the legacy behavior will occur such
# that a copy will be attempted assuming that the glance and nova file systems
# are the same.
class FileTransfer(xfer_base.TransferBase):
desc_required_keys = ['id', 'mountpoint']
def _get_options(self):
fs_dict = {}
for fs in CONF.image_file_url.filesystems:
group_name = 'image_file_url:' + fs
conf_group = CONF[group_name]
if conf_group.id is None:
msg = _('The group %(group_name)s must be configured with '
'an id.') % {'group_name': group_name}
raise exception.ImageDownloadModuleConfigurationError(
module=str(self), reason=msg)
fs_dict[CONF[group_name].id] = CONF[group_name]
return fs_dict
def _verify_config(self):
for fs_key in self.filesystems:
for r in self.desc_required_keys:
fs_ent = self.filesystems[fs_key]
if fs_ent[r] is None:
msg = _('The key %s is required in all file system '
'descriptions.')
LOG.error(msg)
raise exception.ImageDownloadModuleConfigurationError(
module=str(self), reason=msg)
def _file_system_lookup(self, metadata, url_parts):
for r in self.desc_required_keys:
if r not in metadata:
url = url_parts.geturl()
msg = _('The key %(r)s is required in the location metadata '
'to access the url %(url)s.') % {'r': r, 'url': url}
LOG.info(msg)
raise exception.ImageDownloadModuleMetaDataError(
module=str(self), reason=msg)
id = metadata['id']
if id not in self.filesystems:
LOG.info(_LI('The ID %(id)s is unknown.'), {'id': id})
return
fs_descriptor = self.filesystems[id]
return fs_descriptor
def _normalize_destination(self, nova_mount, glance_mount, path):
if not path.startswith(glance_mount):
msg = (_('The mount point advertised by glance: %(glance_mount)s, '
'does not match the URL path: %(path)s') %
{'glance_mount': glance_mount, 'path': path})
raise exception.ImageDownloadModuleMetaDataError(
module=str(self), reason=msg)
new_path = path.replace(glance_mount, nova_mount, 1)
return new_path
def download(self, context, url_parts, dst_file, metadata, **kwargs):
self.filesystems = self._get_options()
if not self.filesystems:
# NOTE(jbresnah) when nothing is configured assume legacy behavior
nova_mountpoint = '/'
glance_mountpoint = '/'
else:
self._verify_config()
fs_descriptor = self._file_system_lookup(metadata, url_parts)
if fs_descriptor is None:
msg = (_('No matching ID for the URL %s was found.') %
url_parts.geturl())
raise exception.ImageDownloadModuleError(reason=msg,
module=str(self))
nova_mountpoint = fs_descriptor['mountpoint']
glance_mountpoint = metadata['mountpoint']
source_file = self._normalize_destination(nova_mountpoint,
glance_mountpoint,
url_parts.path)
lv_utils.copy_image(source_file, dst_file)
LOG.info(_LI('Copied %(source_file)s using %(module_str)s'),
{'source_file': source_file, 'module_str': str(self)})
def get_download_handler(**kwargs):
return FileTransfer()
def get_schemes():
return ['file', 'filesystem']

View File

@ -1,110 +0,0 @@
# 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 mock
import six.moves.urllib.parse as urlparse
import nova.conf
from nova import exception
from nova.image.download import file as tm_file
from nova import test
CONF = nova.conf.CONF
class TestFileTransferModule(test.NoDBTestCase):
@mock.patch('nova.virt.libvirt.utils.copy_image')
def test_filesystem_success(self, copy_mock):
self.flags(allowed_direct_url_schemes=['file'], group='glance')
self.flags(group='image_file_url', filesystems=['gluster'])
# register opts for dynamically created group 'image_file_url:gluster'
nova.conf.image_file_url.register_opts(CONF)
mountpoint = '/gluster'
url = 'file:///gluster/my/image/path'
url_parts = urlparse.urlparse(url)
fs_id = 'someid'
loc_meta = {
'id': fs_id,
'mountpoint': mountpoint
}
dst_file = mock.MagicMock()
tm = tm_file.FileTransfer()
# NOTE(Jbresnah) The following options must be added after the module
# has added the specific groups.
self.flags(group='image_file_url:gluster', id=fs_id)
self.flags(group='image_file_url:gluster', mountpoint=mountpoint)
tm.download(mock.sentinel.ctx, url_parts, dst_file, loc_meta)
copy_mock.assert_called_once_with('/gluster/my/image/path', dst_file)
@mock.patch('nova.virt.libvirt.utils.copy_image')
def test_filesystem_mismatched_mountpoint(self, copy_mock):
self.flags(allowed_direct_url_schemes=['file'], group='glance')
self.flags(group='image_file_url', filesystems=['gluster'])
# register opts for dynamically created group 'image_file_url:gluster'
nova.conf.image_file_url.register_opts(CONF)
mountpoint = '/gluster'
# Should include the mountpoint before my/image/path
url = 'file:///my/image/path'
url_parts = urlparse.urlparse(url)
fs_id = 'someid'
loc_meta = {
'id': fs_id,
'mountpoint': mountpoint
}
dst_file = mock.MagicMock()
tm = tm_file.FileTransfer()
self.flags(group='image_file_url:gluster', id=fs_id)
self.flags(group='image_file_url:gluster', mountpoint=mountpoint)
self.assertRaises(exception.ImageDownloadModuleMetaDataError,
tm.download, mock.sentinel.ctx, url_parts,
dst_file, loc_meta)
self.assertFalse(copy_mock.called)
@mock.patch('nova.virt.libvirt.utils.copy_image')
def test_filesystem_mismatched_filesystem(self, copy_mock):
self.flags(allowed_direct_url_schemes=['file'], group='glance')
self.flags(group='image_file_url', filesystems=['gluster'])
# register opts for dynamically created group 'image_file_url:gluster'
nova.conf.image_file_url.register_opts(CONF)
mountpoint = '/gluster'
# Should include the mountpoint before my/image/path
url = 'file:///my/image/path'
url_parts = urlparse.urlparse(url)
fs_id = 'someid'
loc_meta = {
'id': 'funky',
'mountpoint': mountpoint
}
dst_file = mock.MagicMock()
tm = tm_file.FileTransfer()
self.flags(group='image_file_url:gluster', id=fs_id)
self.flags(group='image_file_url:gluster', mountpoint=mountpoint)
self.assertRaises(exception.ImageDownloadModuleError,
tm.download, mock.sentinel.ctx, url_parts,
dst_file, loc_meta)
self.assertFalse(copy_mock.called)

View File

@ -0,0 +1,10 @@
---
upgrade:
- |
Configuration options related to image file have been removed. They were
marked as deprecated because the feature to download images from glance
via filesystem is not used. Below are the removed options:
- ``image_file_url.filesystems``
- ``image_file_url.FS.id``
- ``image_file_url.FS.mountpoint``

View File

@ -44,8 +44,6 @@ oslo.policy.policies =
nova.compute.monitors.cpu =
virt_driver = nova.compute.monitors.cpu.virt_driver:Monitor
nova.image.download.modules =
file = nova.image.download.file
console_scripts =
nova-all = nova.cmd.all:main
nova-api = nova.cmd.api:main