diff --git a/lower-constraints.txt b/lower-constraints.txt index fc397161cb..41afef13c7 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -58,31 +58,31 @@ netifaces==0.10.4 networkx==2.1.0 numpy==1.19.0 openstacksdk==0.35.0 -os-brick==4.3.1 +os-brick==5.2 os-client-config==1.29.0 os-resource-classes==1.1.0 os-service-types==1.7.0 os-traits==2.7.0 os-vif==1.15.2 -os-win==5.4.0 +os-win==5.5.0 osc-lib==1.10.0 oslo.cache==1.26.0 -oslo.concurrency==4.4.0 +oslo.concurrency==4.5.0 oslo.config==8.6.0 -oslo.context==3.1.1 +oslo.context==3.4.0 oslo.db==10.0.0 -oslo.i18n==5.0.1 -oslo.log==4.4.0 +oslo.i18n==5.1.0 +oslo.log==4.6.1 oslo.messaging==10.3.0 oslo.middleware==3.31.0 oslo.policy==3.7.0 -oslo.privsep==2.4.0 +oslo.privsep==2.6.2 oslo.reports==1.18.0 oslo.rootwrap==5.8.0 -oslo.serialization==4.1.0 -oslo.service==2.5.0 +oslo.serialization==4.2.0 +oslo.service==2.8.0 oslo.upgradecheck==1.3.0 -oslo.utils==4.8.0 +oslo.utils==4.12.1 oslo.versionedobjects==1.35.0 oslo.vmware==3.6.0 oslotest==3.8.0 @@ -93,7 +93,7 @@ packaging==20.4 paramiko==2.7.1 Paste==2.0.2 PasteDeploy==1.5.0 -pbr==5.5.1 +pbr==5.8.0 pluggy==0.6.0 ply==3.11 prettytable==0.7.1 diff --git a/nova/tests/unit/virt/libvirt/volume/test_lightos.py b/nova/tests/unit/virt/libvirt/volume/test_lightos.py new file mode 100644 index 0000000000..0be0f5aefe --- /dev/null +++ b/nova/tests/unit/virt/libvirt/volume/test_lightos.py @@ -0,0 +1,81 @@ +# 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 nova.tests.unit.virt.libvirt.volume import test_volume +from nova.virt.libvirt.volume import lightos + +from os_brick import initiator + + +class LibvirtLightVolumeDriverTestCase(test_volume.LibvirtVolumeBaseTestCase): + + @mock.patch('queue.Queue', return_value='queue') + @mock.patch('nova.utils.get_root_helper') + @mock.patch('os_brick.initiator.connector.InitiatorConnector.factory') + def test_libvirt_lightos_driver(self, mock_factory, mock_helper, + queue): + self.flags(group='libvirt') + mock_helper.return_value = 'sudo' + lightos.LibvirtLightOSVolumeDriver(self.fake_host) + mock_factory.assert_called_once_with( + initiator.LIGHTOS, root_helper='sudo', + device_scan_attempts=5) + + @mock.patch('os_brick.initiator.connector.InitiatorConnector.factory', + new=mock.Mock(return_value=mock.Mock())) + def test_libvirt_lightos_driver_connect(self): + lightos_driver = lightos.LibvirtLightOSVolumeDriver( + self.fake_host) + config = {'server_ip': '127.0.0.1', 'server_port': 9898} + disk_info = { + 'id': '1234567', + 'name': 'aLightVolume', + 'conf': config} + connection_info = {'data': disk_info} + with mock.patch.object(lightos_driver.connector, + 'connect_volume', + return_value={'path': '/dev/dms1234567'}): + lightos_driver.connect_volume(connection_info, None) + (lightos_driver.connector.connect_volume. + assert_called_once_with( + connection_info['data'])) + self.assertEqual('/dev/dms1234567', + connection_info['data']['device_path']) + + @mock.patch('os_brick.initiator.connector.InitiatorConnector.factory', + new=mock.Mock(return_value=mock.Mock())) + def test_libvirt_lightos_driver_disconnect(self): + lightos_driver = lightos.LibvirtLightOSVolumeDriver(self.connr) + disk_info = { + 'path': '/dev/dms1234567', 'name': 'aLightosVolume', + 'type': 'raw', 'dev': 'vda1', 'bus': 'pci0', + 'device_path': '/dev/dms123456'} + connection_info = {'data': disk_info} + lightos_driver.disconnect_volume(connection_info, None) + lightos_driver.connector.disconnect_volume.assert_called_once_with( + disk_info, None) + + @mock.patch('os_brick.initiator.connector.InitiatorConnector.factory', + new=mock.Mock(return_value=mock.Mock())) + def test_libvirt_lightos_driver_get_config(self): + lightos_driver = lightos.LibvirtLightOSVolumeDriver(self.fake_host) + device_path = '/dev/fake-dev' + connection_info = {'data': {'device_path': device_path}} + + conf = lightos_driver.get_config(connection_info, self.disk_info) + tree = conf.format_dom() + + self.assertEqual('block', tree.get('type')) + self.assertEqual(device_path, tree.find('./source').get('dev')) + self.assertEqual('raw', tree.find('./driver').get('type')) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index dc51541975..5dd5bbb9d6 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -188,6 +188,7 @@ VOLUME_DRIVERS = { 'vzstorage': 'nova.virt.libvirt.volume.vzstorage.LibvirtVZStorageVolumeDriver', # noqa:E501 'storpool': 'nova.virt.libvirt.volume.storpool.LibvirtStorPoolVolumeDriver', # noqa:E501 'nvmeof': 'nova.virt.libvirt.volume.nvme.LibvirtNVMEVolumeDriver', + 'lightos': 'nova.virt.libvirt.volume.lightos.LibvirtLightOSVolumeDriver', } diff --git a/nova/virt/libvirt/volume/lightos.py b/nova/virt/libvirt/volume/lightos.py new file mode 100644 index 0000000000..d6d393994e --- /dev/null +++ b/nova/virt/libvirt/volume/lightos.py @@ -0,0 +1,63 @@ +# Copyright (C) 2016-2020 Lightbits Labs Ltd. +# Copyright (C) 2020 Intel Corporation +# 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 nova.conf +from nova import utils +from nova.virt.libvirt.volume import volume as libvirt_volume +from os_brick import initiator +from os_brick.initiator import connector +from oslo_log import log as logging + + +LOG = logging.getLogger(__name__) +CONF = nova.conf.CONF + + +class LibvirtLightOSVolumeDriver(libvirt_volume.LibvirtVolumeDriver): + """Driver to attach NVMe volumes to libvirt.""" + VERSION = '2.3.12' + + def __init__(self, connection): + super(LibvirtLightOSVolumeDriver, self).__init__(connection) + self.connector = connector.InitiatorConnector.factory( + initiator.LIGHTOS, + root_helper=utils.get_root_helper(), + device_scan_attempts=CONF.libvirt.num_nvme_discover_tries) + + def connect_volume(self, connection_info, instance): + device_info = self.connector.connect_volume(connection_info['data']) + LOG.debug("Connecting NVMe volume with device_info %s", device_info) + connection_info['data']['device_path'] = device_info['path'] + + def disconnect_volume(self, connection_info, instance): + """Detach the volume from the instance.""" + LOG.debug("Disconnecting NVMe disk. instance:%s, volume_id:%s", + connection_info.get("instance", ""), + connection_info.get("volume_id", "")) + self.connector.disconnect_volume(connection_info['data'], None) + super(LibvirtLightOSVolumeDriver, self).disconnect_volume( + connection_info, instance) + + def extend_volume(self, connection_info, instance, requested_size=None): + """Extend the volume.""" + LOG.debug("calling os-brick to extend LightOS Volume." + "instance:%s, volume_id:%s", + connection_info.get("instance", ""), + connection_info.get("volume_id", "")) + new_size = self.connector.extend_volume(connection_info['data']) + LOG.debug("Extend LightOS Volume %s; new_size=%s", + connection_info['data']['device_path'], new_size) + return new_size diff --git a/requirements.txt b/requirements.txt index c83d6e38fa..dc5860d6e6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pbr>=5.5.1 # Apache-2.0 +pbr>=5.8.0 # Apache-2.0 SQLAlchemy>=1.4.13 # MIT decorator>=4.1.0 # BSD eventlet>=0.30.1 # MIT @@ -27,26 +27,26 @@ requests>=2.25.1 # Apache-2.0 stevedore>=1.20.0 # Apache-2.0 websockify>=0.9.0 # LGPLv3 oslo.cache>=1.26.0 # Apache-2.0 -oslo.concurrency>=4.4.0 # Apache-2.0 +oslo.concurrency>=4.5.0 # Apache-2.0 oslo.config>=8.6.0 # Apache-2.0 -oslo.context>=3.1.1 # Apache-2.0 -oslo.log>=4.4.0 # Apache-2.0 +oslo.context>=3.4.0 # Apache-2.0 +oslo.log>=4.6.1 # Apache-2.0 oslo.reports>=1.18.0 # Apache-2.0 -oslo.serialization>=4.1.0 # Apache-2.0 +oslo.serialization>=4.2.0 # Apache-2.0 oslo.upgradecheck>=1.3.0 -oslo.utils>=4.8.0 # Apache-2.0 +oslo.utils>=4.12.1 # Apache-2.0 oslo.db>=10.0.0 # Apache-2.0 oslo.rootwrap>=5.8.0 # Apache-2.0 oslo.messaging>=10.3.0 # Apache-2.0 oslo.policy>=3.7.0 # Apache-2.0 -oslo.privsep>=2.4.0 # Apache-2.0 -oslo.i18n>=5.0.1 # Apache-2.0 -oslo.service>=2.5.0 # Apache-2.0 +oslo.privsep>=2.6.2 # Apache-2.0 +oslo.i18n>=5.1.0 # Apache-2.0 +oslo.service>=2.8.0 # Apache-2.0 rfc3986>=1.2.0 # Apache-2.0 oslo.middleware>=3.31.0 # Apache-2.0 psutil>=3.2.2 # BSD oslo.versionedobjects>=1.35.0 # Apache-2.0 -os-brick>=4.3.1 # Apache-2.0 +os-brick>=5.2 # Apache-2.0 os-resource-classes>=1.1.0 # Apache-2.0 os-traits>=2.7.0 # Apache-2.0 os-vif>=1.15.2 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg index 99d7cdaf10..f433c2f6e7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,7 @@ powervm = zvm = zVMCloudConnector>=1.3.0;sys_platform!='win32' # Apache 2.0 License hyperv = - os-win>=5.4.0 # Apache-2.0 + os-win>=5.5.0 # Apache-2.0 vmware = oslo.vmware>=3.6.0 # Apache-2.0