diff --git a/manila/share/drivers/hpe/hpe_3par_driver.py b/manila/share/drivers/hpe/hpe_3par_driver.py index e7a3c0f015..a5c5806cd4 100644 --- a/manila/share/drivers/hpe/hpe_3par_driver.py +++ b/manila/share/drivers/hpe/hpe_3par_driver.py @@ -123,10 +123,12 @@ class HPE3ParShareDriver(driver.ShareDriver): 2.0.1 - Add access_level (e.g. read-only support) 2.0.2 - Add extend/shrink 2.0.3 - Remove file tree on delete when using nested shares #1538800 + 2.0.4 - Reduce the fsquota by share size + when a share is deleted #1582931 """ - VERSION = "2.0.3" + VERSION = "2.0.4" def __init__(self, *args, **kwargs): super(HPE3ParShareDriver, self).__init__((True, False), @@ -353,6 +355,7 @@ class HPE3ParShareDriver(driver.ShareDriver): self._hpe3par.delete_share(share['project_id'], share['id'], + share['size'], share['share_proto'], self.fpg, self.vfs) diff --git a/manila/share/drivers/hpe/hpe_3par_mediator.py b/manila/share/drivers/hpe/hpe_3par_mediator.py index eb86e57173..ced619fb72 100644 --- a/manila/share/drivers/hpe/hpe_3par_mediator.py +++ b/manila/share/drivers/hpe/hpe_3par_mediator.py @@ -71,10 +71,12 @@ class HPE3ParMediator(object): 2.0.2 - Add extend/shrink 2.0.3 - Fix SMB read-only access (added in 2.0.1) 2.0.4 - Remove file tree on delete when using nested shares #1538800 + 2.0.5 - Reduce the fsquota by share size + when a share is deleted #1582931 """ - VERSION = "2.0.4" + VERSION = "2.0.5" def __init__(self, **kwargs): @@ -634,7 +636,8 @@ class HPE3ParMediator(object): LOG.exception(msg) raise exception.ShareBackendException(msg=msg) - def delete_share(self, project_id, share_id, share_proto, fpg, vfs): + def delete_share(self, project_id, share_id, share_size, share_proto, + fpg, vfs): protocol = self.ensure_supported_protocol(share_proto) share_name = self.ensure_prefix(share_id) @@ -665,6 +668,9 @@ class HPE3ParMediator(object): # not treat this as an error_deleting issue. We will allow the # delete to continue as requested. self._delete_file_tree(share_name, protocol, fpg, vfs, fstore) + if fstore: + # reduce the fsquota by share size when a share is deleted. + self._update_capacity_quotas(fstore, 0, share_size, fpg, vfs) if fstore == share_name: try: diff --git a/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py index 810eb9b4b6..f75b518919 100644 --- a/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py @@ -420,6 +420,7 @@ class HPE3ParDriverTestCase(test.TestCase): expected_calls = [ mock.call.delete_share(constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.CIFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS)] diff --git a/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py b/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py index 8203ab96b1..54cd563d5e 100644 --- a/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py @@ -611,9 +611,13 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mock_object(self.mediator, '_unmount_super_share', mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_update_capacity_quotas', + mock.Mock(return_value={})) self.mediator.delete_share(constants.EXPECTED_PROJECT_ID, share_id, + constants.EXPECTED_SIZE_1, constants.NFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -655,6 +659,9 @@ class HPE3ParMediatorTestCase(test.TestCase): expected_mount_path) self.mediator._unmount_super_share.assert_called_with( expected_mount_path) + self.mediator._update_capacity_quotas.assert_called_with( + fstore, 0, constants.EXPECTED_SIZE_1, + constants.EXPECTED_FPG, constants.EXPECTED_VFS) def test_mediator_delete_share_not_found(self): self.init_mediator() @@ -677,6 +684,7 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mediator.delete_share(constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.CIFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -717,6 +725,7 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mediator.delete_share(constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.NFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -750,6 +759,7 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mediator.delete_share, constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.CIFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -781,6 +791,9 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mock_object(self.mediator, '_unmount_super_share', mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_update_capacity_quotas', + mock.Mock(return_value={})) self.mock_client.removefstore.side_effect = Exception( 'removefstore fail.') @@ -788,6 +801,7 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mediator.delete_share, constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.CIFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -833,6 +847,9 @@ class HPE3ParMediatorTestCase(test.TestCase): expected_mount_path) self.mediator._unmount_super_share.assert_called_with( expected_mount_path) + self.mediator._update_capacity_quotas.assert_called_with( + constants.EXPECTED_SHARE_ID, 0, constants.EXPECTED_SIZE_1, + constants.EXPECTED_FPG, constants.EXPECTED_VFS) def test_mediator_delete_cifs_share(self): self.init_mediator() @@ -852,9 +869,13 @@ class HPE3ParMediatorTestCase(test.TestCase): self.mock_object(self.mediator, '_unmount_super_share', mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_update_capacity_quotas', + mock.Mock(return_value={})) self.mediator.delete_share(constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, constants.CIFS, constants.EXPECTED_FPG, constants.EXPECTED_VFS) @@ -900,6 +921,86 @@ class HPE3ParMediatorTestCase(test.TestCase): expected_mount_path) self.mediator._unmount_super_share.assert_called_with( expected_mount_path) + self.mediator._update_capacity_quotas.assert_called_with( + constants.EXPECTED_SHARE_ID, 0, constants.EXPECTED_SIZE_1, + constants.EXPECTED_FPG, constants.EXPECTED_VFS) + + def test_mediator_delete_share_with_fstore_per_share_false(self): + self.init_mediator() + self.mediator.hpe3par_fstore_per_share = False + share_size = int(constants.EXPECTED_SIZE_1) + fstore_init_size = int( + constants.GET_FSQUOTA['members'][0]['hardBlock']) + + expected_capacity = (0-share_size) * units.Ki + fstore_init_size + self.mock_object(self.mediator, + '_find_fstore', + mock.Mock(return_value=constants.EXPECTED_FSTORE)) + self.mock_object(self.mediator, + '_create_mount_directory', + mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_mount_super_share', + mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_delete_share_directory', + mock.Mock(return_value={})) + self.mock_object(self.mediator, + '_unmount_super_share', + mock.Mock(return_value={})) + + self.mediator.delete_share(constants.EXPECTED_PROJECT_ID, + constants.EXPECTED_SHARE_ID, + constants.EXPECTED_SIZE_1, + constants.CIFS, + constants.EXPECTED_FPG, + constants.EXPECTED_VFS) + + expected_calls = [ + mock.call.removefshare(constants.SMB_LOWER, + constants.EXPECTED_VFS, + constants.EXPECTED_SHARE_ID, + fpg=constants.EXPECTED_FPG, + fstore=constants.EXPECTED_FSTORE), + mock.call.createfshare(constants.SMB_LOWER, + constants.EXPECTED_VFS, + constants.EXPECTED_SUPER_SHARE, + allowip=None, + comment=( + constants.EXPECTED_SUPER_SHARE_COMMENT), + fpg=constants.EXPECTED_FPG, + fstore=constants.EXPECTED_FSTORE, + sharedir=''), + mock.call.setfshare(constants.SMB_LOWER, + constants.EXPECTED_VFS, + constants.EXPECTED_SUPER_SHARE, + comment=( + constants.EXPECTED_SUPER_SHARE_COMMENT), + allowperm=( + '+' + constants.USERNAME + ':fullcontrol'), + fpg=constants.EXPECTED_FPG, + fstore=constants.EXPECTED_FSTORE), + mock.call.getfsquota(fpg=constants.EXPECTED_FPG, + fstore=constants.EXPECTED_FSTORE, + vfs=constants.EXPECTED_VFS), + mock.call.setfsquota(constants.EXPECTED_VFS, + fpg=constants.EXPECTED_FPG, + fstore=constants.EXPECTED_FSTORE, + scapacity=six.text_type(expected_capacity), + hcapacity=six.text_type(expected_capacity))] + self.mock_client.assert_has_calls(expected_calls) + + expected_mount_path = constants.EXPECTED_MOUNT_PATH + ( + constants.EXPECTED_SHARE_ID) + self.mediator._create_mount_directory.assert_called_with( + expected_mount_path) + self.mediator._mount_super_share.assert_called_with( + constants.SMB_LOWER, expected_mount_path, constants.EXPECTED_FPG, + constants.EXPECTED_VFS, constants.EXPECTED_FSTORE) + self.mediator._delete_share_directory.assert_called_with( + expected_mount_path) + self.mediator._unmount_super_share.assert_called_with( + expected_mount_path) def test_mediator_create_snapshot(self): self.init_mediator() diff --git a/releasenotes/notes/bug_1582931-1437eae20fa544d1.yaml b/releasenotes/notes/bug_1582931-1437eae20fa544d1.yaml new file mode 100644 index 0000000000..d1b6caf5d2 --- /dev/null +++ b/releasenotes/notes/bug_1582931-1437eae20fa544d1.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - HPE3PAR Driver fix to reduce the fsquota when a share is deleted + for shared fstores. \ No newline at end of file