Merge "libvirt: move the LibvirtQuobyteVolumeDriver into the quobyte module"

This commit is contained in:
Jenkins 2015-07-30 00:59:59 +00:00 committed by Gerrit Code Review
commit 31396bc1b1
5 changed files with 289 additions and 271 deletions

View File

@ -22,11 +22,14 @@ from oslo_utils import fileutils
from nova import exception from nova import exception
from nova import test from nova import test
from nova.tests.unit.virt.libvirt.volume import test_volume
from nova import utils from nova import utils
from nova.virt.libvirt import utils as libvirt_utils
from nova.virt.libvirt.volume import quobyte from nova.virt.libvirt.volume import quobyte
class QuobyteTestCase(test.NoDBTestCase): class QuobyteTestCase(test.NoDBTestCase):
"""Tests the nova.virt.libvirt.volume.quobyte module utilities."""
@mock.patch.object(fileutils, "ensure_tree") @mock.patch.object(fileutils, "ensure_tree")
@mock.patch.object(utils, "execute") @mock.patch.object(utils, "execute")
@ -181,3 +184,182 @@ class QuobyteTestCase(test.NoDBTestCase):
self.assertRaises(exception.NovaException, self.assertRaises(exception.NovaException,
quobyte.validate_volume, quobyte.validate_volume,
export_mnt_base) export_mnt_base)
class LibvirtQuobyteVolumeDriverTestCase(
test_volume.LibvirtVolumeBaseTestCase):
"""Tests the LibvirtQuobyteVolumeDriver class."""
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'mount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=False)
def test_libvirt_quobyte_driver_mount(self,
mock_is_mounted,
mock_mount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
mock_mount_volume.assert_called_once_with(quobyte_volume,
export_mnt_base,
mock.ANY)
mock_validate_volume.assert_called_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'umount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=True)
def test_libvirt_quobyte_driver_umount(self, mock_is_mounted,
mock_umount_volume,
mock_validate_volume):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
libvirt_driver.disconnect_volume(connection_info, "vde")
mock_validate_volume.assert_called_once_with(export_mnt_base)
mock_umount_volume.assert_called_once_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'umount_volume')
def test_libvirt_quobyte_driver_already_mounted(self,
mock_umount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
libvirt_driver.disconnect_volume(connection_info, "vde")
expected_commands = [
('findmnt', '--target', export_mnt_base,
'--source', "quobyte@" + quobyte_volume),
('findmnt', '--target', export_mnt_base,
'--source', "quobyte@" + quobyte_volume),
]
self.assertEqual(expected_commands, self.executes)
mock_umount_volume.assert_called_once_with(export_mnt_base)
mock_validate_volume.assert_called_once_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'mount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=False)
def test_libvirt_quobyte_driver_qcow2(self, mock_is_mounted,
mock_mount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
name = 'volume-00001'
image_format = 'qcow2'
quobyte_volume = '192.168.1.1/volume-00001'
connection_info = {'data': {'export': export_string,
'name': name,
'format': image_format}}
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self.assertEqual(tree.get('type'), 'file')
self.assertEqual(tree.find('./driver').get('type'), 'qcow2')
(mock_mount_volume.
assert_called_once_with('192.168.1.1/volume-00001',
export_mnt_base,
mock.ANY))
mock_validate_volume.assert_called_with(export_mnt_base)
libvirt_driver.disconnect_volume(connection_info, "vde")
def test_libvirt_quobyte_driver_mount_non_quobyte_volume(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
connection_info = {'data': {'export': export_string,
'name': self.name}}
def exe_side_effect(*cmd, **kwargs):
if cmd == mock.ANY:
raise exception.NovaException()
with mock.patch.object(quobyte,
'validate_volume') as mock_execute:
mock_execute.side_effect = exe_side_effect
self.assertRaises(exception.NovaException,
libvirt_driver.connect_volume,
connection_info,
self.disk_info)
def test_libvirt_quobyte_driver_normalize_url_with_protocol(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
self.assertEqual(libvirt_driver._normalize_url(export_string),
"192.168.1.1/volume-00001")
def test_libvirt_quobyte_driver_normalize_url_without_protocol(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = quobyte.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = '192.168.1.1/volume-00001'
self.assertEqual(libvirt_driver._normalize_url(export_string),
"192.168.1.1/volume-00001")

View File

@ -29,7 +29,6 @@ from nova.tests.unit.virt.libvirt import fakelibvirt
from nova import utils from nova import utils
from nova.virt.libvirt import host from nova.virt.libvirt import host
from nova.virt.libvirt import utils as libvirt_utils from nova.virt.libvirt import utils as libvirt_utils
from nova.virt.libvirt.volume import quobyte
from nova.virt.libvirt.volume import volume from nova.virt.libvirt.volume import volume
CONF = cfg.CONF CONF = cfg.CONF
@ -59,10 +58,11 @@ class FakeSecret(object):
return 0 return 0
class LibvirtVolumeTestCase(test.NoDBTestCase): class LibvirtVolumeBaseTestCase(test.NoDBTestCase):
"""Contains common setup and helper methods for libvirt volume tests."""
def setUp(self): def setUp(self):
super(LibvirtVolumeTestCase, self).setUp() super(LibvirtVolumeBaseTestCase, self).setUp()
self.executes = [] self.executes = []
def fake_execute(*cmd, **kwargs): def fake_execute(*cmd, **kwargs):
@ -98,6 +98,13 @@ class LibvirtVolumeTestCase(test.NoDBTestCase):
self.uuid = '875a8070-d0b9-4949-8b31-104d125c9a64' self.uuid = '875a8070-d0b9-4949-8b31-104d125c9a64'
self.user = 'foo' self.user = 'foo'
def _assertFileTypeEquals(self, tree, file_path):
self.assertEqual(tree.get('type'), 'file')
self.assertEqual(tree.find('./source').get('file'), file_path)
class LibvirtVolumeTestCase(LibvirtVolumeBaseTestCase):
def _assertNetworkAndProtocolEquals(self, tree): def _assertNetworkAndProtocolEquals(self, tree):
self.assertEqual(tree.get('type'), 'network') self.assertEqual(tree.get('type'), 'network')
self.assertEqual(tree.find('./source').get('protocol'), 'rbd') self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
@ -110,10 +117,6 @@ class LibvirtVolumeTestCase(test.NoDBTestCase):
iscsi_name = '%s/%s' % (self.iqn, self.vol['id']) iscsi_name = '%s/%s' % (self.iqn, self.vol['id'])
self.assertEqual(tree.find('./source').get('name'), iscsi_name) self.assertEqual(tree.find('./source').get('name'), iscsi_name)
def _assertFileTypeEquals(self, tree, file_path):
self.assertEqual(tree.get('type'), 'file')
self.assertEqual(tree.find('./source').get('file'), file_path)
def _assertDiskInfoEquals(self, tree, disk_info): def _assertDiskInfoEquals(self, tree, disk_info):
self.assertEqual(tree.get('device'), disk_info['type']) self.assertEqual(tree.get('device'), disk_info['type'])
self.assertEqual(tree.find('./target').get('bus'), self.assertEqual(tree.find('./target').get('bus'),
@ -933,177 +936,3 @@ Setting up iSCSI targets: unused
tree = conf.format_dom() tree = conf.format_dom()
self.assertEqual('file', tree.get('type')) self.assertEqual('file', tree.get('type'))
self.assertEqual('fake_serial', tree.find('./serial').text) self.assertEqual('fake_serial', tree.find('./serial').text)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'mount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=False)
def test_libvirt_quobyte_driver_mount(self,
mock_is_mounted,
mock_mount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
mock_mount_volume.assert_called_once_with(quobyte_volume,
export_mnt_base,
mock.ANY)
mock_validate_volume.assert_called_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'umount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=True)
def test_libvirt_quobyte_driver_umount(self, mock_is_mounted,
mock_umount_volume,
mock_validate_volume):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
libvirt_driver.disconnect_volume(connection_info, "vde")
mock_validate_volume.assert_called_once_with(export_mnt_base)
mock_umount_volume.assert_called_once_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'umount_volume')
def test_libvirt_quobyte_driver_already_mounted(self,
mock_umount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
quobyte_volume = '192.168.1.1/volume-00001'
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
libvirt_driver.disconnect_volume(connection_info, "vde")
expected_commands = [
('findmnt', '--target', export_mnt_base,
'--source', "quobyte@" + quobyte_volume),
('findmnt', '--target', export_mnt_base,
'--source', "quobyte@" + quobyte_volume),
]
self.assertEqual(expected_commands, self.executes)
mock_umount_volume.assert_called_once_with(export_mnt_base)
mock_validate_volume.assert_called_once_with(export_mnt_base)
@mock.patch.object(quobyte, 'validate_volume')
@mock.patch.object(quobyte, 'mount_volume')
@mock.patch.object(libvirt_utils, 'is_mounted', return_value=False)
def test_libvirt_quobyte_driver_qcow2(self, mock_is_mounted,
mock_mount_volume,
mock_validate_volume
):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
name = 'volume-00001'
image_format = 'qcow2'
quobyte_volume = '192.168.1.1/volume-00001'
connection_info = {'data': {'export': export_string,
'name': name,
'format': image_format}}
export_mnt_base = os.path.join(mnt_base,
utils.get_hash_str(quobyte_volume))
libvirt_driver.connect_volume(connection_info, self.disk_info)
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self.assertEqual(tree.get('type'), 'file')
self.assertEqual(tree.find('./driver').get('type'), 'qcow2')
(mock_mount_volume.
assert_called_once_with('192.168.1.1/volume-00001',
export_mnt_base,
mock.ANY))
mock_validate_volume.assert_called_with(export_mnt_base)
libvirt_driver.disconnect_volume(connection_info, "vde")
def test_libvirt_quobyte_driver_mount_non_quobyte_volume(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
connection_info = {'data': {'export': export_string,
'name': self.name}}
def exe_side_effect(*cmd, **kwargs):
if cmd == mock.ANY:
raise exception.NovaException()
with mock.patch.object(quobyte,
'validate_volume') as mock_execute:
mock_execute.side_effect = exe_side_effect
self.assertRaises(exception.NovaException,
libvirt_driver.connect_volume,
connection_info,
self.disk_info)
def test_libvirt_quobyte_driver_normalize_url_with_protocol(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = 'quobyte://192.168.1.1/volume-00001'
self.assertEqual(libvirt_driver._normalize_url(export_string),
"192.168.1.1/volume-00001")
def test_libvirt_quobyte_driver_normalize_url_without_protocol(self):
mnt_base = '/mnt'
self.flags(quobyte_mount_point_base=mnt_base, group='libvirt')
libvirt_driver = volume.LibvirtQuobyteVolumeDriver(self.fake_conn)
export_string = '192.168.1.1/volume-00001'
self.assertEqual(libvirt_driver._normalize_url(export_string),
"192.168.1.1/volume-00001")

View File

@ -286,7 +286,7 @@ libvirt_volume_drivers = [
'nova.virt.libvirt.volume.volume.LibvirtFibreChannelVolumeDriver', 'nova.virt.libvirt.volume.volume.LibvirtFibreChannelVolumeDriver',
'scality=nova.virt.libvirt.volume.volume.LibvirtScalityVolumeDriver', 'scality=nova.virt.libvirt.volume.volume.LibvirtScalityVolumeDriver',
'gpfs=nova.virt.libvirt.volume.volume.LibvirtGPFSVolumeDriver', 'gpfs=nova.virt.libvirt.volume.volume.LibvirtGPFSVolumeDriver',
'quobyte=nova.virt.libvirt.volume.volume.LibvirtQuobyteVolumeDriver', 'quobyte=nova.virt.libvirt.volume.quobyte.LibvirtQuobyteVolumeDriver',
] ]

View File

@ -13,9 +13,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import errno
import os import os
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import fileutils from oslo_utils import fileutils
@ -23,11 +25,25 @@ from nova import exception as nova_exception
from nova.i18n import _ from nova.i18n import _
from nova.i18n import _LE from nova.i18n import _LE
from nova.i18n import _LI from nova.i18n import _LI
from nova import paths
from nova import utils from nova import utils
from nova.virt.libvirt import utils as libvirt_utils
from nova.virt.libvirt.volume import volume as libvirt_volume
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
volume_opts = [
cfg.StrOpt('quobyte_mount_point_base',
default=paths.state_path_def('mnt'),
help='Directory where the Quobyte volume is mounted on the '
'compute node'),
cfg.StrOpt('quobyte_client_cfg',
help='Path to a Quobyte Client configuration file.'),
]
CONF = cfg.CONF
CONF.register_opts(volume_opts, 'libvirt')
SOURCE_PROTOCOL = 'quobyte' SOURCE_PROTOCOL = 'quobyte'
SOURCE_TYPE = 'file' SOURCE_TYPE = 'file'
DRIVER_CACHE = 'none' DRIVER_CACHE = 'none'
@ -78,3 +94,82 @@ def validate_volume(mnt_base):
msg = (_LE("Volume is not writable. Please broaden the file" msg = (_LE("Volume is not writable. Please broaden the file"
" permissions. Mount: %s") % mnt_base) " permissions. Mount: %s") % mnt_base)
raise nova_exception.NovaException(msg) raise nova_exception.NovaException(msg)
class LibvirtQuobyteVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver):
"""Class implements libvirt part of volume driver for Quobyte."""
def __init__(self, connection):
"""Create back-end to Quobyte."""
super(LibvirtQuobyteVolumeDriver,
self).__init__(connection, is_block_dev=False)
def get_config(self, connection_info, disk_info):
conf = super(LibvirtQuobyteVolumeDriver,
self).get_config(connection_info, disk_info)
data = connection_info['data']
conf.source_protocol = SOURCE_PROTOCOL
conf.source_type = SOURCE_TYPE
conf.driver_cache = DRIVER_CACHE
conf.driver_io = DRIVER_IO
conf.driver_format = data.get('format', 'raw')
quobyte_volume = self._normalize_url(data['export'])
path = os.path.join(self._get_mount_point_for_share(quobyte_volume),
data['name'])
conf.source_path = path
return conf
@utils.synchronized('connect_volume')
def connect_volume(self, connection_info, disk_info):
"""Connect the volume."""
data = connection_info['data']
quobyte_volume = self._normalize_url(data['export'])
mount_path = self._get_mount_point_for_share(quobyte_volume)
mounted = libvirt_utils.is_mounted(mount_path,
SOURCE_PROTOCOL
+ '@' + quobyte_volume)
if mounted:
try:
os.stat(mount_path)
except OSError as exc:
if exc.errno == errno.ENOTCONN:
mounted = False
LOG.info(_LI('Fixing previous mount %s which was not'
' unmounted correctly.'), mount_path)
umount_volume(mount_path)
if not mounted:
mount_volume(quobyte_volume,
mount_path,
CONF.libvirt.quobyte_client_cfg)
validate_volume(mount_path)
@utils.synchronized('connect_volume')
def disconnect_volume(self, connection_info, disk_dev):
"""Disconnect the volume."""
quobyte_volume = self._normalize_url(connection_info['data']['export'])
mount_path = self._get_mount_point_for_share(quobyte_volume)
if libvirt_utils.is_mounted(mount_path, 'quobyte@' + quobyte_volume):
umount_volume(mount_path)
else:
LOG.info(_LI("Trying to disconnected unmounted volume at %s"),
mount_path)
def _normalize_url(self, export):
protocol = SOURCE_PROTOCOL + "://"
if export.startswith(protocol):
export = export[len(protocol):]
return export
def _get_mount_point_for_share(self, quobyte_volume):
"""Return mount point for Quobyte volume.
:param quobyte_volume: Example: storage-host/openstack-volumes
"""
return os.path.join(CONF.libvirt.quobyte_mount_point_base,
utils.get_hash_str(quobyte_volume))

View File

@ -16,7 +16,6 @@
"""Volume drivers for libvirt.""" """Volume drivers for libvirt."""
import errno
import os import os
import re import re
@ -31,13 +30,11 @@ import six.moves.urllib.parse as urlparse
from nova import exception from nova import exception
from nova.i18n import _ from nova.i18n import _
from nova.i18n import _LE from nova.i18n import _LE
from nova.i18n import _LI
from nova.i18n import _LW from nova.i18n import _LW
from nova import paths from nova import paths
from nova import utils from nova import utils
from nova.virt.libvirt import config as vconfig from nova.virt.libvirt import config as vconfig
from nova.virt.libvirt import utils as libvirt_utils from nova.virt.libvirt import utils as libvirt_utils
from nova.virt.libvirt.volume import quobyte
from nova.virt.libvirt.volume import remotefs from nova.virt.libvirt.volume import remotefs
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -92,12 +89,6 @@ volume_opts = [
default=[], default=[],
help='Protocols listed here will be accessed directly ' help='Protocols listed here will be accessed directly '
'from QEMU. Currently supported protocols: [gluster]'), 'from QEMU. Currently supported protocols: [gluster]'),
cfg.StrOpt('quobyte_mount_point_base',
default=paths.state_path_def('mnt'),
help='Directory where the Quobyte volume is mounted on the '
'compute node'),
cfg.StrOpt('quobyte_client_cfg',
help='Path to a Quobyte Client configuration file.'),
cfg.StrOpt('iscsi_iface', cfg.StrOpt('iscsi_iface',
deprecated_name='iscsi_transport', deprecated_name='iscsi_transport',
help='The iSCSI transport iface to use to connect to target in ' help='The iSCSI transport iface to use to connect to target in '
@ -787,82 +778,3 @@ class LibvirtGPFSVolumeDriver(LibvirtBaseVolumeDriver):
conf.source_type = "file" conf.source_type = "file"
conf.source_path = connection_info['data']['device_path'] conf.source_path = connection_info['data']['device_path']
return conf return conf
class LibvirtQuobyteVolumeDriver(LibvirtBaseVolumeDriver):
"""Class implements libvirt part of volume driver for Quobyte."""
def __init__(self, connection):
"""Create back-end to Quobyte."""
super(LibvirtQuobyteVolumeDriver,
self).__init__(connection, is_block_dev=False)
def get_config(self, connection_info, disk_info):
conf = super(LibvirtQuobyteVolumeDriver,
self).get_config(connection_info, disk_info)
data = connection_info['data']
conf.source_protocol = quobyte.SOURCE_PROTOCOL
conf.source_type = quobyte.SOURCE_TYPE
conf.driver_cache = quobyte.DRIVER_CACHE
conf.driver_io = quobyte.DRIVER_IO
conf.driver_format = data.get('format', 'raw')
quobyte_volume = self._normalize_url(data['export'])
path = os.path.join(self._get_mount_point_for_share(quobyte_volume),
data['name'])
conf.source_path = path
return conf
@utils.synchronized('connect_volume')
def connect_volume(self, connection_info, disk_info):
"""Connect the volume."""
data = connection_info['data']
quobyte_volume = self._normalize_url(data['export'])
mount_path = self._get_mount_point_for_share(quobyte_volume)
mounted = libvirt_utils.is_mounted(mount_path,
quobyte.SOURCE_PROTOCOL
+ '@' + quobyte_volume)
if mounted:
try:
os.stat(mount_path)
except OSError as exc:
if exc.errno == errno.ENOTCONN:
mounted = False
LOG.info(_LI('Fixing previous mount %s which was not'
' unmounted correctly.'), mount_path)
quobyte.umount_volume(mount_path)
if not mounted:
quobyte.mount_volume(quobyte_volume,
mount_path,
CONF.libvirt.quobyte_client_cfg)
quobyte.validate_volume(mount_path)
@utils.synchronized('connect_volume')
def disconnect_volume(self, connection_info, disk_dev):
"""Disconnect the volume."""
quobyte_volume = self._normalize_url(connection_info['data']['export'])
mount_path = self._get_mount_point_for_share(quobyte_volume)
if libvirt_utils.is_mounted(mount_path, 'quobyte@' + quobyte_volume):
quobyte.umount_volume(mount_path)
else:
LOG.info(_LI("Trying to disconnected unmounted volume at %s"),
mount_path)
def _normalize_url(self, export):
protocol = quobyte.SOURCE_PROTOCOL + "://"
if export.startswith(protocol):
export = export[len(protocol):]
return export
def _get_mount_point_for_share(self, quobyte_volume):
"""Return mount point for Quobyte volume.
:param quobyte_volume: Example: storage-host/openstack-volumes
"""
return os.path.join(CONF.libvirt.quobyte_mount_point_base,
utils.get_hash_str(quobyte_volume))