Merge "Make NFS exports in generic driver permanent"

This commit is contained in:
Jenkins 2014-09-05 17:18:43 +00:00 committed by Gerrit Code Review
commit b1a1ea8f61
3 changed files with 65 additions and 16 deletions

View File

@ -25,6 +25,9 @@ STATUS_DEACTIVATING = 'DEACTIVATING'
SECURITY_SERVICES_ALLOWED_TYPES = ['active_directory', 'ldap', 'kerberos']
NFS_EXPORTS_FILE = '/etc/exports'
NFS_EXPORTS_FILE_TEMP = '/var/lib/nfs/etab'
# Below represented ports are ranges (from, to)
CIFS_PORTS = (
("tcp", (445, 445)),

View File

@ -22,6 +22,7 @@ import time
from oslo.config import cfg
import six
from manila.common import constants as const
from manila import compute
from manila import context
from manila import exception
@ -614,6 +615,20 @@ class NASHelperBase(object):
raise NotImplementedError()
def nfs_synchronized(f):
def wrapped_func(self, *args, **kwargs):
key = "nfs-%s" % args[0]["instance_id"]
@utils.synchronized(key)
def source_func(self, *args, **kwargs):
return f(self, *args, **kwargs)
return source_func(self, *args, **kwargs)
return wrapped_func
class NFSHelper(NASHelperBase):
"""Interface to work with share."""
@ -637,6 +652,7 @@ class NFSHelper(NASHelperBase):
"""Remove export."""
pass
@nfs_synchronized
def allow_access(self, server, share_name, access_type, access):
"""Allow access to the host."""
local_path = os.path.join(self.configuration.share_mount_path,
@ -654,7 +670,9 @@ class NFSHelper(NASHelperBase):
self._ssh_exec(server,
['sudo', 'exportfs', '-o', 'rw,no_subtree_check',
':'.join([access, local_path])])
self._sync_nfs_temp_and_perm_files(server)
@nfs_synchronized
def deny_access(self, server, share_name, access_type, access,
force=False):
"""Deny access to the host."""
@ -662,6 +680,20 @@ class NFSHelper(NASHelperBase):
share_name)
self._ssh_exec(server, ['sudo', 'exportfs', '-u',
':'.join([access, local_path])])
self._sync_nfs_temp_and_perm_files(server)
def _sync_nfs_temp_and_perm_files(self, server):
"""Sync changes of exports with permanent NFS config file.
This is required to ensure, that after share server reboot, exports
still exist.
"""
sync_cmd = [
'sudo', 'cp ', const.NFS_EXPORTS_FILE_TEMP, const.NFS_EXPORTS_FILE,
'&&',
'sudo', 'exportfs', '-a',
]
self._ssh_exec(server, sync_cmd)
class CIFSHelper(NASHelperBase):

View File

@ -793,39 +793,53 @@ class NFSHelperTestCase(test.TestCase):
self._execute = mock.Mock(return_value=('', ''))
self._helper = generic.NFSHelper(self._execute, self._ssh_exec,
self.fake_conf)
ip = '10.254.0.3'
self.server = fake_compute.FakeServer(
ip=ip, public_address=ip, instance_id='fake_instance_id')
def test_create_export(self):
fake_server = fake_compute.FakeServer(public_address='10.254.0.3')
ret = self._helper.create_export(fake_server, 'volume-00001')
expected_location = ':'.join([fake_server['public_address'],
ret = self._helper.create_export(self.server, 'fake_share')
expected_location = ':'.join([self.server['public_address'],
os.path.join(CONF.share_mount_path,
'volume-00001')])
'fake_share')])
self.assertEqual(ret, expected_location)
def test_allow_access(self):
fake_server = fake_compute.FakeServer(ip='10.254.0.3')
self._helper.allow_access(fake_server, 'volume-00001',
self.stubs.Set(self._helper, '_sync_nfs_temp_and_perm_files',
mock.Mock())
self._helper.allow_access(self.server, 'fake_share',
'ip', '10.0.0.2')
local_path = os.path.join(CONF.share_mount_path, 'volume-00001')
local_path = os.path.join(CONF.share_mount_path, 'fake_share')
self._ssh_exec.assert_has_calls([
mock.call(fake_server, ['sudo', 'exportfs']),
mock.call(fake_server, ['sudo', 'exportfs', '-o',
mock.call(self.server, ['sudo', 'exportfs']),
mock.call(self.server, ['sudo', 'exportfs', '-o',
'rw,no_subtree_check',
':'.join(['10.0.0.2', local_path])])
])
self._helper._sync_nfs_temp_and_perm_files.assert_called_once_with(
self.server)
def test_allow_access_no_ip(self):
self.assertRaises(exception.InvalidShareAccess,
self._helper.allow_access, 'fake_server', 'share0',
'fake', 'fakerule')
self.assertRaises(
exception.InvalidShareAccess,
self._helper.allow_access,
self.server, 'fake_share', 'fake', 'fakerule',
)
def test_deny_access(self):
fake_server = fake_compute.FakeServer(ip='10.254.0.3')
local_path = os.path.join(CONF.share_mount_path, 'volume-00001')
self._helper.deny_access(fake_server, 'volume-00001', 'ip', '10.0.0.2')
self.stubs.Set(self._helper, '_sync_nfs_temp_and_perm_files',
mock.Mock())
local_path = os.path.join(CONF.share_mount_path, 'fake_share')
self._helper.deny_access(self.server, 'fake_share', 'ip', '10.0.0.2')
export_string = ':'.join(['10.0.0.2', local_path])
expected_exec = ['sudo', 'exportfs', '-u', export_string]
self._ssh_exec.assert_called_once_with(fake_server, expected_exec)
self._ssh_exec.assert_called_once_with(self.server, expected_exec)
self._helper._sync_nfs_temp_and_perm_files.assert_called_once_with(
self.server)
def test_sync_nfs_temp_and_perm_files(self):
self._helper._sync_nfs_temp_and_perm_files(self.server)
self._helper._ssh_exec.assert_called_once_with(self.server, mock.ANY)
class CIFSHelperTestCase(test.TestCase):