Skip to content

Commit b5e2128

Browse files
yuval-lbElod Illes
authored andcommitted
Lightbits LightOS driver
This commit introduces the LightOS driver for nova. LightOS is a software-defined disaggregated clustered storage solution running on commodity servers with commodity SSDs. It it developed by Lightbits Labs (https://www.lightbitslabs.com) and is actively developed and maintained. LightOS is proprietary but the openstack drivers are licensed under Apache v2.0. The Cinder driver for LightOS currently supports the following functionality: Create volume Delete volume Attach volume Detach volume Create image from volume create volume from image Live migration Volume replication Thin provisioning Multi-attach Extend volume Create snapshot Delete snapshot Create volume from snapshot Create volume from volume (clone) This driver has been developed and has been in use for a couple of years by Lightbits and our clients. We have tested it extensively internally with multiple openstack versions, including Queens, Rocky, Stein, and Train. We have also tested it with master (19.1 xena) and we are working to extend testing to cover additional openstack releases. We are glad to join the openstack community and hope to get your feedback and comments on this driver, and if it is acceptable, to see it merged into the tree. Note: the patch depends on os-brick 5.2.0. That version also increased the lower constraints of several dependencies, thus needs nova to increase those as well in requirements.txt, lower-constraints.txt and setup.cfg. Depends-On: I2e86fa84049053b7c75421d33ad1a1af459ef4e0 Signed-off-by: Yuval Brave [email protected] Change-Id: Ic314b26695d9681d31a18adcec0794c2ff41fe71
1 parent 0c31561 commit b5e2128

File tree

6 files changed

+167
-22
lines changed

6 files changed

+167
-22
lines changed

lower-constraints.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,31 @@ netifaces==0.10.4
5858
networkx==2.1.0
5959
numpy==1.19.0
6060
openstacksdk==0.35.0
61-
os-brick==4.3.1
61+
os-brick==5.2
6262
os-client-config==1.29.0
6363
os-resource-classes==1.1.0
6464
os-service-types==1.7.0
6565
os-traits==2.7.0
6666
os-vif==1.15.2
67-
os-win==5.4.0
67+
os-win==5.5.0
6868
osc-lib==1.10.0
6969
oslo.cache==1.26.0
70-
oslo.concurrency==4.4.0
70+
oslo.concurrency==4.5.0
7171
oslo.config==8.6.0
72-
oslo.context==3.1.1
72+
oslo.context==3.4.0
7373
oslo.db==10.0.0
74-
oslo.i18n==5.0.1
75-
oslo.log==4.4.0
74+
oslo.i18n==5.1.0
75+
oslo.log==4.6.1
7676
oslo.messaging==10.3.0
7777
oslo.middleware==3.31.0
7878
oslo.policy==3.7.0
79-
oslo.privsep==2.4.0
79+
oslo.privsep==2.6.2
8080
oslo.reports==1.18.0
8181
oslo.rootwrap==5.8.0
82-
oslo.serialization==4.1.0
83-
oslo.service==2.5.0
82+
oslo.serialization==4.2.0
83+
oslo.service==2.8.0
8484
oslo.upgradecheck==1.3.0
85-
oslo.utils==4.8.0
85+
oslo.utils==4.12.1
8686
oslo.versionedobjects==1.35.0
8787
oslo.vmware==3.6.0
8888
oslotest==3.8.0
@@ -93,7 +93,7 @@ packaging==20.4
9393
paramiko==2.7.1
9494
Paste==2.0.2
9595
PasteDeploy==1.5.0
96-
pbr==5.5.1
96+
pbr==5.8.0
9797
pluggy==0.6.0
9898
ply==3.11
9999
prettytable==0.7.1
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import mock
14+
15+
from nova.tests.unit.virt.libvirt.volume import test_volume
16+
from nova.virt.libvirt.volume import lightos
17+
18+
from os_brick import initiator
19+
20+
21+
class LibvirtLightVolumeDriverTestCase(test_volume.LibvirtVolumeBaseTestCase):
22+
23+
@mock.patch('queue.Queue', return_value='queue')
24+
@mock.patch('nova.utils.get_root_helper')
25+
@mock.patch('os_brick.initiator.connector.InitiatorConnector.factory')
26+
def test_libvirt_lightos_driver(self, mock_factory, mock_helper,
27+
queue):
28+
self.flags(group='libvirt')
29+
mock_helper.return_value = 'sudo'
30+
lightos.LibvirtLightOSVolumeDriver(self.fake_host)
31+
mock_factory.assert_called_once_with(
32+
initiator.LIGHTOS, root_helper='sudo',
33+
device_scan_attempts=5)
34+
35+
@mock.patch('os_brick.initiator.connector.InitiatorConnector.factory',
36+
new=mock.Mock(return_value=mock.Mock()))
37+
def test_libvirt_lightos_driver_connect(self):
38+
lightos_driver = lightos.LibvirtLightOSVolumeDriver(
39+
self.fake_host)
40+
config = {'server_ip': '127.0.0.1', 'server_port': 9898}
41+
disk_info = {
42+
'id': '1234567',
43+
'name': 'aLightVolume',
44+
'conf': config}
45+
connection_info = {'data': disk_info}
46+
with mock.patch.object(lightos_driver.connector,
47+
'connect_volume',
48+
return_value={'path': '/dev/dms1234567'}):
49+
lightos_driver.connect_volume(connection_info, None)
50+
(lightos_driver.connector.connect_volume.
51+
assert_called_once_with(
52+
connection_info['data']))
53+
self.assertEqual('/dev/dms1234567',
54+
connection_info['data']['device_path'])
55+
56+
@mock.patch('os_brick.initiator.connector.InitiatorConnector.factory',
57+
new=mock.Mock(return_value=mock.Mock()))
58+
def test_libvirt_lightos_driver_disconnect(self):
59+
lightos_driver = lightos.LibvirtLightOSVolumeDriver(self.connr)
60+
disk_info = {
61+
'path': '/dev/dms1234567', 'name': 'aLightosVolume',
62+
'type': 'raw', 'dev': 'vda1', 'bus': 'pci0',
63+
'device_path': '/dev/dms123456'}
64+
connection_info = {'data': disk_info}
65+
lightos_driver.disconnect_volume(connection_info, None)
66+
lightos_driver.connector.disconnect_volume.assert_called_once_with(
67+
disk_info, None)
68+
69+
@mock.patch('os_brick.initiator.connector.InitiatorConnector.factory',
70+
new=mock.Mock(return_value=mock.Mock()))
71+
def test_libvirt_lightos_driver_get_config(self):
72+
lightos_driver = lightos.LibvirtLightOSVolumeDriver(self.fake_host)
73+
device_path = '/dev/fake-dev'
74+
connection_info = {'data': {'device_path': device_path}}
75+
76+
conf = lightos_driver.get_config(connection_info, self.disk_info)
77+
tree = conf.format_dom()
78+
79+
self.assertEqual('block', tree.get('type'))
80+
self.assertEqual(device_path, tree.find('./source').get('dev'))
81+
self.assertEqual('raw', tree.find('./driver').get('type'))

nova/virt/libvirt/driver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def __repr__(self):
188188
'vzstorage': 'nova.virt.libvirt.volume.vzstorage.LibvirtVZStorageVolumeDriver', # noqa:E501
189189
'storpool': 'nova.virt.libvirt.volume.storpool.LibvirtStorPoolVolumeDriver', # noqa:E501
190190
'nvmeof': 'nova.virt.libvirt.volume.nvme.LibvirtNVMEVolumeDriver',
191+
'lightos': 'nova.virt.libvirt.volume.lightos.LibvirtLightOSVolumeDriver',
191192
}
192193

