[Pure Storage] Add new array status for replication capability
This patch adds a new field for the `get pools` command to show what replication capability the backend array currently has. This is based on the status of current array connections in the backend array. Response will be `async`, `sync`. `sync` or `trisync`. `trisync` implies support for `sync` and `async`. `sync` implies support for `async`. Change-Id: I46cbb986ed73335270d6dd4ad197197648b55506
This commit is contained in:
parent
7d25060243
commit
a87eb13648
@ -4152,12 +4152,61 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
|
|||||||
actual_ratio = self.driver._get_thin_provisioning(provisioned, used)
|
actual_ratio = self.driver._get_thin_provisioning(provisioned, used)
|
||||||
self.assertEqual(expected_ratio, actual_ratio)
|
self.assertEqual(expected_ratio, actual_ratio)
|
||||||
|
|
||||||
|
@ddt.data(
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'sync-replication'},
|
||||||
|
],
|
||||||
|
expected='sync'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'async-replication'}
|
||||||
|
],
|
||||||
|
expected='async'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'async-replication'},
|
||||||
|
{'status': 'connected', 'type': 'sync-replication'},
|
||||||
|
{'status': 'connected', 'type': 'async-replication'}
|
||||||
|
],
|
||||||
|
expected='trisync'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'async-replication'},
|
||||||
|
{'status': 'connected', 'type': 'async-replication'}
|
||||||
|
],
|
||||||
|
expected='async'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'sync-replication'},
|
||||||
|
{'status': 'connected', 'type': 'sync-replication'}
|
||||||
|
],
|
||||||
|
expected='sync'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connected', 'type': 'sync-replication'},
|
||||||
|
{'status': 'connected', 'type': 'async-replication'}
|
||||||
|
],
|
||||||
|
expected='trisync'),
|
||||||
|
dict(
|
||||||
|
connections=[
|
||||||
|
{'status': 'connecting', 'type': 'sync-replication'}
|
||||||
|
],
|
||||||
|
expected=None))
|
||||||
|
@ddt.unpack
|
||||||
|
def test_get_replication_capability(self, connections, expected):
|
||||||
|
self.array.list_array_connections.return_value = connections
|
||||||
|
connection_status = self.driver._get_replication_capability()
|
||||||
|
self.assertEqual(expected, connection_status)
|
||||||
|
|
||||||
|
@mock.patch(BASE_DRIVER_OBJ + '._get_replication_capability')
|
||||||
@mock.patch(BASE_DRIVER_OBJ + '.get_goodness_function')
|
@mock.patch(BASE_DRIVER_OBJ + '.get_goodness_function')
|
||||||
@mock.patch(BASE_DRIVER_OBJ + '.get_filter_function')
|
@mock.patch(BASE_DRIVER_OBJ + '.get_filter_function')
|
||||||
@mock.patch(BASE_DRIVER_OBJ + '._get_provisioned_space')
|
@mock.patch(BASE_DRIVER_OBJ + '._get_provisioned_space')
|
||||||
@mock.patch(BASE_DRIVER_OBJ + '._get_thin_provisioning')
|
@mock.patch(BASE_DRIVER_OBJ + '._get_thin_provisioning')
|
||||||
def test_get_volume_stats(self, mock_get_thin_provisioning, mock_get_space,
|
def test_get_volume_stats(self, mock_get_thin_provisioning, mock_get_space,
|
||||||
mock_get_filter, mock_get_goodness):
|
mock_get_filter, mock_get_goodness,
|
||||||
|
mock_get_replication_capability):
|
||||||
filter_function = 'capabilities.total_volumes < 10'
|
filter_function = 'capabilities.total_volumes < 10'
|
||||||
goodness_function = '90'
|
goodness_function = '90'
|
||||||
num_hosts = 20
|
num_hosts = 20
|
||||||
@ -4172,6 +4221,7 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
|
|||||||
mock_get_space.return_value = (PROVISIONED_CAPACITY * units.Gi, 100)
|
mock_get_space.return_value = (PROVISIONED_CAPACITY * units.Gi, 100)
|
||||||
mock_get_filter.return_value = filter_function
|
mock_get_filter.return_value = filter_function
|
||||||
mock_get_goodness.return_value = goodness_function
|
mock_get_goodness.return_value = goodness_function
|
||||||
|
mock_get_replication_capability.return_value = 'sync'
|
||||||
mock_get_thin_provisioning.return_value = (PROVISIONED_CAPACITY /
|
mock_get_thin_provisioning.return_value = (PROVISIONED_CAPACITY /
|
||||||
USED_SPACE)
|
USED_SPACE)
|
||||||
|
|
||||||
@ -4203,6 +4253,7 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
|
|||||||
'usec_per_read_op': PERF_INFO['usec_per_read_op'],
|
'usec_per_read_op': PERF_INFO['usec_per_read_op'],
|
||||||
'usec_per_write_op': PERF_INFO['usec_per_write_op'],
|
'usec_per_write_op': PERF_INFO['usec_per_write_op'],
|
||||||
'queue_depth': PERF_INFO['queue_depth'],
|
'queue_depth': PERF_INFO['queue_depth'],
|
||||||
|
'replication_capability': 'sync',
|
||||||
'replication_enabled': False,
|
'replication_enabled': False,
|
||||||
'replication_type': [],
|
'replication_type': [],
|
||||||
'replication_count': 0,
|
'replication_count': 0,
|
||||||
|
@ -918,6 +918,7 @@ class PureBaseVolumeDriver(san.SanDriver):
|
|||||||
data['queue_depth'] = perf_info['queue_depth']
|
data['queue_depth'] = perf_info['queue_depth']
|
||||||
|
|
||||||
# Replication
|
# Replication
|
||||||
|
data["replication_capability"] = self._get_replication_capability()
|
||||||
data["replication_enabled"] = self._is_replication_enabled
|
data["replication_enabled"] = self._is_replication_enabled
|
||||||
repl_types = []
|
repl_types = []
|
||||||
if self._is_replication_enabled:
|
if self._is_replication_enabled:
|
||||||
@ -930,6 +931,39 @@ class PureBaseVolumeDriver(san.SanDriver):
|
|||||||
in self._replication_target_arrays]
|
in self._replication_target_arrays]
|
||||||
self._stats = data
|
self._stats = data
|
||||||
|
|
||||||
|
def _get_replication_capability(self):
|
||||||
|
"""Discovered connected arrays status for replication"""
|
||||||
|
connections = self._get_current_array().list_array_connections()
|
||||||
|
is_sync, is_async, is_trisync = False, False, False
|
||||||
|
for conn in connections:
|
||||||
|
# If connection status is connected, we can have
|
||||||
|
# either sync or async replication
|
||||||
|
if conn["status"] == "connected":
|
||||||
|
# check for async replication
|
||||||
|
if conn["type"] == "async-replication":
|
||||||
|
is_async = True
|
||||||
|
# check for sync replication
|
||||||
|
elif conn["type"] == "sync-replication":
|
||||||
|
is_sync = True
|
||||||
|
# If we've connections for both sync and async
|
||||||
|
# replication, we can set trisync replication
|
||||||
|
# and exit the loop
|
||||||
|
if is_sync and is_async:
|
||||||
|
is_trisync = True
|
||||||
|
break
|
||||||
|
# Check if it is a trisync replication
|
||||||
|
if is_trisync:
|
||||||
|
replication_type = "trisync"
|
||||||
|
# If replication is not trisync, it will be either
|
||||||
|
# sync or async
|
||||||
|
elif is_sync:
|
||||||
|
replication_type = "sync"
|
||||||
|
elif is_async:
|
||||||
|
replication_type = "async"
|
||||||
|
else:
|
||||||
|
replication_type = None
|
||||||
|
return replication_type
|
||||||
|
|
||||||
def _get_provisioned_space(self):
|
def _get_provisioned_space(self):
|
||||||
"""Sum up provisioned size of all volumes on array"""
|
"""Sum up provisioned size of all volumes on array"""
|
||||||
volumes = self._get_current_array().list_volumes(pending=True)
|
volumes = self._get_current_array().list_volumes(pending=True)
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Pure Storage driver: Added replication capability to backend pool information.
|
||||||
|
Response will be ```async```, ```sync``` or```trisync```. ```sync``` implies
|
||||||
|
support for ```async``` and ```trisync``` implies support for ```sync``` and ```async```.
|
Loading…
Reference in New Issue
Block a user