Merge "Fix get_stats to return real used space in HNAS"
This commit is contained in:
commit
cc66f22781
@ -48,24 +48,26 @@ class HNASSSHBackend(object):
|
|||||||
def get_stats(self):
|
def get_stats(self):
|
||||||
"""Get the stats from file-system.
|
"""Get the stats from file-system.
|
||||||
|
|
||||||
The available space is calculated by total space - SUM(quotas).
|
|
||||||
:returns:
|
:returns:
|
||||||
total_fs_space = Total size from filesystem in config file.
|
fs_capacity.size = Total size from filesystem.
|
||||||
available_space = Free space currently on filesystem.
|
available_space = Free space currently on filesystem.
|
||||||
"""
|
"""
|
||||||
total_fs_space = self._get_filesystem_capacity()
|
command = ['df', '-a', '-f', self.fs_name]
|
||||||
total_quota = 0
|
output, err = self._execute(command)
|
||||||
share_list = self._get_vvol_list()
|
|
||||||
|
|
||||||
for item in share_list:
|
line = output.split('\n')
|
||||||
share_quota = self._get_share_quota(item)
|
fs_capacity = Capacity(line[3])
|
||||||
if share_quota is not None:
|
|
||||||
total_quota += share_quota
|
available_space = fs_capacity.size - fs_capacity.used
|
||||||
available_space = total_fs_space - total_quota
|
|
||||||
LOG.debug("Available space in the file system: %(space)s.",
|
LOG.debug("Total space in file system: %(total)s GB.",
|
||||||
|
{'total': fs_capacity.size})
|
||||||
|
LOG.debug("Used space in the file system: %(used)s GB.",
|
||||||
|
{'used': fs_capacity.used})
|
||||||
|
LOG.debug("Available space in the file system: %(space)s GB.",
|
||||||
{'space': available_space})
|
{'space': available_space})
|
||||||
|
|
||||||
return total_fs_space, available_space
|
return fs_capacity.size, available_space
|
||||||
|
|
||||||
def allow_access(self, share_id, host, share_proto, permission='rw'):
|
def allow_access(self, share_id, host, share_proto, permission='rw'):
|
||||||
"""Allow access to the share.
|
"""Allow access to the share.
|
||||||
@ -674,38 +676,6 @@ class HNASSSHBackend(object):
|
|||||||
# Returns None if the quota is unset
|
# Returns None if the quota is unset
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_vvol_list(self):
|
|
||||||
command = ['virtual-volume', 'list', self.fs_name]
|
|
||||||
output, err = self._execute(command)
|
|
||||||
|
|
||||||
vvol_list = []
|
|
||||||
items = output.split('\n')
|
|
||||||
|
|
||||||
for i in range(0, len(items) - 1):
|
|
||||||
if ":" not in items[i]:
|
|
||||||
vvol_list.append(items[i])
|
|
||||||
|
|
||||||
return vvol_list
|
|
||||||
|
|
||||||
def _get_filesystem_capacity(self):
|
|
||||||
command = ['filesystem-limits', self.fs_name]
|
|
||||||
output, err = self._execute(command)
|
|
||||||
|
|
||||||
items = output.split('\n')
|
|
||||||
|
|
||||||
for i in range(0, len(items) - 1):
|
|
||||||
if 'Current capacity' in items[i]:
|
|
||||||
fs_capacity = items[i].split(' ')
|
|
||||||
|
|
||||||
# Gets the index of the file system capacity (EX: 20GiB)
|
|
||||||
index = [i for i, string in enumerate(fs_capacity)
|
|
||||||
if 'GiB' in string]
|
|
||||||
|
|
||||||
fs_capacity = fs_capacity[index[0]]
|
|
||||||
fs_capacity = fs_capacity.split('GiB')[0]
|
|
||||||
|
|
||||||
return int(fs_capacity)
|
|
||||||
|
|
||||||
@mutils.synchronized("hds_hnas_select_fs", external=True)
|
@mutils.synchronized("hds_hnas_select_fs", external=True)
|
||||||
def _locked_selectfs(self, op, path):
|
def _locked_selectfs(self, op, path):
|
||||||
if op == 'create':
|
if op == 'create':
|
||||||
@ -827,3 +797,20 @@ class JobSubmit(object):
|
|||||||
|
|
||||||
self.request_status = " ".join(split_data[1:4])
|
self.request_status = " ".join(split_data[1:4])
|
||||||
self.job_id = split_data[8]
|
self.job_id = split_data[8]
|
||||||
|
|
||||||
|
|
||||||
|
class Capacity(object):
|
||||||
|
def __init__(self, data):
|
||||||
|
if data:
|
||||||
|
items = data.split()
|
||||||
|
self.id = items[0]
|
||||||
|
self.label = items[1]
|
||||||
|
self.evs = items[2]
|
||||||
|
self.size = float(items[3])
|
||||||
|
self.size_measure = items[4]
|
||||||
|
if self.size_measure == 'TB':
|
||||||
|
self.size = self.size * units.Ki
|
||||||
|
self.used = float(items[5])
|
||||||
|
self.used_measure = items[6]
|
||||||
|
if self.used_measure == 'TB':
|
||||||
|
self.used = self.used * units.Ki
|
||||||
|
@ -381,6 +381,24 @@ HNAS_RESULT_job_running = """JOB ID : ab4211b8-aac8-11ce-91af-39e0822ea368
|
|||||||
block special devices, 25 character devices
|
block special devices, 25 character devices
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
HNAS_RESULT_df = """
|
||||||
|
ID Label EVS Size Used Snapshots Deduped \
|
||||||
|
Avail Thin ThinSize ThinAvail FS Type
|
||||||
|
---- ------------- --- -------- -------------- --------- ------- \
|
||||||
|
------------- ---- -------- --------- -------------------
|
||||||
|
1051 FS-ManilaDev1 3 70.00 GB 10.00 GB (75%) 0 B (0%) NA \
|
||||||
|
18.3 GB (25%) No 4 KB,WFS-2,128 DSBs
|
||||||
|
"""
|
||||||
|
|
||||||
|
HNAS_RESULT_df_tb = """
|
||||||
|
ID Label EVS Size Used Snapshots Deduped \
|
||||||
|
Avail Thin ThinSize ThinAvail FS Type
|
||||||
|
---- ------------- --- -------- -------------- --------- ------- \
|
||||||
|
------------- ---- -------- --------- -------------------
|
||||||
|
1051 FS-ManilaDev1 3.00 7.00 TB 2 TB (75%) 0 B (0%) NA \
|
||||||
|
18.3 GB (25%) No 4 KB,WFS-2,128 DSBs
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class HNASSSHTestCase(test.TestCase):
|
class HNASSSHTestCase(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -422,37 +440,44 @@ class HNASSSHTestCase(test.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def test_get_stats(self):
|
def test_get_stats(self):
|
||||||
fake_list_command = ['quota', 'list', 'file_system', 'vol3']
|
fake_list_command = ['df', '-a', '-f', 'file_system']
|
||||||
|
expected_debug_calls = [
|
||||||
|
('Total space in file system: %(total)s GB.', {'total': 7168.0}),
|
||||||
|
('Used space in the file system: %(used)s GB.', {'used': 2048.0}),
|
||||||
|
('Available space in the file system: %(space)s GB.',
|
||||||
|
{'space': 5120.0})
|
||||||
|
]
|
||||||
|
|
||||||
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
||||||
mock.Mock(side_effect=[(HNAS_RESULT_fslimits, ""),
|
mock.Mock(return_value=(HNAS_RESULT_df_tb, "")))
|
||||||
(HNAS_RESULT_vvol_list, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_vvol_list, "")]))
|
|
||||||
|
|
||||||
total, free = self._driver.get_stats()
|
total, free = self._driver.get_stats()
|
||||||
|
|
||||||
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
||||||
self.assertTrue(self.mock_log.debug.called)
|
self.mock_log.debug.assert_has_calls([mock.call(*a) for a in
|
||||||
self.assertEqual(100, total)
|
expected_debug_calls])
|
||||||
self.assertEqual(85, free)
|
self.assertEqual(7168.0, total)
|
||||||
|
self.assertEqual(5120.0, free)
|
||||||
|
|
||||||
def test_get_stats_terabytes(self):
|
def test_get_stats_terabytes(self):
|
||||||
fake_list_command = ['quota', 'list', 'file_system', 'vol3']
|
fake_list_command = ['df', '-a', '-f', 'file_system']
|
||||||
|
expected_debug_calls = [
|
||||||
|
('Total space in file system: %(total)s GB.', {'total': 7168.0}),
|
||||||
|
('Used space in the file system: %(used)s GB.', {'used': 2048.0}),
|
||||||
|
('Available space in the file system: %(space)s GB.',
|
||||||
|
{'space': 5120.0})
|
||||||
|
]
|
||||||
|
|
||||||
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
||||||
mock.Mock(side_effect=[(HNAS_RESULT_fslimits_tb, ""),
|
mock.Mock(return_value=(HNAS_RESULT_df_tb, "")))
|
||||||
(HNAS_RESULT_vvol_list, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_quota_tb, ""),
|
|
||||||
(HNAS_RESULT_quota, "")]))
|
|
||||||
|
|
||||||
total, free = self._driver.get_stats()
|
total, free = self._driver.get_stats()
|
||||||
|
|
||||||
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
||||||
self.assertTrue(self.mock_log.debug.called)
|
self.mock_log.debug.assert_has_calls([mock.call(*a) for a in
|
||||||
self.assertEqual(1500, total)
|
expected_debug_calls])
|
||||||
self.assertEqual(466, free)
|
self.assertEqual(7168.0, total)
|
||||||
|
self.assertEqual(5120.0, free)
|
||||||
|
|
||||||
def test_allow_access(self):
|
def test_allow_access(self):
|
||||||
fake_mod_command = ['nfs-export', 'mod', '-c',
|
fake_mod_command = ['nfs-export', 'mod', '-c',
|
||||||
@ -836,9 +861,7 @@ class HNASSSHTestCase(test.TestCase):
|
|||||||
(HNAS_RESULT_vvol, ""),
|
(HNAS_RESULT_vvol, ""),
|
||||||
(HNAS_RESULT_quota, ""),
|
(HNAS_RESULT_quota, ""),
|
||||||
(HNAS_RESULT_export, ""),
|
(HNAS_RESULT_export, ""),
|
||||||
(HNAS_RESULT_fslimits, ""),
|
(HNAS_RESULT_df, ""),
|
||||||
(HNAS_RESULT_vvol, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_empty, "")]))
|
(HNAS_RESULT_empty, "")]))
|
||||||
|
|
||||||
self._driver.extend_share(self.vvol['id'],
|
self._driver.extend_share(self.vvol['id'],
|
||||||
@ -850,18 +873,14 @@ class HNASSSHTestCase(test.TestCase):
|
|||||||
ssh.HNASSSHBackend._execute.assert_called_with(fake_quota_mod_command)
|
ssh.HNASSSHBackend._execute.assert_called_with(fake_quota_mod_command)
|
||||||
|
|
||||||
def test_extend_share_no_space(self):
|
def test_extend_share_no_space(self):
|
||||||
fake_list_command = ['quota', 'list', 'file_system', 'vol3']
|
fake_list_command = ['df', '-a', '-f', 'file_system']
|
||||||
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
self.mock_object(ssh.HNASSSHBackend, '_execute',
|
||||||
mock.Mock(side_effect=[(HNAS_RESULT_fs, ""),
|
mock.Mock(side_effect=[(HNAS_RESULT_fs, ""),
|
||||||
(HNAS_RESULT_fs, ""),
|
(HNAS_RESULT_fs, ""),
|
||||||
(HNAS_RESULT_vvol, ""),
|
(HNAS_RESULT_vvol, ""),
|
||||||
(HNAS_RESULT_quota, ""),
|
(HNAS_RESULT_quota, ""),
|
||||||
(HNAS_RESULT_export, ""),
|
(HNAS_RESULT_export, ""),
|
||||||
(HNAS_RESULT_fslimits, ""),
|
(HNAS_RESULT_df, "")]))
|
||||||
(HNAS_RESULT_vvol_list, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_quota, ""),
|
|
||||||
(HNAS_RESULT_quota, "")]))
|
|
||||||
|
|
||||||
# Tests when try to create a share bigger than available free space
|
# Tests when try to create a share bigger than available free space
|
||||||
self.assertRaises(exception.HNASBackendException,
|
self.assertRaises(exception.HNASBackendException,
|
||||||
@ -879,13 +898,13 @@ class HNASSSHTestCase(test.TestCase):
|
|||||||
(HNAS_RESULT_vvol, ""),
|
(HNAS_RESULT_vvol, ""),
|
||||||
(HNAS_RESULT_quota, ""),
|
(HNAS_RESULT_quota, ""),
|
||||||
(HNAS_RESULT_export, ""),
|
(HNAS_RESULT_export, ""),
|
||||||
(HNAS_RESULT_quota, "")]))
|
(HNAS_RESULT_quota_tb, "")]))
|
||||||
|
|
||||||
output = self._driver.manage_existing(self.vvol, self.vvol['id'])
|
output = self._driver.manage_existing(self.vvol, self.vvol['id'])
|
||||||
|
|
||||||
self.assertEqual({'export_locations':
|
self.assertEqual({'export_locations':
|
||||||
['172.24.44.1:/shares/vvol_test'],
|
['172.24.44.1:/shares/vvol_test'],
|
||||||
'size': 5.0}, output)
|
'size': 1024.0}, output)
|
||||||
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
|
||||||
|
|
||||||
def test_manage_existing_share_without_size(self):
|
def test_manage_existing_share_without_size(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user