Merge "Hitachi HNAS driver share shrink"
This commit is contained in:
commit
e5f4e981f5
@ -47,7 +47,7 @@ Mapping of share drivers and share features support
|
||||
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
|
||||
| HDFS | DHSS = False (K) | \- | M | \- | K | K |
|
||||
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
|
||||
| Hitachi HNAS | DHSS = False (L) | L | L | \- | L | L |
|
||||
| Hitachi HNAS | DHSS = False (L) | L | L | M | L | L |
|
||||
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
|
||||
| HPE 3PAR | DHSS = True (L) & False (K) | \- | \- | \- | K | K |
|
||||
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
|
||||
|
@ -424,6 +424,25 @@ class HDSHNASDriver(driver.ShareDriver):
|
||||
{'shr_path': share['export_locations'][0]['path'],
|
||||
'shr_id': share['id']})
|
||||
|
||||
def shrink_share(self, share, new_size, share_server=None):
|
||||
"""Shrinks a share to new size.
|
||||
|
||||
:param share: Share that will be shrunk.
|
||||
:param new_size: New size of share.
|
||||
:param share_server: Data structure with share server information.
|
||||
Not used by this driver.
|
||||
"""
|
||||
share_id = self._get_hnas_share_id(share['id'])
|
||||
|
||||
LOG.debug("Shrinking share in HNAS: %(shr_id)s.",
|
||||
{'shr_id': share['id']})
|
||||
|
||||
self._shrink_share(share_id, share['size'], new_size)
|
||||
LOG.info(_LI("Share %(shr_id)s successfully shrunk to "
|
||||
"%(shr_size)sG."),
|
||||
{'shr_id': share['id'],
|
||||
'shr_size': six.text_type(new_size)})
|
||||
|
||||
def _get_hnas_share_id(self, share_id):
|
||||
hnas_id = self.private_storage.get(share_id, 'hnas_id')
|
||||
|
||||
@ -549,6 +568,25 @@ class HDSHNASDriver(driver.ShareDriver):
|
||||
self.hnas.check_export(share_id)
|
||||
return path
|
||||
|
||||
def _shrink_share(self, share_id, old_size, new_size):
|
||||
"""Shrinks a share to new size.
|
||||
|
||||
:param share_id: ID of share that will be shrunk.
|
||||
:param old_size: Current size of share that will be shrunk.
|
||||
:param new_size: New size of share after shrink operation.
|
||||
"""
|
||||
self._ensure_share(share_id)
|
||||
|
||||
usage = self.hnas.get_share_usage(share_id)
|
||||
|
||||
LOG.debug("Usage space in share %(share)s: %(usage)sG",
|
||||
{'share': share_id, 'usage': usage})
|
||||
|
||||
if new_size > usage:
|
||||
self.hnas.modify_quota(share_id, new_size)
|
||||
else:
|
||||
raise exception.ShareShrinkingPossibleDataLoss(share_id=share_id)
|
||||
|
||||
def _extend_share(self, share_id, old_size, new_size):
|
||||
"""Extends a share to new size.
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_log import log
|
||||
from oslo_utils import strutils
|
||||
from oslo_utils import units
|
||||
import paramiko
|
||||
import six
|
||||
@ -297,6 +298,20 @@ class HNASSSHBackend(object):
|
||||
"below 1G.") % share_id)
|
||||
raise exception.HNASBackendException(msg=msg)
|
||||
|
||||
def get_share_usage(self, share_id):
|
||||
command = ['quota', 'list', self.fs_name, share_id]
|
||||
output, err = self._execute(command)
|
||||
|
||||
quota = Quota(output)
|
||||
|
||||
if quota.usage is None:
|
||||
msg = (_("Virtual volume %s does not have any quota.") % share_id)
|
||||
raise exception.HNASItemNotFoundException(msg=msg)
|
||||
else:
|
||||
bytes_usage = strutils.string_to_bytes(six.text_type(quota.usage) +
|
||||
quota.usage_unit)
|
||||
return bytes_usage / units.Gi
|
||||
|
||||
def _get_share_export(self, share_id):
|
||||
share_id = '/shares/' + share_id
|
||||
command = ['nfs-export', 'list ', share_id]
|
||||
|
@ -379,6 +379,31 @@ class HDSHNASTestCase(test.TestCase):
|
||||
ssh.HNASSSHBackend.check_quota.assert_called_once_with(share['id'])
|
||||
ssh.HNASSSHBackend.check_export.assert_called_once_with(share['id'])
|
||||
|
||||
def test_shrink_share(self):
|
||||
self.mock_object(hds_hnas.HDSHNASDriver, "_get_hnas_share_id",
|
||||
mock.Mock(return_value=share['id']))
|
||||
self.mock_object(hds_hnas.HDSHNASDriver, "_ensure_share", mock.Mock())
|
||||
self.mock_object(ssh.HNASSSHBackend, "get_share_usage", mock.Mock(
|
||||
return_value=10))
|
||||
self.mock_object(ssh.HNASSSHBackend, "modify_quota", mock.Mock())
|
||||
|
||||
self._driver.shrink_share(share, 11)
|
||||
|
||||
ssh.HNASSSHBackend.get_share_usage.assert_called_once_with(share['id'])
|
||||
ssh.HNASSSHBackend.modify_quota.assert_called_once_with(share['id'],
|
||||
11)
|
||||
|
||||
def test_shrink_share_new_size_lower_than_usage(self):
|
||||
self.mock_object(hds_hnas.HDSHNASDriver, "_get_hnas_share_id",
|
||||
mock.Mock(return_value=share['id']))
|
||||
self.mock_object(hds_hnas.HDSHNASDriver, "_ensure_share", mock.Mock())
|
||||
self.mock_object(ssh.HNASSSHBackend, "get_share_usage", mock.Mock(
|
||||
return_value=10))
|
||||
|
||||
self.assertRaises(exception.ShareShrinkingPossibleDataLoss,
|
||||
self._driver.shrink_share, share, 9)
|
||||
ssh.HNASSSHBackend.get_share_usage.assert_called_once_with(share['id'])
|
||||
|
||||
def test_extend_share(self):
|
||||
self.mock_object(hds_hnas.HDSHNASDriver, "_get_hnas_share_id",
|
||||
mock.Mock(return_value=share['id']))
|
||||
|
@ -96,7 +96,7 @@ File system fake_fs successfully mounted."""
|
||||
|
||||
HNAS_RESULT_quota = """Type : Explicit
|
||||
Target : ViVol: vvol_test
|
||||
Usage : 0 B
|
||||
Usage : 1 GB
|
||||
Limit : 5 GB (Hard)
|
||||
Warning : Unset
|
||||
Critical : Unset
|
||||
@ -112,7 +112,7 @@ Last modified : 2015-06-23 22:37:17.363660800+00:00 """
|
||||
|
||||
HNAS_RESULT_quota_tb = """Type : Explicit
|
||||
Target : ViVol: vvol_test
|
||||
Usage : 0 B
|
||||
Usage : 1 TB
|
||||
Limit : 1 TB (Hard)
|
||||
Warning : Unset
|
||||
Critical : Unset
|
||||
@ -128,7 +128,7 @@ Last modified : 2015-06-23 22:37:17.363660800+00:00 """
|
||||
|
||||
HNAS_RESULT_quota_mb = """Type : Explicit
|
||||
Target : ViVol: vvol_test
|
||||
Usage : 0 B
|
||||
Usage : 20 MB
|
||||
Limit : 500 MB (Hard)
|
||||
Warning : Unset
|
||||
Critical : Unset
|
||||
@ -797,6 +797,32 @@ class HNASSSHTestCase(test.TestCase):
|
||||
self.assertRaises(exception.HNASBackendException,
|
||||
self._driver_ssh.get_share_quota, "vvol_test")
|
||||
|
||||
def test_get_share_usage(self):
|
||||
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
|
||||
return_value=(HNAS_RESULT_quota, '')))
|
||||
|
||||
self.assertEqual(1, self._driver_ssh.get_share_usage("vvol_test"))
|
||||
|
||||
def test_get_share_usage_error(self):
|
||||
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
|
||||
return_value=(HNAS_RESULT_quota_err, '')))
|
||||
|
||||
self.assertRaises(exception.HNASItemNotFoundException,
|
||||
self._driver_ssh.get_share_usage, "vvol_test")
|
||||
|
||||
def test_get_share_usage_mb(self):
|
||||
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
|
||||
return_value=(HNAS_RESULT_quota_mb, '')))
|
||||
|
||||
self.assertEqual(0.01953125, self._driver_ssh.get_share_usage(
|
||||
"vvol_test"))
|
||||
|
||||
def test_get_share_usage_tb(self):
|
||||
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
|
||||
return_value=(HNAS_RESULT_quota_tb, '')))
|
||||
|
||||
self.assertEqual(1024, self._driver_ssh.get_share_usage("vvol_test"))
|
||||
|
||||
def test__get_share_export(self):
|
||||
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
||||
mock.Mock(return_value=[HNAS_RESULT_export_ip, '']))
|
||||
|
Loading…
Reference in New Issue
Block a user