Merge "NetApp: Refresh directory before waiting"
This commit is contained in:
commit
987476cdd5
@ -16,6 +16,9 @@
|
||||
Mock unit tests for the NetApp cmode nfs storage driver
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from os_brick.remotefs import remotefs as remotefs_brick
|
||||
@ -839,23 +842,35 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
def test__copy_from_img_service_qcow2_copyoffload_workflow_success(
|
||||
self, mock_exists, mock_qemu_img_info, mock_cvrt_image):
|
||||
drv = self.driver
|
||||
cinder_mount_point_base = '/opt/stack/data/cinder/mnt/'
|
||||
# To get the cinder mount point directory, we use:
|
||||
mount_dir = hashlib.md5(
|
||||
'203.0.113.122:/cinder-flexvol1'.encode('utf-8')).hexdigest()
|
||||
cinder_mount_point = cinder_mount_point_base + mount_dir
|
||||
destination_copied_file = (
|
||||
'/cinder-flexvol1/a155308c-0290-497b-b278-4cdd01de0253'
|
||||
)
|
||||
volume = {'id': 'vol_id', 'name': 'name', 'size': 1}
|
||||
image_id = 'image_id'
|
||||
context = object()
|
||||
image_service = mock.Mock()
|
||||
image_service.get_location.return_value = ('nfs://ip1/openstack/img',
|
||||
None)
|
||||
image_service.get_location.return_value = (
|
||||
'nfs://203.0.113.122/glance-flexvol1', None)
|
||||
image_service.show.return_value = {'size': 1,
|
||||
'disk_format': 'qcow2'}
|
||||
drv._check_get_nfs_path_segs =\
|
||||
mock.Mock(return_value=('ip1', '/openstack'))
|
||||
drv._check_get_nfs_path_segs = (
|
||||
mock.Mock(return_value=('203.0.113.122', '/openstack'))
|
||||
)
|
||||
|
||||
drv._get_ip_verify_on_cluster = mock.Mock(return_value='ip1')
|
||||
drv._get_host_ip = mock.Mock(return_value='ip2')
|
||||
drv._get_export_path = mock.Mock(return_value='/exp_path')
|
||||
drv._get_ip_verify_on_cluster = mock.Mock(return_value='203.0.113.122')
|
||||
drv._get_host_ip = mock.Mock(return_value='203.0.113.122')
|
||||
drv._get_export_path = mock.Mock(
|
||||
return_value='/cinder-flexvol1')
|
||||
drv._get_provider_location = mock.Mock(return_value='share')
|
||||
drv._execute = mock.Mock()
|
||||
drv._get_mount_point_for_share = mock.Mock(return_value='mnt_point')
|
||||
drv._execute_as_root = False
|
||||
drv._get_mount_point_for_share = mock.Mock(
|
||||
return_value=cinder_mount_point)
|
||||
img_inf = mock.Mock()
|
||||
img_inf.file_format = 'raw'
|
||||
mock_qemu_img_info.return_value = img_inf
|
||||
@ -865,17 +880,33 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
|
||||
drv._delete_file_at_path = mock.Mock()
|
||||
drv._clone_file_dst_exists = mock.Mock()
|
||||
drv._post_clone_image = mock.Mock()
|
||||
self.mock_object(uuid, 'uuid4', mock.Mock(
|
||||
return_value='a155308c-0290-497b-b278-4cdd01de0253'))
|
||||
|
||||
retval = drv._copy_from_img_service(
|
||||
context, volume, image_service, image_id)
|
||||
|
||||
self.assertIsNone(retval)
|
||||
drv._get_ip_verify_on_cluster.assert_any_call('ip1')
|
||||
drv._get_ip_verify_on_cluster.assert_any_call('203.0.113.122')
|
||||
drv._get_export_path.assert_called_with('vol_id')
|
||||
drv._check_share_can_hold_size.assert_called_with('share', 1)
|
||||
drv._post_clone_image.assert_called_with(volume)
|
||||
self.assertEqual(1, mock_cvrt_image.call_count)
|
||||
self.assertEqual(1, drv._execute.call_count)
|
||||
|
||||
# _execute must be called once for copy-offload and again to touch
|
||||
# the top directory to refresh cache
|
||||
drv._execute.assert_has_calls(
|
||||
[
|
||||
mock.call(
|
||||
'copyoffload_tool_path', '203.0.113.122',
|
||||
'203.0.113.122', '/openstack/glance-flexvol1',
|
||||
destination_copied_file, run_as_root=False,
|
||||
check_exit_code=0
|
||||
),
|
||||
mock.call('touch', cinder_mount_point, run_as_root=False)
|
||||
]
|
||||
)
|
||||
self.assertEqual(2, drv._execute.call_count)
|
||||
self.assertEqual(2, drv._delete_file_at_path.call_count)
|
||||
self.assertEqual(1, drv._clone_file_dst_exists.call_count)
|
||||
|
||||
|
@ -653,6 +653,15 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
else:
|
||||
return False
|
||||
|
||||
@utils.trace_method
|
||||
def _touch_path_to_refresh(self, path):
|
||||
try:
|
||||
# Touching parent directory forces NFS client to flush its cache.
|
||||
self._execute('touch', path, run_as_root=self._execute_as_root)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception("Failed to touch path %s.", path)
|
||||
|
||||
@utils.trace_method
|
||||
def _discover_file_till_timeout(self, path, timeout=75):
|
||||
"""Checks if file size at path is equal to size."""
|
||||
# Sometimes nfs takes time to discover file
|
||||
@ -664,6 +673,9 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
# retries to ensure that this cache has refreshed.
|
||||
retry_seconds = timeout
|
||||
sleep_interval = 2
|
||||
base_path = os.path.dirname(path)
|
||||
self._touch_path_to_refresh(base_path)
|
||||
|
||||
while True:
|
||||
if os.path.exists(path):
|
||||
return True
|
||||
@ -674,6 +686,7 @@ class NetAppNfsDriver(driver.ManageableVD,
|
||||
else:
|
||||
time.sleep(sleep_interval)
|
||||
retry_seconds -= sleep_interval
|
||||
self._touch_path_to_refresh(base_path)
|
||||
|
||||
def _is_cloneable_share(self, image_location):
|
||||
"""Finds if the image at location is cloneable."""
|
||||
|
@ -122,8 +122,9 @@ rm: CommandFilter, rm, root
|
||||
# cinder/volume/drivers/remotefs.py
|
||||
mkdir: CommandFilter, mkdir, root
|
||||
|
||||
# cinder/volume/drivers/netapp/nfs.py:
|
||||
# cinder/volume/drivers/netapp/dataontap/nfs_base.py:
|
||||
netapp_nfs_find: RegExpFilter, find, root, find, ^[/]*([^/\0]+(/+)?)*$, -maxdepth, \d+, -name, img-cache.*, -amin, \+\d+
|
||||
netapp_nfs_touch: CommandFilter, touch, root
|
||||
|
||||
# cinder/volume/drivers/glusterfs.py
|
||||
chgrp: CommandFilter, chgrp, root
|
||||
|
Loading…
Reference in New Issue
Block a user