diff --git a/etc/nova/rootwrap.d/compute.filters b/etc/nova/rootwrap.d/compute.filters index a6bc32c10fb..86a23f0a4eb 100644 --- a/etc/nova/rootwrap.d/compute.filters +++ b/etc/nova/rootwrap.d/compute.filters @@ -14,7 +14,6 @@ tune2fs: CommandFilter, tune2fs, root # nova/virt/disk/api.py: 'mount', '-o', 'bind', src, target # nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'.. # nova/virt/configdrive.py: 'mount', device, mountdir -# nova/virt/libvirt/volume.py: 'mount', '-t', 'sofs' ... mount: CommandFilter, mount, root # nova/virt/disk/mount/api.py: 'umount', mapped_device diff --git a/nova/conf/libvirt.py b/nova/conf/libvirt.py index f3f1f136490..63725ddce52 100644 --- a/nova/conf/libvirt.py +++ b/nova/conf/libvirt.py @@ -908,31 +908,6 @@ help='Path to a Quobyte Client configuration file.'), ] -libvirt_volume_scality_opts = [ - cfg.StrOpt('scality_sofs_config', - help=""" -Path or URL to Scality SOFS(Scale-Out File Server) configuration file. - -The Scality SOFS provides OpenStack users the option of storing their -data on a high capacity, replicated, highly available Scality Ring object -storage cluster. -"""), - cfg.StrOpt('scality_sofs_mount_point', - default='$state_path/scality', - help=""" -Base dir where Scality SOFS shall be mounted. - -The Scality volume driver in Nova mounts SOFS and lets the hypervisor access -the volumes. - -Possible values: - -* $state_path/scality where state_path is a config option that specifies - the top-level directory for maintaining nova's state or Any string - containing the full directory path. -"""), -] - libvirt_volume_smbfs_opts = [ cfg.StrOpt('smbfs_mount_point_base', default=paths.state_path_def('mnt'), @@ -1092,7 +1067,6 @@ libvirt_volume_net_opts, libvirt_volume_nfs_opts, libvirt_volume_quobyte_opts, - libvirt_volume_scality_opts, libvirt_volume_smbfs_opts, libvirt_remotefs_opts, libvirt_volume_vzstorage_opts, diff --git a/nova/tests/unit/virt/libvirt/volume/test_scality.py b/nova/tests/unit/virt/libvirt/volume/test_scality.py deleted file mode 100644 index b08ebbe18ea..00000000000 --- a/nova/tests/unit/virt/libvirt/volume/test_scality.py +++ /dev/null @@ -1,115 +0,0 @@ -# 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 mock - -import nova.exception -from nova.tests.unit.virt.libvirt.volume import test_volume -from nova.virt.libvirt.volume import scality - - -class LibvirtScalityVolumeDriverTestCase( - test_volume.LibvirtVolumeBaseTestCase): - - def setUp(self): - super(LibvirtScalityVolumeDriverTestCase, self).setUp() - - self.scality_sofs_config = 'fake.conf' - self.scality_sofs_mount_point = '/fake' - self.flags(scality_sofs_config=self.scality_sofs_config, - scality_sofs_mount_point=self.scality_sofs_mount_point, - group='libvirt') - - self.drv = scality.LibvirtScalityVolumeDriver(self.fake_host) - - @mock.patch('six.moves.urllib.request.urlopen') - def test_connect_volume(self, mock_urlopen): - TEST_VOLDIR = 'volumes' - TEST_VOLNAME = 'volume_name' - TEST_CONN_INFO = { - 'data': { - 'sofs_path': os.path.join(TEST_VOLDIR, TEST_VOLNAME) - } - } - TEST_VOLPATH = os.path.join(self.scality_sofs_mount_point, - TEST_VOLDIR, - TEST_VOLNAME) - - def _access_wrapper(path, flags): - if path == '/sbin/mount.sofs': - return True - else: - return os.access(path, flags) - - self.stub_out('os.access', _access_wrapper) - - with mock.patch.object(self.drv, '_mount_sofs'): - self.drv.connect_volume(TEST_CONN_INFO, self.disk_info, - mock.sentinel.instance) - - device_path = os.path.join(self.scality_sofs_mount_point, - TEST_CONN_INFO['data']['sofs_path']) - self.assertEqual(TEST_CONN_INFO['data']['device_path'], device_path) - - conf = self.drv.get_config(TEST_CONN_INFO, self.disk_info) - tree = conf.format_dom() - self._assertFileTypeEquals(tree, TEST_VOLPATH) - - @mock.patch('nova.utils.execute') - def test_mount_sofs_when_sofs_already_mounted(self, mock_execute): - with mock.patch.object(self.drv, '_sofs_is_mounted') as m_is_mounted: - m_is_mounted.return_value = True - - self.drv._mount_sofs() - - mock_execute.assert_called_once_with('mkdir', '-p', - self.scality_sofs_mount_point) - self.assertEqual(1, m_is_mounted.call_count) - - @mock.patch('nova.utils.execute', mock.Mock()) - def test_mount_sofs_when_mount_fails(self): - with mock.patch.object(self.drv, '_sofs_is_mounted') as m_is_mounted: - m_is_mounted.side_effect = [False, False] - - self.assertRaises(nova.exception.NovaException, - self.drv._mount_sofs) - - self.assertEqual(2, m_is_mounted.call_count) - - @mock.patch('nova.utils.execute') - def test_mount_sofs_when_sofs_is_not_mounted(self, mock_execute): - with mock.patch.object(self.drv, '_sofs_is_mounted') as m_is_mounted: - m_is_mounted.side_effect = [False, True] - - self.drv._mount_sofs() - - self.assertEqual(2, m_is_mounted.call_count) - self.assertEqual(2, mock_execute.call_count) - expected_calls = [ - mock.call('mkdir', '-p', self.scality_sofs_mount_point), - mock.call('mount', '-t', 'sofs', self.scality_sofs_config, - self.scality_sofs_mount_point, run_as_root=True) - ] - mock_execute.assert_has_calls(expected_calls) - - def test_sofs_is_mounted_when_sofs_is_not_mounted(self): - mock_open = mock.mock_open(read_data='tmpfs /dev/shm\n') - with mock.patch('io.open', mock_open) as mock_open: - self.assertFalse(self.drv._sofs_is_mounted()) - - def test_sofs_is_mounted_when_sofs_is_mounted(self): - proc_mount = '/dev/fuse ' + self.scality_sofs_mount_point + '\n' - mock_open = mock.mock_open(read_data=proc_mount) - with mock.patch('io.open', mock_open) as mock_open: - self.assertTrue(self.drv._sofs_is_mounted()) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 67b4bf5f76a..895f313e8f5 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -161,7 +161,6 @@ 'fibre_channel=' 'nova.virt.libvirt.volume.fibrechannel.' 'LibvirtFibreChannelVolumeDriver', - 'scality=nova.virt.libvirt.volume.scality.LibvirtScalityVolumeDriver', 'gpfs=nova.virt.libvirt.volume.gpfs.LibvirtGPFSVolumeDriver', 'quobyte=nova.virt.libvirt.volume.quobyte.LibvirtQuobyteVolumeDriver', 'hgst=nova.virt.libvirt.volume.hgst.LibvirtHGSTVolumeDriver', diff --git a/nova/virt/libvirt/volume/scality.py b/nova/virt/libvirt/volume/scality.py deleted file mode 100644 index 44e8bbc1e77..00000000000 --- a/nova/virt/libvirt/volume/scality.py +++ /dev/null @@ -1,136 +0,0 @@ -# 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 io -import os - -from oslo_log import log as logging -from six.moves import urllib -import six.moves.urllib.parse as urlparse - -import nova.conf -from nova import exception -from nova.i18n import _ -from nova import utils -from nova.virt.libvirt.volume import fs - -LOG = logging.getLogger(__name__) - -CONF = nova.conf.CONF - - -class LibvirtScalityVolumeDriver(fs.LibvirtBaseFileSystemVolumeDriver): - """Scality SOFS Nova driver. Provide hypervisors with access - to sparse files on SOFS. - """ - - def _get_mount_point_base(self): - return CONF.libvirt.scality_sofs_mount_point - - def _get_device_path(self, connection_info): - """Returns the hashed path to the device. - - :param connection_info: dict of the form - - :: - - connection_info = { - 'data': { - 'sofs_path': the file system share - ... - } - ... - } - - :returns: The full path to the device. - """ - # TODO(mriedem): change the scality volume driver in cinder to set - # the export and name keys rather than the sofs_path so this is - # standardized. - path = os.path.join(CONF.libvirt.scality_sofs_mount_point, - connection_info['data']['sofs_path']) - return path - - def get_config(self, connection_info, disk_info): - """Returns xml for libvirt.""" - conf = super(LibvirtScalityVolumeDriver, - self).get_config(connection_info, disk_info) - conf.source_type = 'file' - conf.source_path = connection_info['data']['device_path'] - - # The default driver cache policy is 'none', and this causes - # qemu/kvm to open the volume file with O_DIRECT, which is - # rejected by FUSE (on kernels older than 3.3). Scality SOFS - # is FUSE based, so we must provide a more sensible default. - conf.driver_cache = 'writethrough' - - return conf - - def connect_volume(self, connection_info, disk_info, instance): - """Connect the volume.""" - self._check_prerequisites() - self._mount_sofs() - - connection_info['data']['device_path'] = \ - self._get_device_path(connection_info) - - def _check_prerequisites(self): - """Sanity checks before attempting to mount SOFS.""" - - # config is mandatory - config = CONF.libvirt.scality_sofs_config - if not config: - msg = _("Value required for 'scality_sofs_config'") - LOG.warning(msg) - raise exception.InternalError(msg) - - # config can be a file path or a URL, check it - if urlparse.urlparse(config).scheme == '': - # turn local path into URL - config = 'file://%s' % config - try: - urllib.request.urlopen(config, timeout=5).close() - except urllib.error.URLError as e: - msg = _("Cannot access 'scality_sofs_config': %s") % e - LOG.warning(msg) - raise exception.InternalError(msg) - - # mount.sofs must be installed - if not os.access('/sbin/mount.sofs', os.X_OK): - msg = _("Cannot execute /sbin/mount.sofs") - LOG.warning(msg) - raise exception.InternalError(msg) - - def _sofs_is_mounted(self): - """Detects whether Scality SOFS is already mounted.""" - mount_path = CONF.libvirt.scality_sofs_mount_point.rstrip('/') - with io.open('/proc/mounts') as mounts: - for mount in mounts.readlines(): - parts = mount.split() - if (parts[0].endswith('fuse') and - parts[1].rstrip('/') == mount_path): - return True - return False - - def _mount_sofs(self): - config = CONF.libvirt.scality_sofs_config - mount_path = CONF.libvirt.scality_sofs_mount_point - - if not os.path.isdir(mount_path): - utils.execute('mkdir', '-p', mount_path) - if not self._sofs_is_mounted(): - utils.execute('mount', '-t', 'sofs', config, mount_path, - run_as_root=True) - if not self._sofs_is_mounted(): - msg = _("Cannot mount Scality SOFS, check syslog for errors") - LOG.warning(msg) - raise exception.InternalError(msg) diff --git a/releasenotes/notes/remove-scality-volume-driver-21ff4832d0d3f28e.yaml b/releasenotes/notes/remove-scality-volume-driver-21ff4832d0d3f28e.yaml new file mode 100644 index 00000000000..1527f28f4fe --- /dev/null +++ b/releasenotes/notes/remove-scality-volume-driver-21ff4832d0d3f28e.yaml @@ -0,0 +1,16 @@ +--- +upgrade: + - | + The ``nova.virt.libvirt.volume.scality.LibvirtScalityVolumeDriver`` volume + driver has been removed. The Scality volume driver in Cinder was deprecated + during the Newton release and was removed from Cinder in the Ocata release + so it is effectively not maintained and therefore no longer supported. + - | + The following configuration options, previously found in the ``libvirt`` + group, have been removed: + + - ``scality_sofs_config`` + - ``scality_sofs_mount_point`` + + These were used by the now-removed ``LibvirtScalityVolumeDriver`` volume + driver and therefore no longer had any effect.