[RFE] NetApp share server migration get progress
Implement method share_server_migration_get_progress to get the share server migration percent based in the total size of shares (GB) tranfered from source to destination. Depends-On: I9eae95ff3f66a3497b00ca582491afec58ae6dc3 Closes-bug: #2030969 Change-Id: If4bf3378388cc0d9ea03f58b0ab5abd9a268bfdd
This commit is contained in:
parent
b4cc96d5fd
commit
bb7a06bf32
@ -6041,3 +6041,34 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
|||||||
|
|
||||||
return self.send_request(
|
return self.send_request(
|
||||||
'get-job', api_args=api_args, use_zapi=False)
|
'get-job', api_args=api_args, use_zapi=False)
|
||||||
|
|
||||||
|
@na_utils.trace
|
||||||
|
def get_svm_volumes_total_size(self, svm_name):
|
||||||
|
"""Gets volumes sizes sum (GB) from all volumes in SVM by svm_name"""
|
||||||
|
|
||||||
|
request = {}
|
||||||
|
|
||||||
|
query = {
|
||||||
|
'svm.name': svm_name,
|
||||||
|
'fields': 'size'
|
||||||
|
}
|
||||||
|
|
||||||
|
api_args = self._format_request(request, query=query)
|
||||||
|
|
||||||
|
response = self.send_request(
|
||||||
|
'svm-migration-get-progress', api_args=api_args, use_zapi=False)
|
||||||
|
|
||||||
|
svm_volumes = response.get('records', [])
|
||||||
|
|
||||||
|
if len(svm_volumes) > 0:
|
||||||
|
total_volumes_size = 0
|
||||||
|
for volume in svm_volumes:
|
||||||
|
# Root volumes are not taking account because they are part of
|
||||||
|
# SVM creation.
|
||||||
|
if volume['name'] != 'root':
|
||||||
|
total_volumes_size = total_volumes_size + volume['size']
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Convert Bytes to GBs.
|
||||||
|
return (total_volumes_size / 1024**3)
|
||||||
|
@ -5214,3 +5214,29 @@ class NetAppRestClient(object):
|
|||||||
'name': ipspace_name
|
'name': ipspace_name
|
||||||
}
|
}
|
||||||
self.send_request('/network/ipspaces', 'delete', query=query)
|
self.send_request('/network/ipspaces', 'delete', query=query)
|
||||||
|
|
||||||
|
@na_utils.trace
|
||||||
|
def get_svm_volumes_total_size(self, svm_name):
|
||||||
|
"""Gets volumes sizes sum (GB) from all volumes in SVM by svm_name"""
|
||||||
|
|
||||||
|
query = {
|
||||||
|
'svm.name': svm_name,
|
||||||
|
'fields': 'size'
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.send_request('/storage/volumes/', 'get', query=query)
|
||||||
|
|
||||||
|
svm_volumes = response.get('records', [])
|
||||||
|
|
||||||
|
if len(svm_volumes) > 0:
|
||||||
|
total_volumes_size = 0
|
||||||
|
for volume in svm_volumes:
|
||||||
|
# Root volumes are not taking account because they are part of
|
||||||
|
# SVM creation.
|
||||||
|
if volume['name'] != 'root':
|
||||||
|
total_volumes_size = total_volumes_size + volume['size']
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Convert Bytes to GBs.
|
||||||
|
return (total_volumes_size / 1024**3)
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
ENDPOINT_MIGRATION_ACTIONS = 'svm/migrations/%(svm_migration_id)s'
|
ENDPOINT_MIGRATION_ACTIONS = 'svm/migrations/%(svm_migration_id)s'
|
||||||
ENDPOINT_MIGRATIONS = 'svm/migrations'
|
ENDPOINT_MIGRATIONS = 'svm/migrations'
|
||||||
ENDPOINT_JOB_ACTIONS = 'cluster/jobs/%(job_uuid)s'
|
ENDPOINT_JOB_ACTIONS = 'cluster/jobs/%(job_uuid)s'
|
||||||
|
ENDPOINT_MIGRATION_GET_PROGRESS = '/storage/volumes/'
|
||||||
|
|
||||||
endpoints = {
|
endpoints = {
|
||||||
'system-get-version': {
|
'system-get-version': {
|
||||||
@ -46,4 +47,8 @@ endpoints = {
|
|||||||
'method': 'patch',
|
'method': 'patch',
|
||||||
'url': ENDPOINT_MIGRATION_ACTIONS
|
'url': ENDPOINT_MIGRATION_ACTIONS
|
||||||
},
|
},
|
||||||
|
'svm-migration-get-progress': {
|
||||||
|
'method': 'get',
|
||||||
|
'url': ENDPOINT_MIGRATION_GET_PROGRESS
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -2025,10 +2025,41 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
|||||||
|
|
||||||
LOG.info('Share server migration was cancelled.')
|
LOG.info('Share server migration was cancelled.')
|
||||||
|
|
||||||
|
@na_utils.trace
|
||||||
def share_server_migration_get_progress(self, context, src_share_server,
|
def share_server_migration_get_progress(self, context, src_share_server,
|
||||||
dest_share_server, shares,
|
dest_share_server, shares,
|
||||||
snapshots):
|
snapshots):
|
||||||
# TODO(dviroel): get snapmirror info to infer the progress
|
"""Compare source SVM total shares size with the destination SVM.
|
||||||
|
|
||||||
|
1. Gets the total size of the source SVM shares
|
||||||
|
2. Gets the total size of the destination SVM shares
|
||||||
|
3. Return the progress up to 99%, because 100% migration will be
|
||||||
|
returned when SVM migration phase 1 is finished.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get the total size of the source share server shares.
|
||||||
|
src_shares_total_size = 0
|
||||||
|
for instance in shares:
|
||||||
|
src_shares_total_size = (
|
||||||
|
src_shares_total_size + instance.get('size', 0))
|
||||||
|
|
||||||
|
if src_shares_total_size > 0:
|
||||||
|
# Destination share server has the same name as the source share
|
||||||
|
# server.
|
||||||
|
dest_share_server_name = self._get_vserver_name(
|
||||||
|
dest_share_server['source_share_server_id'])
|
||||||
|
|
||||||
|
# Get current volume total size in the destination SVM.
|
||||||
|
dest_shares_total_size = self._client.get_svm_volumes_total_size(
|
||||||
|
dest_share_server_name)
|
||||||
|
|
||||||
|
# The 100% progress will be return only when the SVM migration
|
||||||
|
# phase 1 is completed. 99% is an arbitrary number.
|
||||||
|
total_progress = (
|
||||||
|
(99 * dest_shares_total_size) / src_shares_total_size)
|
||||||
|
|
||||||
|
return {'total_progress': round(total_progress)}
|
||||||
|
|
||||||
return {'total_progress': 0}
|
return {'total_progress': 0}
|
||||||
|
|
||||||
def _update_share_attributes_after_server_migration(
|
def _update_share_attributes_after_server_migration(
|
||||||
|
@ -4764,3 +4764,13 @@ FAKE_ROOT_AGGREGATES_RESPONSE = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAKE_GET_VOLUME = {
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"uuid": FAKE_UUID,
|
||||||
|
"name": "share_6cb5b3f4_35d0_40b8_a106_d35262ac17c7",
|
||||||
|
"size": 1024**3,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
@ -9024,3 +9024,28 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
|||||||
exception.NetAppException,
|
exception.NetAppException,
|
||||||
self.client.check_snaprestore_license)
|
self.client.check_snaprestore_license)
|
||||||
client_cmode.LOG.exception.assert_called_once()
|
client_cmode.LOG.exception.assert_called_once()
|
||||||
|
|
||||||
|
def test_get_svm_volumes_total_size(self):
|
||||||
|
expected = 1
|
||||||
|
|
||||||
|
request = {}
|
||||||
|
|
||||||
|
api_args = {
|
||||||
|
'svm.name': fake.VSERVER_NAME,
|
||||||
|
'fields': 'size'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mock_object(self.client, '_format_request',
|
||||||
|
mock.Mock(return_value=api_args))
|
||||||
|
|
||||||
|
self.mock_object(self.client, 'send_request',
|
||||||
|
mock.Mock(return_value=fake.FAKE_GET_VOLUME))
|
||||||
|
|
||||||
|
result = self.client.get_svm_volumes_total_size(fake.VSERVER_NAME)
|
||||||
|
|
||||||
|
self.client._format_request.assert_called_once_with(request,
|
||||||
|
query=api_args)
|
||||||
|
self.client.send_request.assert_called_once_with(
|
||||||
|
'svm-migration-get-progress', api_args=api_args, use_zapi=False)
|
||||||
|
|
||||||
|
self.assertEqual(expected, result)
|
||||||
|
@ -6747,3 +6747,21 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(netapp_utils.NetAppDriverException,
|
self.assertRaises(netapp_utils.NetAppDriverException,
|
||||||
self.client._break_snapmirror)
|
self.client._break_snapmirror)
|
||||||
|
|
||||||
|
def test_get_svm_volumes_total_size(self):
|
||||||
|
expected = 1
|
||||||
|
|
||||||
|
fake_query = {
|
||||||
|
'svm.name': fake.VSERVER_NAME,
|
||||||
|
'fields': 'size'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mock_object(self.client, 'send_request',
|
||||||
|
mock.Mock(return_value=fake.FAKE_GET_VOLUME))
|
||||||
|
|
||||||
|
result = self.client.get_svm_volumes_total_size(fake.VSERVER_NAME)
|
||||||
|
|
||||||
|
self.client.send_request.assert_called_once_with(
|
||||||
|
'/storage/volumes/', 'get', query=fake_query)
|
||||||
|
|
||||||
|
self.assertEqual(expected, result)
|
||||||
|
@ -3433,12 +3433,24 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||||||
[]))
|
[]))
|
||||||
|
|
||||||
def test_share_server_migration_get_progress(self):
|
def test_share_server_migration_get_progress(self):
|
||||||
expected_result = {'total_progress': 0}
|
fake_vserver_name = fake.VSERVER1
|
||||||
|
expected_result = {'total_progress': 50}
|
||||||
|
|
||||||
|
self.mock_object(self.library._client, 'get_svm_volumes_total_size',
|
||||||
|
mock.Mock(return_value=5))
|
||||||
|
|
||||||
|
self.mock_object(self.library, '_get_vserver_name',
|
||||||
|
mock.Mock(return_value=fake_vserver_name))
|
||||||
|
|
||||||
result = self.library.share_server_migration_get_progress(
|
result = self.library.share_server_migration_get_progress(
|
||||||
None, None, None, None, None
|
None, self.fake_src_share_server, self.fake_dest_share_server,
|
||||||
|
[self.fake_src_share], None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.library._client.get_svm_volumes_total_size.assert_called_once_with
|
||||||
|
(fake_vserver_name)
|
||||||
|
self.library._get_vserver_name.assert_called_once_with
|
||||||
|
(self.fake_dest_share_server['source_share_server_id'])
|
||||||
self.assertEqual(expected_result, result)
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
@ddt.data({'subtype': 'default',
|
@ddt.data({'subtype': 'default',
|
||||||
|
@ -582,6 +582,7 @@ SHARE_SERVER = {
|
|||||||
|
|
||||||
SHARE_SERVER_2 = {
|
SHARE_SERVER_2 = {
|
||||||
'id': 'fake_id_2',
|
'id': 'fake_id_2',
|
||||||
|
'source_share_server_id': 'fake_src_share_server_id_2',
|
||||||
'share_network_id': 'c5b3a865-56d0-4d88-abe5-879965e099c9',
|
'share_network_id': 'c5b3a865-56d0-4d88-abe5-879965e099c9',
|
||||||
'backend_details': {
|
'backend_details': {
|
||||||
'vserver_name': VSERVER2
|
'vserver_name': VSERVER2
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
NetApp driver is now able to inform the migration percentage of a share
|
||||||
|
server migration.
|
Loading…
Reference in New Issue
Block a user