Merge "libvirt: move LibvirtSMBFSVolumeDriver into it's own module"
This commit is contained in:
commit
b144fe4447
104
nova/tests/unit/virt/libvirt/volume/test_smbfs.py
Normal file
104
nova/tests/unit/virt/libvirt/volume/test_smbfs.py
Normal file
@ -0,0 +1,104 @@
|
||||
# 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
|
||||
|
||||
from nova.tests.unit.virt.libvirt.volume import test_volume
|
||||
from nova import utils
|
||||
from nova.virt.libvirt import utils as libvirt_utils
|
||||
from nova.virt.libvirt.volume import smbfs
|
||||
|
||||
|
||||
class LibvirtSMBFSVolumeDriverTestCase(test_volume.LibvirtVolumeBaseTestCase):
|
||||
"""Tests the libvirt SMBFS volume driver."""
|
||||
|
||||
def setUp(self):
|
||||
super(LibvirtSMBFSVolumeDriverTestCase, self).setUp()
|
||||
self.mnt_base = '/mnt'
|
||||
self.flags(smbfs_mount_point_base=self.mnt_base, group='libvirt')
|
||||
|
||||
@mock.patch.object(libvirt_utils, 'is_mounted')
|
||||
def test_libvirt_smbfs_driver(self, mock_is_mounted):
|
||||
mock_is_mounted.return_value = False
|
||||
|
||||
libvirt_driver = smbfs.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(self.mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'options': None}}
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('mkdir', '-p', export_mnt_base),
|
||||
('mount', '-t', 'cifs', '-o', 'username=guest',
|
||||
export_string, export_mnt_base),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
||||
def test_libvirt_smbfs_driver_already_mounted(self):
|
||||
libvirt_driver = smbfs.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(self.mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name}}
|
||||
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('findmnt', '--target', export_mnt_base,
|
||||
'--source', export_string),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
||||
def test_libvirt_smbfs_driver_get_config(self):
|
||||
libvirt_driver = smbfs.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(self.mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
file_path = os.path.join(export_mnt_base, self.name)
|
||||
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'device_path': file_path}}
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertFileTypeEquals(tree, file_path)
|
||||
|
||||
@mock.patch.object(libvirt_utils, 'is_mounted')
|
||||
def test_libvirt_smbfs_driver_with_opts(self, mock_is_mounted):
|
||||
mock_is_mounted.return_value = False
|
||||
|
||||
libvirt_driver = smbfs.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
options = '-o user=guest,uid=107,gid=105'
|
||||
export_mnt_base = os.path.join(self.mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'options': options}}
|
||||
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('mkdir', '-p', export_mnt_base),
|
||||
('mount', '-t', 'cifs', '-o', 'user=guest,uid=107,gid=105',
|
||||
export_string, export_mnt_base),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
@ -644,87 +644,3 @@ Setting up iSCSI targets: unused
|
||||
('umount', export_mnt_base),
|
||||
]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
||||
@mock.patch.object(libvirt_utils, 'is_mounted')
|
||||
def test_libvirt_smbfs_driver(self, mock_is_mounted):
|
||||
mnt_base = '/mnt'
|
||||
self.flags(smbfs_mount_point_base=mnt_base, group='libvirt')
|
||||
mock_is_mounted.return_value = False
|
||||
|
||||
libvirt_driver = volume.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'options': None}}
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('mkdir', '-p', export_mnt_base),
|
||||
('mount', '-t', 'cifs', '-o', 'username=guest',
|
||||
export_string, export_mnt_base),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
||||
def test_libvirt_smbfs_driver_already_mounted(self):
|
||||
mnt_base = '/mnt'
|
||||
self.flags(smbfs_mount_point_base=mnt_base, group='libvirt')
|
||||
|
||||
libvirt_driver = volume.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name}}
|
||||
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('findmnt', '--target', export_mnt_base,
|
||||
'--source', export_string),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
||||
def test_libvirt_smbfs_driver_get_config(self):
|
||||
mnt_base = '/mnt'
|
||||
self.flags(smbfs_mount_point_base=mnt_base, group='libvirt')
|
||||
libvirt_driver = volume.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
export_mnt_base = os.path.join(mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
file_path = os.path.join(export_mnt_base, self.name)
|
||||
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'device_path': file_path}}
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertFileTypeEquals(tree, file_path)
|
||||
|
||||
@mock.patch.object(libvirt_utils, 'is_mounted')
|
||||
def test_libvirt_smbfs_driver_with_opts(self, mock_is_mounted):
|
||||
mnt_base = '/mnt'
|
||||
self.flags(smbfs_mount_point_base=mnt_base, group='libvirt')
|
||||
mock_is_mounted.return_value = False
|
||||
|
||||
libvirt_driver = volume.LibvirtSMBFSVolumeDriver(self.fake_conn)
|
||||
export_string = '//192.168.1.1/volumes'
|
||||
options = '-o user=guest,uid=107,gid=105'
|
||||
export_mnt_base = os.path.join(mnt_base,
|
||||
utils.get_hash_str(export_string))
|
||||
connection_info = {'data': {'export': export_string,
|
||||
'name': self.name,
|
||||
'options': options}}
|
||||
|
||||
libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
expected_commands = [
|
||||
('mkdir', '-p', export_mnt_base),
|
||||
('mount', '-t', 'cifs', '-o', 'user=guest,uid=107,gid=105',
|
||||
export_string, export_mnt_base),
|
||||
('umount', export_mnt_base)]
|
||||
self.assertEqual(expected_commands, self.executes)
|
||||
|
@ -280,7 +280,7 @@ libvirt_volume_drivers = [
|
||||
'rbd=nova.virt.libvirt.volume.volume.LibvirtNetVolumeDriver',
|
||||
'sheepdog=nova.virt.libvirt.volume.volume.LibvirtNetVolumeDriver',
|
||||
'nfs=nova.virt.libvirt.volume.volume.LibvirtNFSVolumeDriver',
|
||||
'smbfs=nova.virt.libvirt.volume.volume.LibvirtSMBFSVolumeDriver',
|
||||
'smbfs=nova.virt.libvirt.volume.smbfs.LibvirtSMBFSVolumeDriver',
|
||||
'aoe=nova.virt.libvirt.volume.aoe.LibvirtAOEVolumeDriver',
|
||||
'glusterfs='
|
||||
'nova.virt.libvirt.volume.glusterfs.LibvirtGlusterfsVolumeDriver',
|
||||
|
101
nova/virt/libvirt/volume/smbfs.py
Normal file
101
nova/virt/libvirt/volume/smbfs.py
Normal file
@ -0,0 +1,101 @@
|
||||
# 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 re
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from nova import paths
|
||||
from nova import utils
|
||||
from nova.virt.libvirt import utils as libvirt_utils
|
||||
from nova.virt.libvirt.volume import remotefs
|
||||
from nova.virt.libvirt.volume import volume as libvirt_volume
|
||||
|
||||
volume_opts = [
|
||||
cfg.StrOpt('smbfs_mount_point_base',
|
||||
default=paths.state_path_def('mnt'),
|
||||
help='Directory where the SMBFS shares are mounted on the '
|
||||
'compute node'),
|
||||
cfg.StrOpt('smbfs_mount_options',
|
||||
default='',
|
||||
help='Mount options passed to the SMBFS client. See '
|
||||
'mount.cifs man page for details. Note that the '
|
||||
'libvirt-qemu uid and gid must be specified.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts, 'libvirt')
|
||||
|
||||
|
||||
class LibvirtSMBFSVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver):
|
||||
"""Class implements libvirt part of volume driver for SMBFS."""
|
||||
|
||||
def __init__(self, connection):
|
||||
super(LibvirtSMBFSVolumeDriver,
|
||||
self).__init__(connection, is_block_dev=False)
|
||||
self.username_regex = re.compile(
|
||||
r"(user(?:name)?)=(?:[^ ,]+\\)?([^ ,]+)")
|
||||
|
||||
def _get_device_path(self, connection_info):
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
volume_path = os.path.join(mount_path,
|
||||
connection_info['data']['name'])
|
||||
return volume_path
|
||||
|
||||
def _get_mount_path(self, smbfs_share):
|
||||
mount_path = os.path.join(CONF.libvirt.smbfs_mount_point_base,
|
||||
utils.get_hash_str(smbfs_share))
|
||||
return mount_path
|
||||
|
||||
def get_config(self, connection_info, disk_info):
|
||||
"""Returns xml for libvirt."""
|
||||
conf = super(LibvirtSMBFSVolumeDriver,
|
||||
self).get_config(connection_info, disk_info)
|
||||
|
||||
conf.source_type = 'file'
|
||||
conf.driver_cache = 'writethrough'
|
||||
conf.source_path = connection_info['data']['device_path']
|
||||
conf.driver_format = connection_info['data'].get('format', 'raw')
|
||||
return conf
|
||||
|
||||
def connect_volume(self, connection_info, disk_info):
|
||||
"""Connect the volume."""
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
|
||||
if not libvirt_utils.is_mounted(mount_path, smbfs_share):
|
||||
mount_options = self._parse_mount_options(connection_info)
|
||||
remotefs.mount_share(mount_path, smbfs_share,
|
||||
export_type='cifs', options=mount_options)
|
||||
|
||||
device_path = self._get_device_path(connection_info)
|
||||
connection_info['data']['device_path'] = device_path
|
||||
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
"""Disconnect the volume."""
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
remotefs.unmount_share(mount_path, smbfs_share)
|
||||
|
||||
def _parse_mount_options(self, connection_info):
|
||||
mount_options = " ".join(
|
||||
[connection_info['data'].get('options') or '',
|
||||
CONF.libvirt.smbfs_mount_options])
|
||||
|
||||
if not self.username_regex.findall(mount_options):
|
||||
mount_options = mount_options + ' -o username=guest'
|
||||
else:
|
||||
# Remove the Domain Name from user name
|
||||
mount_options = self.username_regex.sub(r'\1=\2', mount_options)
|
||||
return mount_options.strip(", ").split(' ')
|
@ -17,7 +17,6 @@
|
||||
"""Volume drivers for libvirt."""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from os_brick.initiator import connector
|
||||
from oslo_concurrency import processutils
|
||||
@ -33,7 +32,6 @@ from nova import paths
|
||||
from nova import utils
|
||||
from nova.virt.libvirt import config as vconfig
|
||||
from nova.virt.libvirt import utils as libvirt_utils
|
||||
from nova.virt.libvirt.volume import remotefs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -56,15 +54,6 @@ volume_opts = [
|
||||
cfg.StrOpt('nfs_mount_options',
|
||||
help='Mount options passed to the NFS client. See section '
|
||||
'of the nfs man page for details'),
|
||||
cfg.StrOpt('smbfs_mount_point_base',
|
||||
default=paths.state_path_def('mnt'),
|
||||
help='Directory where the SMBFS shares are mounted on the '
|
||||
'compute node'),
|
||||
cfg.StrOpt('smbfs_mount_options',
|
||||
default='',
|
||||
help='Mount options passed to the SMBFS client. See '
|
||||
'mount.cifs man page for details. Note that the '
|
||||
'libvirt-qemu uid and gid must be specified.'),
|
||||
cfg.BoolOpt('iscsi_use_multipath',
|
||||
default=False,
|
||||
help='Use multipath connection of the iSCSI volume'),
|
||||
@ -417,67 +406,3 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver):
|
||||
LOG.warn(_LW("%s is already mounted"), nfs_share)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
class LibvirtSMBFSVolumeDriver(LibvirtBaseVolumeDriver):
|
||||
"""Class implements libvirt part of volume driver for SMBFS."""
|
||||
|
||||
def __init__(self, connection):
|
||||
super(LibvirtSMBFSVolumeDriver,
|
||||
self).__init__(connection, is_block_dev=False)
|
||||
self.username_regex = re.compile(
|
||||
r"(user(?:name)?)=(?:[^ ,]+\\)?([^ ,]+)")
|
||||
|
||||
def _get_device_path(self, connection_info):
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
volume_path = os.path.join(mount_path,
|
||||
connection_info['data']['name'])
|
||||
return volume_path
|
||||
|
||||
def _get_mount_path(self, smbfs_share):
|
||||
mount_path = os.path.join(CONF.libvirt.smbfs_mount_point_base,
|
||||
utils.get_hash_str(smbfs_share))
|
||||
return mount_path
|
||||
|
||||
def get_config(self, connection_info, disk_info):
|
||||
"""Returns xml for libvirt."""
|
||||
conf = super(LibvirtSMBFSVolumeDriver,
|
||||
self).get_config(connection_info, disk_info)
|
||||
|
||||
conf.source_type = 'file'
|
||||
conf.driver_cache = 'writethrough'
|
||||
conf.source_path = connection_info['data']['device_path']
|
||||
conf.driver_format = connection_info['data'].get('format', 'raw')
|
||||
return conf
|
||||
|
||||
def connect_volume(self, connection_info, disk_info):
|
||||
"""Connect the volume."""
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
|
||||
if not libvirt_utils.is_mounted(mount_path, smbfs_share):
|
||||
mount_options = self._parse_mount_options(connection_info)
|
||||
remotefs.mount_share(mount_path, smbfs_share,
|
||||
export_type='cifs', options=mount_options)
|
||||
|
||||
device_path = self._get_device_path(connection_info)
|
||||
connection_info['data']['device_path'] = device_path
|
||||
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
"""Disconnect the volume."""
|
||||
smbfs_share = connection_info['data']['export']
|
||||
mount_path = self._get_mount_path(smbfs_share)
|
||||
remotefs.unmount_share(mount_path, smbfs_share)
|
||||
|
||||
def _parse_mount_options(self, connection_info):
|
||||
mount_options = " ".join(
|
||||
[connection_info['data'].get('options') or '',
|
||||
CONF.libvirt.smbfs_mount_options])
|
||||
|
||||
if not self.username_regex.findall(mount_options):
|
||||
mount_options = mount_options + ' -o username=guest'
|
||||
else:
|
||||
# Remove the Domain Name from user name
|
||||
mount_options = self.username_regex.sub(r'\1=\2', mount_options)
|
||||
return mount_options.strip(", ").split(' ')
|
||||
|
Loading…
x
Reference in New Issue
Block a user