summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pylintrc2
-rw-r--r--cinder/backup/drivers/ceph.py1
-rw-r--r--cinder/tests/unit/api/v2/test_snapshots.py2
-rw-r--r--cinder/tests/unit/backup/drivers/test_backup_ceph.py29
-rw-r--r--cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py5
-rw-r--r--cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py4
-rw-r--r--cinder/tests/unit/volume/drivers/test_rbd.py45
-rw-r--r--cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py4
-rw-r--r--cinder/volume/drivers/rbd.py7
-rw-r--r--cinder/volume/targets/driver.py8
-rw-r--r--releasenotes/notes/hitachi-vsp-add-hostgroup-name-format-option-4c8e4a5ddd69b9bd.yaml26
-rw-r--r--releasenotes/notes/rbd-total_capacity-60f10b45e3a8c8ea.yaml8
12 files changed, 96 insertions, 45 deletions
diff --git a/.pylintrc b/.pylintrc
index 502fea6d4..db9ade98b 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -224,7 +224,7 @@ additional-builtins=_
[TYPECHECK]
# List of module names for which member attributes should not be checked
ignored-modules=six.moves,_MovedItems,alembic.context,alembic.op,
- alembic.config,pyxcli,storpool,oslo_privsep.capabilities
+ alembic.config,pyxcli,storpool,oslo_privsep.capabilities,nvmet
signature-mutators=unittest.mock.patch,unittest.mock.patch.object,sqlalchemy.util._preloaded.dependencies
# This is for cinder.objects.*, and requests.packages.*, but due to
diff --git a/cinder/backup/drivers/ceph.py b/cinder/backup/drivers/ceph.py
index d21e458bf..0e329bd88 100644
--- a/cinder/backup/drivers/ceph.py
+++ b/cinder/backup/drivers/ceph.py
@@ -350,7 +350,6 @@ class CephBackupDriver(driver.BackupDriver):
Incremental backups use a new base name so we support old and new style
format.
"""
- # Ensure no unicode
if not backup:
return "volume-%s.backup.base" % volume_id
diff --git a/cinder/tests/unit/api/v2/test_snapshots.py b/cinder/tests/unit/api/v2/test_snapshots.py
index ce58abb40..d85ae2d33 100644
--- a/cinder/tests/unit/api/v2/test_snapshots.py
+++ b/cinder/tests/unit/api/v2/test_snapshots.py
@@ -528,7 +528,7 @@ class SnapshotApiTest(test.TestCase):
@mock.patch.object(db, 'snapshot_get_all_by_project')
@mock.patch('cinder.db.snapshot_metadata_get', return_value=dict())
- def test_list_snpashots_with_wrong_limit_and_offset(self,
+ def test_list_snapshots_with_wrong_limit_and_offset(self,
mock_metadata_get,
mock_snapshot_get_all):
"""Test list with negative and non numeric limit and offset."""
diff --git a/cinder/tests/unit/backup/drivers/test_backup_ceph.py b/cinder/tests/unit/backup/drivers/test_backup_ceph.py
index 9bd350703..813c6fea2 100644
--- a/cinder/tests/unit/backup/drivers/test_backup_ceph.py
+++ b/cinder/tests/unit/backup/drivers/test_backup_ceph.py
@@ -17,6 +17,7 @@
import hashlib
import json
import os
+import subprocess
import tempfile
import threading
from unittest import mock
@@ -136,8 +137,7 @@ class BackupCephTestCase(test.TestCase):
'user_foo', 'conf_foo')
return linuxrbd.RBDVolumeIOWrapper(rbd_meta)
- def _setup_mock_popen(self, mock_popen, retval=None, p1hook=None,
- p2hook=None):
+ def _setup_mock_popen(self, retval=None, p1hook=None, p2hook=None):
class MockPopen(object):
hooks = [p2hook, p1hook]
@@ -157,7 +157,7 @@ class BackupCephTestCase(test.TestCase):
self.callstack.append('communicate')
return retval
- mock_popen.side_effect = MockPopen
+ subprocess.Popen.side_effect = MockPopen
def setUp(self):
global RAISED_EXCEPTIONS
@@ -468,8 +468,7 @@ class BackupCephTestCase(test.TestCase):
@common_mocks
@mock.patch('fcntl.fcntl', spec=True)
- @mock.patch('subprocess.Popen', spec=True)
- def test_backup_volume_from_rbd(self, mock_popen, mock_fnctl):
+ def test_backup_volume_from_rbd(self, mock_fnctl):
"""Test full RBD backup generated successfully."""
backup_name = self.service._get_backup_base_name(self.volume_id,
self.alt_backup)
@@ -485,8 +484,7 @@ class BackupCephTestCase(test.TestCase):
self.callstack.append('read')
return self.volume_file.read(self.data_length)
- self._setup_mock_popen(mock_popen,
- ['out', 'err'],
+ self._setup_mock_popen(['out', 'err'],
p1hook=mock_read_data,
p2hook=mock_write_data)
@@ -647,8 +645,7 @@ class BackupCephTestCase(test.TestCase):
@common_mocks
@mock.patch('fcntl.fcntl', spec=True)
- @mock.patch('subprocess.Popen', spec=True)
- def test_backup_volume_from_rbd_fail(self, mock_popen, mock_fnctl):
+ def test_backup_volume_from_rbd_fail(self, mock_fnctl):
"""Test of when an exception occurs in an exception handler.
In _backup_rbd(), after an exception.BackupRBDOperationFailed
@@ -670,8 +667,7 @@ class BackupCephTestCase(test.TestCase):
self.callstack.append('read')
return self.volume_file.read(self.data_length)
- self._setup_mock_popen(mock_popen,
- ['out', 'err'],
+ self._setup_mock_popen(['out', 'err'],
p1hook=mock_read_data,
p2hook=mock_write_data)
@@ -726,8 +722,7 @@ class BackupCephTestCase(test.TestCase):
@common_mocks
@mock.patch('fcntl.fcntl', spec=True)
- @mock.patch('subprocess.Popen', spec=True)
- def test_backup_volume_from_rbd_fail2(self, mock_popen, mock_fnctl):
+ def test_backup_volume_from_rbd_fail2(self, mock_fnctl):
"""Test of when an exception occurs in an exception handler.
In backup(), after an exception.BackupOperationError occurs in
@@ -748,8 +743,7 @@ class BackupCephTestCase(test.TestCase):
self.callstack.append('read')
return self.volume_file.read(self.data_length)
- self._setup_mock_popen(mock_popen,
- ['out', 'err'],
+ self._setup_mock_popen(['out', 'err'],
p1hook=mock_read_data,
p2hook=mock_write_data)
@@ -1324,10 +1318,9 @@ class BackupCephTestCase(test.TestCase):
@common_mocks
@mock.patch('fcntl.fcntl', spec=True)
- @mock.patch('subprocess.Popen', spec=True)
- def test_piped_execute(self, mock_popen, mock_fcntl):
+ def test_piped_execute(self, mock_fcntl):
mock_fcntl.return_value = 0
- self._setup_mock_popen(mock_popen, ['out', 'err'])
+ self._setup_mock_popen(['out', 'err'])
self.service._piped_execute(['foo'], ['bar'])
self.assertEqual(['popen_init', 'popen_init',
'stdout_close', 'communicate'], self.callstack)
diff --git a/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py b/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
index d19824208..1d1e440cb 100644
--- a/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
+++ b/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py
@@ -749,10 +749,7 @@ class HPE3PARBaseDriver(test.TestCase):
configuration.unique_fqdn_network = True
return configuration
- @mock.patch(
- 'hpe3parclient.client.HPE3ParClient',
- spec=True,
- )
+ @mock.patch('hpe3parclient.client.HPE3ParClient')
def setup_mock_client(self, _m_client, driver, conf=None, m_conf=None,
is_primera=False,
wsapi_version=wsapi_version_latest):
diff --git a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py
index 8581253b6..1266fa9f4 100644
--- a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py
+++ b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py
@@ -6527,8 +6527,6 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
self.assertTrue(each_pool['multiattach'])
self.assertLessEqual(each_pool['free_capacity_gb'],
each_pool['total_capacity_gb'])
- self.assertLessEqual(each_pool['allocated_capacity_gb'],
- each_pool['total_capacity_gb'])
self.assertEqual(25, each_pool['reserved_percentage'])
self.assertEqual(is_thin_provisioning_enabled,
each_pool['thin_provisioning_support'])
@@ -6543,8 +6541,6 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
self._def_flags['storwize_svc_volpool_name'])
self.assertAlmostEqual(3328.0, each_pool['total_capacity_gb'])
self.assertAlmostEqual(3287.5, each_pool['free_capacity_gb'])
- self.assertAlmostEqual(25.0,
- each_pool['allocated_capacity_gb'])
if is_thin_provisioning_enabled:
self.assertAlmostEqual(
1576.96, each_pool['provisioned_capacity_gb'])
diff --git a/cinder/tests/unit/volume/drivers/test_rbd.py b/cinder/tests/unit/volume/drivers/test_rbd.py
index 21645886f..57dae3af1 100644
--- a/cinder/tests/unit/volume/drivers/test_rbd.py
+++ b/cinder/tests/unit/volume/drivers/test_rbd.py
@@ -1969,6 +1969,51 @@ class RBDTestCase(test.TestCase):
])
self.assertEqual((free_capacity, total_capacity), result)
+ @ddt.data(
+ # Normal case, no quota and dynamic total
+ {'free_capacity': 27.0, 'total_capacity': 28.44},
+ # No quota and static total
+ {'dynamic_total': False,
+ 'free_capacity': 27.0, 'total_capacity': 59.96},
+ # Quota and dynamic total
+ {'quota_max_bytes': 3221225472, 'max_avail': 1073741824,
+ 'free_capacity': 1, 'total_capacity': 2.44},
+ # Quota and static total
+ {'quota_max_bytes': 3221225472, 'max_avail': 1073741824,
+ 'dynamic_total': False,
+ 'free_capacity': 1, 'total_capacity': 3.00},
+ # Quota and dynamic total when free would be negative
+ {'quota_max_bytes': 1073741824,
+ 'free_capacity': 0, 'total_capacity': 1.44},
+ )
+ @ddt.unpack
+ @common_mocks
+ def test_get_pool_nautilus(self, free_capacity, total_capacity,
+ max_avail=28987613184, quota_max_bytes=0,
+ dynamic_total=True):
+ client = self.mock_client.return_value
+ client.__enter__.return_value = client
+ client.cluster.mon_command.side_effect = [
+ (0, '{"stats":{"total_bytes":64385286144,'
+ '"total_used_bytes":3289628672,"total_avail_bytes":61095657472},'
+ '"pools":[{"name":"rbd","id":2,"stats":{"kb_used":1510197,'
+ '"stored":1546440971,"bytes_used":4639322913,"max_avail":%s,'
+ '"objects":412}},{"name":"volumes","id":3,"stats":{"kb_used":0,'
+ '"bytes_used":0,"max_avail":28987613184,"objects":0}}]}\n' %
+ max_avail, ''),
+ (0, '{"pool_name":"volumes","pool_id":4,"quota_max_objects":0,'
+ '"quota_max_bytes":%s}\n' % quota_max_bytes, ''),
+ ]
+ with mock.patch.object(self.driver.configuration, 'safe_get',
+ return_value=dynamic_total):
+ result = self.driver._get_pool_stats()
+ client.cluster.mon_command.assert_has_calls([
+ mock.call('{"prefix":"df", "format":"json"}', b''),
+ mock.call('{"prefix":"osd pool get-quota", "pool": "rbd",'
+ ' "format":"json"}', b''),
+ ])
+ self.assertEqual((free_capacity, total_capacity), result)
+
@common_mocks
def test_get_pool_bytes(self):
"""Test for mon_commands returning bytes instead of strings."""
diff --git a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py
index 938741156..ede96c72e 100644
--- a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py
+++ b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py
@@ -6850,8 +6850,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
easy_tier = pool_data['easy_tier'] in ['on', 'auto']
total_capacity_gb = float(pool_data['capacity']) / units.Gi
free_capacity_gb = float(pool_data['free_capacity']) / units.Gi
- allocated_capacity_gb = (float(pool_data['used_capacity']) /
- units.Gi)
provisioned_capacity_gb = float(
pool_data['virtual_capacity']) / units.Gi
@@ -6878,7 +6876,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
'pool_name': pool_data['name'],
'total_capacity_gb': total_capacity_gb,
'free_capacity_gb': free_capacity_gb,
- 'allocated_capacity_gb': allocated_capacity_gb,
'provisioned_capacity_gb': provisioned_capacity_gb,
'compression_support': compression_enabled,
'reserved_percentage':
@@ -6911,7 +6908,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
pool_stats = {'pool_name': pool,
'total_capacity_gb': 0,
'free_capacity_gb': 0,
- 'allocated_capacity_gb': 0,
'provisioned_capacity_gb': 0,
'thin_provisioning_support': True,
'thick_provisioning_support': False,
diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index 07cc72174..6cc86c2c5 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -722,12 +722,15 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
total_capacity: float
free_capacity: float
+
+ # In Nautilus bytes_used was renamed to stored
+ bytes_used = pool_stats.get('stored', pool_stats['bytes_used'])
quota_outbuf = encodeutils.safe_decode(quota_outbuf)
bytes_quota = json.loads(quota_outbuf)['quota_max_bytes']
# With quota the total is the quota limit and free is quota - used
if bytes_quota:
total_capacity = bytes_quota
- free_capacity = max(min(total_capacity - pool_stats['bytes_used'],
+ free_capacity = max(min(total_capacity - bytes_used,
pool_stats['max_avail']),
0)
# Without quota free is pools max available and total is global size
@@ -737,7 +740,7 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
# If we want dynamic total capacity (default behavior)
if self.configuration.safe_get('report_dynamic_total_capacity'):
- total_capacity = free_capacity + pool_stats['bytes_used']
+ total_capacity = free_capacity + bytes_used
free_capacity = round((float(free_capacity) / units.Gi), 2)
total_capacity = round((float(total_capacity) / units.Gi), 2)
diff --git a/cinder/volume/targets/driver.py b/cinder/volume/targets/driver.py
index 9e186629b..644664b45 100644
--- a/cinder/volume/targets/driver.py
+++ b/cinder/volume/targets/driver.py
@@ -85,3 +85,11 @@ class Target(object, metaclass=abc.ABCMeta):
"""
a_host = A.get('host')
return a_host and (a_host == B.get('host'))
+
+ def extend_target(self, volume):
+ """Reinitializes a target after the volume has been extended.
+
+ Most drivers don't need to do anything, but in other cases this may
+ cause IO disruption.
+ """
+ pass
diff --git a/releasenotes/notes/hitachi-vsp-add-hostgroup-name-format-option-4c8e4a5ddd69b9bd.yaml b/releasenotes/notes/hitachi-vsp-add-hostgroup-name-format-option-4c8e4a5ddd69b9bd.yaml
index 20ed2cb80..e96aa8b28 100644
--- a/releasenotes/notes/hitachi-vsp-add-hostgroup-name-format-option-4c8e4a5ddd69b9bd.yaml
+++ b/releasenotes/notes/hitachi-vsp-add-hostgroup-name-format-option-4c8e4a5ddd69b9bd.yaml
@@ -3,6 +3,7 @@ features:
- |
Hitachi driver: Add a config option ``hitachi_group_name_format`` for
hostgroup name format.
+
When using this option, users can specify the name format of
host groups or iSCSI targets.
Rules of the format:
@@ -12,22 +13,25 @@ features:
* The specified value must start with ``HBSD-``.
* You can use the following variables:
- * ``{wwn}``: FC driver only. This is replaced with the smallest
- WWPN of the WWPNs of the connecting node.
- * ``{ip}``: iSCSI driver only. This is replaced with the IP address of
- the connecting node.
- * ``{host}``: This is replaced with the host name of the connecting node.
+ ``{wwn}``
+ `FC driver only.` This is replaced with the smallest
+ WWPN of the WWPNs of the connecting node.
+ ``{ip}``
+ `iSCSI driver only.` This is replaced with the IP address of
+ the connecting node.
+ ``{host}``
+ This is replaced with the host name of the connecting node.
* You can use each variable in the specified value no more than once.
* The specified value must include the following variables:
- * FC driver: ``{wwn}``
- * iSCSI driver: ``{ip}``
+ * FC driver: ``{wwn}``
+ * iSCSI driver: ``{ip}``
* The maximum length of a specified value is as follows:
- * FC driver: 64
- * iSCSI driver: 32
+ * FC driver: 64
+ * iSCSI driver: 32
* In the length calculation, use the following values as the length of
each variable:
@@ -46,8 +50,10 @@ features:
iSCSI targets do not exceed the maximum length.
If you specify this parameter, it is recommended that you specify ``True``
- for the hitachi_group_create parameter to collect necessary
+ for the ``hitachi_group_create`` parameter to collect necessary
information automatically.
+
Examples:
+
* FC driver: ``HBSD-{host}-{wwn}``
* iSCSI driver: ``HBSD-{host}-{ip}``
diff --git a/releasenotes/notes/rbd-total_capacity-60f10b45e3a8c8ea.yaml b/releasenotes/notes/rbd-total_capacity-60f10b45e3a8c8ea.yaml
new file mode 100644
index 000000000..1efa65097
--- /dev/null
+++ b/releasenotes/notes/rbd-total_capacity-60f10b45e3a8c8ea.yaml
@@ -0,0 +1,8 @@
+---
+fixes:
+ - |
+ RBD driver `bug #1960206
+ <https://bugs.launchpad.net/cinder/+bug/1960206>`_: Fixed
+ ``total_capacity`` reported by the driver to the scheduler on Ceph clusters
+ that have renamed the ``bytes_used`` field to ``stored``. (e.g., `Nautilus
+ <https://docs.ceph.com/en/nautilus/releases/nautilus/#upgrade-compatibility-notes>`_).