193194

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (C) 2016-2020 Lightbits Labs Ltd.
2+
# Copyright (C) 2020 Intel Corporation
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
import nova.conf
18+
from nova import utils
19+
from nova.virt.libvirt.volume import volume as libvirt_volume
20+
from os_brick import initiator
21+
from os_brick.initiator import connector
22+
from oslo_log import log as logging
23+
24+
25+
LOG = logging.getLogger(__name__)
26+
CONF = nova.conf.CONF
27+
28+
29+
class LibvirtLightOSVolumeDriver(libvirt_volume.LibvirtVolumeDriver):
30+
"""Driver to attach NVMe volumes to libvirt."""
31+
VERSION = '2.3.12'
32+
33+
def __init__(self, connection):
34+
super(LibvirtLightOSVolumeDriver, self).__init__(connection)
35+
self.connector = connector.InitiatorConnector.factory(
36+
initiator.LIGHTOS,
37+
root_helper=utils.get_root_helper(),
38+
device_scan_attempts=CONF.libvirt.num_nvme_discover_tries)
39+
40+
def connect_volume(self, connection_info, instance):
41+
device_info = self.connector.connect_volume(connection_info['data'])
42+
LOG.debug("Connecting NVMe volume with device_info %s", device_info)
43+
connection_info['data']['device_path'] = device_info['path']
44+
45+
def disconnect_volume(self, connection_info, instance):
46+
"""Detach the volume from the instance."""
47+
LOG.debug("Disconnecting NVMe disk. instance:%s, volume_id:%s",
48+
connection_info.get("instance", ""),
49+
connection_info.get("volume_id", ""))
50+
self.connector.disconnect_volume(connection_info['data'], None)
51+
super(LibvirtLightOSVolumeDriver, self).disconnect_volume(
52+
connection_info, instance)
53+
54+
def extend_volume(self, connection_info, instance, requested_size=None):
55+
"""Extend the volume."""
56+
LOG.debug("calling os-brick to extend LightOS Volume."
57+
"instance:%s, volume_id:%s",
58+
connection_info.get("instance", ""),
59+
connection_info.get("volume_id", ""))
60+
new_size = self.connector.extend_volume(connection_info['data'])
61+
LOG.debug("Extend LightOS Volume %s; new_size=%s",
62+
connection_info['data']['device_path'], new_size)
63+
return new_size

