Merge "[ZFSonLinux] Fix share migration support"

This commit is contained in:
Jenkins 2016-09-10 15:47:07 +00:00 committed by Gerrit Code Review
commit 29c05e72f5
3 changed files with 80 additions and 14 deletions

View File

@ -141,7 +141,7 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then
# replication tests run faster. The default is 300, which is greater than
# the build timeout for ZFS on the gate.
echo "MANILA_REPLICA_STATE_UPDATE_INTERVAL=60" >> $localrc_path
echo "MANILA_ZFSONLINUX_USE_SSH=False" >> $localrc_path
echo "MANILA_ZFSONLINUX_USE_SSH=True" >> $localrc_path
elif [[ "$DRIVER" == "container" ]]; then
echo "SHARE_DRIVER=manila.share.drivers.container.driver.ContainerShareDriver" >> $localrc_path
echo "SHARE_BACKING_FILE_SIZE=32000M" >> $localrc_path

View File

@ -19,6 +19,7 @@ and exports them as shares.
"""
import math
import os
import time
from oslo_config import cfg
@ -1377,9 +1378,12 @@ class ZFSonLinuxShareDriver(zfs_utils.ExecuteMixin, driver.ShareDriver):
src_dataset_name = self.private_storage.get(
source_share['id'], 'dataset_name')
dst_dataset_name = self._get_dataset_name(destination_share)
ssh_cmd = '%(username)s@%(host)s' % {
'username': self.configuration.zfs_ssh_username,
'host': self.service_ip,
backend_name = share_utils.extract_host(
destination_share['host'], level='backend_name')
config = get_backend_configuration(backend_name)
remote_ssh_cmd = '%(username)s@%(host)s' % {
'username': config.zfs_ssh_username,
'host': config.zfs_service_ip,
}
snapshot_tag = self._get_migration_snapshot_tag(destination_share)
src_snapshot_name = (
@ -1396,7 +1400,7 @@ class ZFSonLinuxShareDriver(zfs_utils.ExecuteMixin, driver.ShareDriver):
self.private_storage.update(destination_share['id'], {
'entity_type': 'share',
'dataset_name': dst_dataset_name,
'ssh_cmd': ssh_cmd,
'ssh_cmd': remote_ssh_cmd,
'pool_name': share_utils.extract_host(
destination_share['host'], level='pool'),
'migr_snapshot_tag': snapshot_tag,
@ -1407,17 +1411,17 @@ class ZFSonLinuxShareDriver(zfs_utils.ExecuteMixin, driver.ShareDriver):
# Send/receive temporary snapshot
cmd = (
'nohup '
'sudo zfs send -vDR ' + src_snapshot_name + ' '
'| ssh ' + ssh_cmd + ' '
'sudo zfs receive -v ' + dst_dataset_name + ' '
'& exit 0'
'| ssh ' + remote_ssh_cmd + ' '
'sudo zfs receive -v ' + dst_dataset_name
)
# TODO(vponomaryov): following works only
# when config option zfs_use_ssh is set to "False". Because
# SSH coneector does not support that "shell=True" feature that is
# required in current situation.
self.execute(cmd, shell=True)
filename = dst_dataset_name.replace('/', '_')
with utils.tempdir() as tmpdir:
tmpfilename = os.path.join(tmpdir, '%s.sh' % filename)
with open(tmpfilename, "w") as migr_script:
migr_script.write(cmd)
self.execute('sudo', 'chmod', '755', tmpfilename)
self.execute('nohup', tmpfilename, '&')
@ensure_share_server_not_provided
def migration_continue(

View File

@ -15,6 +15,7 @@
import ddt
import mock
from oslo_config import cfg
from manila import context
@ -29,6 +30,7 @@ CONF = cfg.CONF
class FakeConfig(object):
def __init__(self, *args, **kwargs):
self.driver_handles_share_servers = False
self.share_driver = 'fake_share_driver_name'
self.share_backend_name = 'FAKE_BACKEND_NAME'
self.zfs_share_export_ip = kwargs.get(
"zfs_share_export_ip", "1.1.1.1")
@ -2044,3 +2046,63 @@ class ZFSonLinuxShareDriverTestCase(test.TestCase):
self.assertIn('id', result)
self.assertEqual(expected_status, result['status'])
self.assertEqual(snapshot_instance['id'], result['id'])
def test_migration_start(self):
src_share = {
'id': 'fake_src_share_id',
'host': 'foohost@foobackend#foopool',
}
src_dataset_name = 'foo_dataset_name'
dst_share = {
'id': 'fake_dst_share_id',
'host': 'barhost@barbackend#barpool',
}
dst_dataset_name = 'bar_dataset_name'
snapshot_tag = 'fake_migration_snapshot_tag'
self.mock_object(
self.driver,
'_get_dataset_name',
mock.Mock(return_value=dst_dataset_name))
self.mock_object(
self.driver,
'_get_migration_snapshot_tag',
mock.Mock(return_value=snapshot_tag))
self.mock_object(
zfs_driver,
'get_backend_configuration',
mock.Mock(return_value=type(
'FakeConfig', (object,), {
'zfs_ssh_username': (
self.driver.configuration.zfs_ssh_username),
'zfs_service_ip': self.driver.configuration.zfs_service_ip,
})))
self.mock_object(self.driver, 'execute')
self.driver.private_storage.update(
src_share['id'], {'dataset_name': src_dataset_name})
self.driver.migration_start(
self._context, src_share, dst_share)
src_snapshot_name = (
'%(dataset_name)s@%(snapshot_tag)s' % {
'snapshot_tag': snapshot_tag,
'dataset_name': src_dataset_name,
}
)
self.driver.execute.assert_has_calls([
mock.call('sudo', 'zfs', 'snapshot', src_snapshot_name),
mock.call('sudo', 'chmod', '755', mock.ANY),
mock.call('nohup', mock.ANY, '&'),
])
self.driver._get_migration_snapshot_tag.assert_called_once_with(
dst_share)
self.driver._get_dataset_name.assert_called_once_with(
dst_share)
for k, v in (('dataset_name', dst_dataset_name),
('migr_snapshot_tag', snapshot_tag),
('pool_name', 'barpool'),
('ssh_cmd',
self.driver.configuration.zfs_ssh_username + '@' +
self.driver.configuration.zfs_service_ip)):
self.assertEqual(
v, self.driver.private_storage.get(dst_share['id'], k))