From bd5e484371af24f43d86b224caabb1f34561e46d Mon Sep 17 00:00:00 2001 From: Sean McGinnis Date: Thu, 19 Dec 2019 07:34:57 -0600 Subject: [PATCH] Remove Sheepdog connector The Sheepdog project is no longer active and the driver has been removed from Cinder. This cleans up os-brick related code for the driver. Change-Id: I9684db3ab134aeccce9f2ca47c29cdccaa8c5697 Signed-off-by: Sean McGinnis --- os_brick/initiator/__init__.py | 1 - os_brick/initiator/connector.py | 4 - os_brick/initiator/connectors/sheepdog.py | 127 ------------------ os_brick/initiator/linuxsheepdog.py | 114 ---------------- .../initiator/connectors/test_sheepdog.py | 87 ------------ .../tests/initiator/test_linuxsheepdog.py | 121 ----------------- .../remove-sheepdog-611257b28bc88934.yaml | 6 + 7 files changed, 6 insertions(+), 454 deletions(-) delete mode 100644 os_brick/initiator/connectors/sheepdog.py delete mode 100644 os_brick/initiator/linuxsheepdog.py delete mode 100644 os_brick/tests/initiator/connectors/test_sheepdog.py delete mode 100644 os_brick/tests/initiator/test_linuxsheepdog.py create mode 100644 releasenotes/notes/remove-sheepdog-611257b28bc88934.yaml diff --git a/os_brick/initiator/__init__.py b/os_brick/initiator/__init__.py index 019219220..bb8386542 100644 --- a/os_brick/initiator/__init__.py +++ b/os_brick/initiator/__init__.py @@ -57,7 +57,6 @@ SCALITY = "SCALITY" QUOBYTE = "QUOBYTE" DISCO = "DISCO" VZSTORAGE = "VZSTORAGE" -SHEEPDOG = "SHEEPDOG" VMDK = "VMDK" GPFS = "GPFS" VERITAS_HYPERSCALE = "VERITAS_HYPERSCALE" diff --git a/os_brick/initiator/connector.py b/os_brick/initiator/connector.py index 963ee6a65..5315a54e8 100644 --- a/os_brick/initiator/connector.py +++ b/os_brick/initiator/connector.py @@ -115,8 +115,6 @@ _connector_mapping_linux = { 'os_brick.initiator.connectors.scaleio.ScaleIOConnector', initiator.DISCO: 'os_brick.initiator.connectors.disco.DISCOConnector', - initiator.SHEEPDOG: - 'os_brick.initiator.connectors.sheepdog.SheepdogConnector', initiator.VMDK: 'os_brick.initiator.connectors.vmware.VmdkConnector', initiator.GPFS: @@ -175,8 +173,6 @@ _connector_mapping_linux_ppc64 = { 'os_brick.initiator.connectors.vrtshyperscale.HyperScaleConnector', initiator.ISER: 'os_brick.initiator.connectors.iscsi.ISCSIConnector', - initiator.SHEEPDOG: - 'os_brick.initiator.connectors.sheepdog.SheepdogConnector', } # Mapping for the windows connectors diff --git a/os_brick/initiator/connectors/sheepdog.py b/os_brick/initiator/connectors/sheepdog.py deleted file mode 100644 index c224b011c..000000000 --- a/os_brick/initiator/connectors/sheepdog.py +++ /dev/null @@ -1,127 +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. - -from oslo_log import log as logging - -from os_brick import exception -from os_brick.i18n import _ -from os_brick import initiator -from os_brick.initiator.connectors import base -from os_brick.initiator import linuxsheepdog -from os_brick import utils - -DEVICE_SCAN_ATTEMPTS_DEFAULT = 3 -LOG = logging.getLogger(__name__) - - -class SheepdogConnector(base.BaseLinuxConnector): - """"Connector class to attach/detach sheepdog volumes.""" - - def __init__(self, root_helper, driver=None, use_multipath=False, - device_scan_attempts=initiator.DEVICE_SCAN_ATTEMPTS_DEFAULT, - *args, **kwargs): - - super(SheepdogConnector, self).__init__(root_helper, driver=driver, - device_scan_attempts= - device_scan_attempts, - *args, **kwargs) - - @staticmethod - def get_connector_properties(root_helper, *args, **kwargs): - """The Sheepdog connector properties.""" - return {} - - def get_volume_paths(self, connection_properties): - # TODO(lixiaoy1): don't know where the connector - # looks for sheepdog volumes. - return [] - - def get_search_path(self): - # TODO(lixiaoy1): don't know where the connector - # looks for sheepdog volumes. - return None - - def get_all_available_volumes(self, connection_properties=None): - # TODO(lixiaoy1): not sure what to return here for sheepdog - return [] - - def _get_sheepdog_handle(self, connection_properties): - try: - host = connection_properties['hosts'][0] - name = connection_properties['name'] - port = connection_properties['ports'][0] - except IndexError: - msg = _("Connect volume failed, malformed connection properties") - raise exception.BrickException(msg=msg) - - sheepdog_handle = linuxsheepdog.SheepdogVolumeIOWrapper( - host, port, name) - return sheepdog_handle - - @utils.trace - def connect_volume(self, connection_properties): - """Connect to a volume. - - :param connection_properties: The dictionary that describes all - of the target volume attributes. - :type connection_properties: dict - :returns: dict - """ - - sheepdog_handle = self._get_sheepdog_handle(connection_properties) - return {'path': sheepdog_handle} - - @utils.trace - def disconnect_volume(self, connection_properties, device_info, - force=False, ignore_errors=False): - """Disconnect a volume. - - :param connection_properties: The dictionary that describes all - of the target volume attributes. - :type connection_properties: dict - :param device_info: historical difference, but same as connection_props - :type device_info: dict - """ - if device_info: - sheepdog_handle = device_info.get('path', None) - self.check_IO_handle_valid(sheepdog_handle, - linuxsheepdog.SheepdogVolumeIOWrapper, - 'Sheepdog') - if sheepdog_handle is not None: - sheepdog_handle.close() - - def check_valid_device(self, path, run_as_root=True): - """Verify an existing sheepdog handle is connected and valid.""" - sheepdog_handle = path - - if sheepdog_handle is None: - return False - - original_offset = sheepdog_handle.tell() - - try: - sheepdog_handle.read(4096) - except Exception as e: - LOG.error("Failed to access sheepdog device " - "handle: %(error)s", - {"error": e}) - return False - finally: - sheepdog_handle.seek(original_offset, 0) - - return True - - def extend_volume(self, connection_properties): - # TODO(lixiaoy1): is this possible? - raise NotImplementedError diff --git a/os_brick/initiator/linuxsheepdog.py b/os_brick/initiator/linuxsheepdog.py deleted file mode 100644 index 542f04d62..000000000 --- a/os_brick/initiator/linuxsheepdog.py +++ /dev/null @@ -1,114 +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. - -""" -Generic SheepDog Connection Utilities. - -""" -import eventlet -import io -from oslo_concurrency import processutils - -from os_brick import exception -from os_brick.i18n import _ - - -class SheepdogVolumeIOWrapper(io.RawIOBase): - """File-like object with Sheepdog backend.""" - - def __init__(self, addr, port, volume, snapshot_name=None): - self._addr = addr - self._port = port - self._vdiname = volume - self._snapshot_name = snapshot_name - self._offset = 0 - # SheepdogVolumeIOWrapper instance becomes invalid - # if a write error occurs. - self._valid = True - - def _execute(self, cmd, data=None): - try: - # NOTE(yamada-h): processutils.execute causes busy waiting - # under eventlet. - # To avoid wasting CPU resources, it should not be used for - # the command which takes long time to execute. - # For workaround, we replace a subprocess module with - # the original one while only executing a read/write command. - _processutils_subprocess = processutils.subprocess - processutils.subprocess = eventlet.patcher.original('subprocess') - return processutils.execute(*cmd, process_input=data)[0] - except (processutils.ProcessExecutionError, OSError): - self._valid = False - raise exception.VolumeDriverException(name=self._vdiname) - finally: - processutils.subprocess = _processutils_subprocess - - def read(self, length=None): - if not self._valid: - raise exception.VolumeDriverException(name=self._vdiname) - - cmd = ['dog', 'vdi', 'read', '-a', self._addr, '-p', self._port] - if self._snapshot_name: - cmd.extend(('-s', self._snapshot_name)) - cmd.extend((self._vdiname, self._offset)) - if length: - cmd.append(length) - data = self._execute(cmd) - self._offset += len(data) - return data - - def write(self, data): - if not self._valid: - raise exception.VolumeDriverException(name=self._vdiname) - - length = len(data) - cmd = ('dog', 'vdi', 'write', '-a', self._addr, '-p', self._port, - self._vdiname, self._offset, length) - self._execute(cmd, data) - self._offset += length - return length - - def seek(self, offset, whence=0): - if not self._valid: - raise exception.VolumeDriverException(name=self._vdiname) - - if whence == 0: - # SEEK_SET or 0 - start of the stream (the default); - # offset should be zero or positive - new_offset = offset - elif whence == 1: - # SEEK_CUR or 1 - current stream position; offset may be negative - new_offset = self._offset + offset - else: - # SEEK_END or 2 - end of the stream; offset is usually negative - # TODO(yamada-h): Support SEEK_END - raise IOError(_("Invalid argument - whence=%s not supported.") % - whence) - - if new_offset < 0: - raise IOError(_("Invalid argument - negative seek offset.")) - - self._offset = new_offset - - def tell(self): - return self._offset - - def flush(self): - pass - - def fileno(self): - """Sheepdog does not have support for fileno so we raise IOError. - - Raising IOError is recommended way to notify caller that interface is - not supported - see http://docs.python.org/2/library/io.html#io.IOBase - """ - raise IOError(_("fileno is not supported by SheepdogVolumeIOWrapper")) diff --git a/os_brick/tests/initiator/connectors/test_sheepdog.py b/os_brick/tests/initiator/connectors/test_sheepdog.py deleted file mode 100644 index e2a359ec1..000000000 --- a/os_brick/tests/initiator/connectors/test_sheepdog.py +++ /dev/null @@ -1,87 +0,0 @@ -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# -# 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 - -from os_brick import exception -from os_brick.initiator.connectors import sheepdog -from os_brick.initiator import linuxsheepdog -from os_brick.tests.initiator import test_connector - - -class SheepdogConnectorTestCase(test_connector.ConnectorTestCase): - - def setUp(self): - super(SheepdogConnectorTestCase, self).setUp() - - self.hosts = ['fake_hosts'] - self.ports = ['fake_ports'] - self.volume = 'fake_volume' - - self.connection_properties = { - 'hosts': self.hosts, - 'name': self.volume, - 'ports': self.ports, - } - - def test_get_connector_properties(self): - props = sheepdog.SheepdogConnector.get_connector_properties( - 'sudo', multipath=True, enforce_multipath=True) - - expected_props = {} - self.assertEqual(expected_props, props) - - def test_get_search_path(self): - sd_connector = sheepdog.SheepdogConnector(None) - path = sd_connector.get_search_path() - self.assertIsNone(path) - - def test_get_volume_paths(self): - sd_connector = sheepdog.SheepdogConnector(None) - expected = [] - actual = sd_connector.get_volume_paths(self.connection_properties) - self.assertEqual(expected, actual) - - def test_connect_volume(self): - """Test the connect volume case.""" - sd_connector = sheepdog.SheepdogConnector(None) - device_info = sd_connector.connect_volume(self.connection_properties) - - # Ensure expected object is returned correctly - self.assertIsInstance(device_info['path'], - linuxsheepdog.SheepdogVolumeIOWrapper) - - @mock.patch.object(linuxsheepdog.SheepdogVolumeIOWrapper, 'close') - def test_disconnect_volume(self, volume_close): - """Test the disconnect volume case.""" - sd_connector = sheepdog.SheepdogConnector(None) - device_info = sd_connector.connect_volume(self.connection_properties) - sd_connector.disconnect_volume(self.connection_properties, device_info) - - self.assertEqual(1, volume_close.call_count) - - def test_disconnect_volume_with_invalid_handle(self): - """Test the disconnect volume case with invalid handle.""" - sd_connector = sheepdog.SheepdogConnector(None) - device_info = {'path': 'fake_handle'} - self.assertRaises(exception.InvalidIOHandleObject, - sd_connector.disconnect_volume, - self.connection_properties, - device_info) - - def test_extend_volume(self): - sd_connector = sheepdog.SheepdogConnector(None) - self.assertRaises(NotImplementedError, - sd_connector.extend_volume, - self.connection_properties) diff --git a/os_brick/tests/initiator/test_linuxsheepdog.py b/os_brick/tests/initiator/test_linuxsheepdog.py deleted file mode 100644 index 64fcdd2a0..000000000 --- a/os_brick/tests/initiator/test_linuxsheepdog.py +++ /dev/null @@ -1,121 +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 mock -from os_brick import exception -from os_brick.initiator import linuxsheepdog -from os_brick.tests import base -from oslo_concurrency import processutils - -SHEEP_ADDR = '127.0.0.1' -SHEEP_PORT = 7000 - - -class SheepdogVolumeIOWrapperTestCase(base.TestCase): - def setUp(self): - super(SheepdogVolumeIOWrapperTestCase, self).setUp() - self.volume = 'volume-2f9b2ff5-987b-4412-a91c-23caaf0d5aff' - self.snapshot_name = 'snapshot-bf452d80-068a-43d7-ba9f-196cf47bd0be' - - self.vdi_wrapper = linuxsheepdog.SheepdogVolumeIOWrapper( - SHEEP_ADDR, SHEEP_PORT, self.volume) - self.snapshot_wrapper = linuxsheepdog.SheepdogVolumeIOWrapper( - SHEEP_ADDR, SHEEP_PORT, self.volume, self.snapshot_name) - - self.execute = mock.MagicMock() - self.mock_object(processutils, 'execute', self.execute) - - def test_init(self): - self.assertEqual(self.volume, self.vdi_wrapper._vdiname) - self.assertIsNone(self.vdi_wrapper._snapshot_name) - self.assertEqual(0, self.vdi_wrapper._offset) - - self.assertEqual(self.snapshot_name, - self.snapshot_wrapper._snapshot_name) - - def test_execute(self): - cmd = ('cmd1', 'arg1') - data = 'data1' - - self.vdi_wrapper._execute(cmd, data) - - self.execute.assert_called_once_with(*cmd, process_input=data) - - def test_execute_error(self): - cmd = ('cmd1', 'arg1') - data = 'data1' - self.mock_object(processutils, 'execute', - mock.MagicMock(side_effect=OSError)) - - args = (cmd, data) - self.assertRaises(exception.VolumeDriverException, - self.vdi_wrapper._execute, - *args) - - def test_read_vdi(self): - self.vdi_wrapper.read() - self.execute.assert_called_once_with( - 'dog', 'vdi', 'read', '-a', SHEEP_ADDR, '-p', SHEEP_PORT, - self.volume, 0, process_input=None) - - def test_read_vdi_invalid(self): - self.vdi_wrapper._valid = False - self.assertRaises(exception.VolumeDriverException, - self.vdi_wrapper.read) - - def test_write_vdi(self): - data = 'data1' - - self.vdi_wrapper.write(data) - - self.execute.assert_called_once_with( - 'dog', 'vdi', 'write', '-a', SHEEP_ADDR, '-p', SHEEP_PORT, - self.volume, 0, len(data), - process_input=data) - self.assertEqual(len(data), self.vdi_wrapper.tell()) - - def test_write_vdi_invalid(self): - self.vdi_wrapper._valid = False - self.assertRaises(exception.VolumeDriverException, - self.vdi_wrapper.write, 'dummy_data') - - def test_read_snapshot(self): - self.snapshot_wrapper.read() - self.execute.assert_called_once_with( - 'dog', 'vdi', 'read', '-a', SHEEP_ADDR, '-p', SHEEP_PORT, - '-s', self.snapshot_name, self.volume, 0, - process_input=None) - - def test_seek(self): - self.vdi_wrapper.seek(12345) - self.assertEqual(12345, self.vdi_wrapper.tell()) - - self.vdi_wrapper.seek(-2345, whence=1) - self.assertEqual(10000, self.vdi_wrapper.tell()) - - # This results in negative offset. - self.assertRaises(IOError, self.vdi_wrapper.seek, -20000, whence=1) - - def test_seek_invalid(self): - seek_num = 12345 - self.vdi_wrapper._valid = False - self.assertRaises(exception.VolumeDriverException, - self.vdi_wrapper.seek, seek_num) - - def test_flush(self): - # flush does nothing. - self.vdi_wrapper.flush() - self.assertFalse(self.execute.called) - - def test_fileno(self): - self.assertRaises(IOError, self.vdi_wrapper.fileno) diff --git a/releasenotes/notes/remove-sheepdog-611257b28bc88934.yaml b/releasenotes/notes/remove-sheepdog-611257b28bc88934.yaml new file mode 100644 index 000000000..9dc45d711 --- /dev/null +++ b/releasenotes/notes/remove-sheepdog-611257b28bc88934.yaml @@ -0,0 +1,6 @@ +--- +upgrade: + - | + The Sheepdog project is no longer active and its driver has been removed + from Cinder. The connector and Sheepdog related handling has now been + removed from os-brick as well.