requirements.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pbr>=5.5.1 # Apache-2.0
1+
pbr>=5.8.0 # Apache-2.0
22
SQLAlchemy>=1.4.13 # MIT
33
decorator>=4.1.0 # BSD
44
eventlet>=0.30.1 # MIT
@@ -27,26 +27,26 @@ requests>=2.25.1 # Apache-2.0
2727
stevedore>=1.20.0 # Apache-2.0
2828
websockify>=0.9.0 # LGPLv3
2929
oslo.cache>=1.26.0 # Apache-2.0
30-
oslo.concurrency>=4.4.0 # Apache-2.0
30+
oslo.concurrency>=4.5.0 # Apache-2.0
3131
oslo.config>=8.6.0 # Apache-2.0
32-
oslo.context>=3.1.1 # Apache-2.0
33-
oslo.log>=4.4.0 # Apache-2.0
32+
oslo.context>=3.4.0 # Apache-2.0
33+
oslo.log>=4.6.1 # Apache-2.0
3434
oslo.reports>=1.18.0 # Apache-2.0
35-
oslo.serialization>=4.1.0 # Apache-2.0
35+
oslo.serialization>=4.2.0 # Apache-2.0
3636
oslo.upgradecheck>=1.3.0
37-
oslo.utils>=4.8.0 # Apache-2.0
37+
oslo.utils>=4.12.1 # Apache-2.0
3838
oslo.db>=10.0.0 # Apache-2.0
3939
oslo.rootwrap>=5.8.0 # Apache-2.0
4040
oslo.messaging>=10.3.0 # Apache-2.0
4141
oslo.policy>=3.7.0 # Apache-2.0
42-
oslo.privsep>=2.4.0 # Apache-2.0
43-
oslo.i18n>=5.0.1 # Apache-2.0
44-
oslo.service>=2.5.0 # Apache-2.0
42+
oslo.privsep>=2.6.2 # Apache-2.0
43+
oslo.i18n>=5.1.0 # Apache-2.0
44+
oslo.service>=2.8.0 # Apache-2.0
4545
rfc3986>=1.2.0 # Apache-2.0
4646
oslo.middleware>=3.31.0 # Apache-2.0
4747
psutil>=3.2.2 # BSD
4848
oslo.versionedobjects>=1.35.0 # Apache-2.0
49-
os-brick>=4.3.1 # Apache-2.0
49+
os-brick>=5.2 # Apache-2.0
5050
os-resource-classes>=1.1.0 # Apache-2.0
5151
os-traits>=2.7.0 # Apache-2.0
5252
os-vif>=1.15.2 # Apache-2.0

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ powervm =
3535
zvm =
3636
zVMCloudConnector>=1.3.0;sys_platform!='win32' # Apache 2.0 License
3737
hyperv =
38-
os-win>=5.4.0 # Apache-2.0
38+
os-win>=5.5.0 # Apache-2.0
3939
vmware =
4040
oslo.vmware>=3.6.0 # Apache-2.0
4141

0 commit comments

Comments
 (0)