From c9fa6f939c8f3ad5a0add3ed92499b394b1330c8 Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Fri, 1 Nov 2024 07:33:34 +0000 Subject: [PATCH] [netapp] Allow share server migration with replicas New share server property `share_replicas_migration_support` will be set by backend driver and then evaluated in api layer to allow/dis-allow share server migration with replicas. Closes-bug: #2052785 Change-Id: I1cc5489488f44cc7edc7348fb3b3af7397564682 Depends-On: https://review.opendev.org/c/openstack/manila-tempest-plugin/+/935355 --- ...0d8c8f6d54a4_modify_share_servers_table.py | 55 +++++++++++++++++++ manila/db/sqlalchemy/models.py | 2 + manila/scheduler/host_manager.py | 9 +++ manila/scheduler/utils.py | 4 +- manila/share/api.py | 4 +- manila/share/driver.py | 3 + .../dataontap/cluster_mode/drv_multi_svm.py | 1 + .../netapp/dataontap/cluster_mode/lib_base.py | 1 + manila/share/manager.py | 10 +++- manila/tests/scheduler/test_host_manager.py | 11 ++++ .../share/drivers/dell_emc/test_driver.py | 1 + manila/tests/share/drivers/dummy.py | 1 + .../glusterfs/test_glusterfs_native.py | 1 + .../share/drivers/hpe/test_hpe_3par_driver.py | 3 + .../share/drivers/huawei/test_huawei_nas.py | 1 + .../share/drivers/netapp/dataontap/fakes.py | 4 ++ .../share/drivers/veritas/test_veritas_isa.py | 1 + .../share/drivers/zfsonlinux/test_driver.py | 1 + manila/tests/share/test_manager.py | 4 +- ...ration-with-replicas-971fece378440aba.yaml | 6 ++ 20 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 manila/db/migrations/alembic/versions/0d8c8f6d54a4_modify_share_servers_table.py create mode 100644 releasenotes/notes/bug-2052785-netapp-allow-share-server-migration-with-replicas-971fece378440aba.yaml diff --git a/manila/db/migrations/alembic/versions/0d8c8f6d54a4_modify_share_servers_table.py b/manila/db/migrations/alembic/versions/0d8c8f6d54a4_modify_share_servers_table.py new file mode 100644 index 0000000000..a5bc7b16ea --- /dev/null +++ b/manila/db/migrations/alembic/versions/0d8c8f6d54a4_modify_share_servers_table.py @@ -0,0 +1,55 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""modify_share_servers_table + +Revision ID: 0d8c8f6d54a4 +Revises: cdefa6287df8 +Create Date: 2024-11-15 09:25:25.957286 + +""" + +# revision identifiers, used by Alembic. +revision = '0d8c8f6d54a4' +down_revision = 'cdefa6287df8' + +from alembic import op +from oslo_log import log +import sqlalchemy as sa + + +SHARE_SERVERS_TABLE = 'share_servers' +LOG = log.getLogger(__name__) + + +def upgrade(): + # add a new column to share_servers. + try: + op.add_column( + SHARE_SERVERS_TABLE, + sa.Column('share_replicas_migration_support', sa.Boolean, + nullable=False, server_default=sa.sql.false())) + except Exception: + LOG.error("Table %s could not add column " + "'share_replicas_migration_support'.", + SHARE_SERVERS_TABLE) + raise + + +def downgrade(): + try: + op.drop_column(SHARE_SERVERS_TABLE, + 'share_replicas_migration_support') + except Exception: + LOG.error("Table %s failed to drop the column " + "'share_replicas_migration_support'.", SHARE_SERVERS_TABLE) + raise diff --git a/manila/db/sqlalchemy/models.py b/manila/db/sqlalchemy/models.py index bfb114bb53..4c3014f826 100644 --- a/manila/db/sqlalchemy/models.py +++ b/manila/db/sqlalchemy/models.py @@ -1120,6 +1120,8 @@ class ShareServer(BASE, ManilaBase): Boolean, nullable=False, default=False) network_allocation_update_support = Column( Boolean, nullable=False, default=False) + share_replicas_migration_support = Column( + Boolean, nullable=False, default=False) status = Column(Enum( constants.STATUS_INACTIVE, constants.STATUS_ACTIVE, constants.STATUS_ERROR, constants.STATUS_DELETING, diff --git a/manila/scheduler/host_manager.py b/manila/scheduler/host_manager.py index 4900028c32..286c0fb584 100644 --- a/manila/scheduler/host_manager.py +++ b/manila/scheduler/host_manager.py @@ -160,6 +160,7 @@ class HostState(object): self.network_allocation_update_support = False self.share_server_multiple_subnet_support = False self.mount_point_name_support = False + self.share_replicas_migration_support = False # PoolState for all pools self.pools = {} @@ -365,6 +366,10 @@ class HostState(object): pool_cap['share_server_multiple_subnet_support'] = ( self.share_server_multiple_subnet_support) + if 'share_replicas_migration_support' not in pool_cap: + pool_cap['share_replicas_migration_support'] = ( + self.share_replicas_migration_support) + if self.ipv4_support is not None: pool_cap['ipv4_support'] = self.ipv4_support @@ -400,6 +405,8 @@ class HostState(object): 'network_allocation_update_support', False) self.share_server_multiple_subnet_support = capability.get( 'share_server_multiple_subnet_support', False) + self.share_replicas_migration_support = capability.get( + 'share_replicas_migration_support', False) def consume_from_share(self, share): """Incrementally update host state from an share.""" @@ -506,6 +513,8 @@ class PoolState(HostState): 'network_allocation_update_support', False) self.share_server_multiple_subnet_support = capability.get( 'share_server_multiple_subnet_support', False) + self.share_replicas_migration_support = capability.get( + 'share_replicas_migration_support', False) def update_pools(self, capability): # Do nothing, since we don't have pools within pool, yet diff --git a/manila/scheduler/utils.py b/manila/scheduler/utils.py index e2fcf54982..61e2088b69 100644 --- a/manila/scheduler/utils.py +++ b/manila/scheduler/utils.py @@ -68,7 +68,9 @@ def generate_stats(host_state, properties): 'share_server_multiple_subnet_support': ( host_state.share_server_multiple_subnet_support), 'mount_point_name_support': ( - host_state.mount_point_name_support) + host_state.mount_point_name_support), + 'share_replicas_migration_support': ( + host_state.share_replicas_migration_support), } host_caps = host_state.capabilities diff --git a/manila/share/api.py b/manila/share/api.py index 7ec6d62efe..7566b81ed9 100644 --- a/manila/share/api.py +++ b/manila/share/api.py @@ -3090,7 +3090,9 @@ class API(base.Base): 'share_status': share['status']} raise exception.InvalidShareServer(reason=msg) - if share.has_replicas: + if (not share_server.get( + 'share_replicas_migration_support', False) and + share.has_replicas): msg = _('Share %s has replicas. Remove the replicas of all ' 'shares in the share server before attempting to ' 'migrate it.') % share['id'] diff --git a/manila/share/driver.py b/manila/share/driver.py index 92e1282f31..d134d990d3 100644 --- a/manila/share/driver.py +++ b/manila/share/driver.py @@ -292,6 +292,7 @@ class ShareDriver(object): # property will be saved in every new share server. self.network_allocation_update_support = False self.dhss_mandatory_security_service_association = {} + self.share_replicas_migration_support = False self.pools = [] if self.configuration: @@ -1357,6 +1358,8 @@ class ShareDriver(object): self.network_allocation_update_support), share_server_multiple_subnet_support=False, mount_point_name_support=False, + share_replicas_migration_support=( + self.share_replicas_migration_support), ) if isinstance(data, dict): common.update(data) diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py index e1d207218b..5000e1af59 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/drv_multi_svm.py @@ -45,6 +45,7 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver): # NetApp driver supports multiple subnets including update existing # share servers. self.network_allocation_update_support = True + self.share_replicas_migration_support = True def do_setup(self, context): self.library.do_setup(context) diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py index 99589713fa..c8b0905de8 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py @@ -571,6 +571,7 @@ class NetAppCmodeFileStorageLibrary(object): 'security_service_update_support': True, 'share_server_multiple_subnet_support': True, 'mount_point_name_support': True, + 'share_replicas_migration_support': True, } # Add storage service catalog data. diff --git a/manila/share/manager.py b/manila/share/manager.py index 228793b437..a7dee321ad 100644 --- a/manila/share/manager.py +++ b/manila/share/manager.py @@ -811,6 +811,8 @@ class ShareManager(manager.SchedulerDependentManager): self.driver.security_service_update_support), 'network_allocation_update_support': ( self.driver.network_allocation_update_support), + 'share_replicas_migration_support': ( + self.driver.share_replicas_migration_support), } ) @@ -901,6 +903,8 @@ class ShareManager(manager.SchedulerDependentManager): self.driver.security_service_update_support), 'network_allocation_update_support': ( self.driver.network_allocation_update_support), + 'share_replicas_migration_support': ( + self.driver.share_replicas_migration_support), } ) @@ -1088,6 +1092,8 @@ class ShareManager(manager.SchedulerDependentManager): self.driver.security_service_update_support), 'network_allocation_update_support': ( self.driver.network_allocation_update_support), + 'share_replicas_migration_support': ( + self.driver.share_replicas_migration_support), } ) @@ -3389,7 +3395,9 @@ class ShareManager(manager.SchedulerDependentManager): {'status': constants.STATUS_ACTIVE, 'identifier': new_identifier, 'network_allocation_update_support': ( - self.driver.network_allocation_update_support)}) + self.driver.network_allocation_update_support), + 'share_replicas_migration_support': ( + self.driver.share_replicas_migration_support)}) except Exception: msg = "Error managing share server %s" diff --git a/manila/tests/scheduler/test_host_manager.py b/manila/tests/scheduler/test_host_manager.py index de275734e9..e3c9e9b46d 100644 --- a/manila/tests/scheduler/test_host_manager.py +++ b/manila/tests/scheduler/test_host_manager.py @@ -218,6 +218,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host2@back1#BBB', @@ -252,6 +253,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host2@back2#CCC', @@ -286,6 +288,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, ] @@ -342,6 +345,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host2@BBB#pool2', @@ -377,6 +381,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host3@CCC#pool3', @@ -412,6 +417,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host4@DDD#pool4a', @@ -447,6 +453,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host4@DDD#pool4b', @@ -482,6 +489,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, ] @@ -550,6 +558,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, { 'name': 'host2@back1#BBB', @@ -584,6 +593,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False }, }, ] @@ -646,6 +656,7 @@ class HostManagerTestCase(test.TestCase): 'network_allocation_update_support': False, 'share_server_multiple_subnet_support': False, 'mount_point_name_support': False, + 'share_replicas_migration_support': False, }, }, ] diff --git a/manila/tests/share/drivers/dell_emc/test_driver.py b/manila/tests/share/drivers/dell_emc/test_driver.py index 9a79ab5dde..ec8ae33aef 100644 --- a/manila/tests/share/drivers/dell_emc/test_driver.py +++ b/manila/tests/share/drivers/dell_emc/test_driver.py @@ -176,6 +176,7 @@ class EMCShareFrameworkTestCase(test.TestCase): data['security_service_update_support'] = False data['share_server_multiple_subnet_support'] = False data['network_allocation_update_support'] = False + data['share_replicas_migration_support'] = False self.assertEqual(data, self.driver._stats) def _fake_safe_get(self, value): diff --git a/manila/tests/share/drivers/dummy.py b/manila/tests/share/drivers/dummy.py index b8a786983a..072ada6157 100644 --- a/manila/tests/share/drivers/dummy.py +++ b/manila/tests/share/drivers/dummy.py @@ -147,6 +147,7 @@ class DummyDriver(driver.ShareDriver): self.migration_progress = {} self.security_service_update_support = True self.network_allocation_update_support = True + self.share_replicas_migration_support = True def _verify_configuration(self): allowed_driver_methods = [m for m in dir(self) if m[0] != '_'] diff --git a/manila/tests/share/drivers/glusterfs/test_glusterfs_native.py b/manila/tests/share/drivers/glusterfs/test_glusterfs_native.py index d408a199a6..778d015ba9 100644 --- a/manila/tests/share/drivers/glusterfs/test_glusterfs_native.py +++ b/manila/tests/share/drivers/glusterfs/test_glusterfs_native.py @@ -274,6 +274,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase): 'security_service_update_support': False, 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, } self.assertEqual(test_data, self._driver._stats) diff --git a/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py index dbd22c6cd6..67ab6348de 100644 --- a/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py @@ -754,6 +754,7 @@ class HPE3ParDriverTestCase(test.TestCase): 'security_service_update_support': False, 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, } result = self.driver.get_share_stats(refresh=True) @@ -834,6 +835,7 @@ class HPE3ParDriverTestCase(test.TestCase): 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, 'mount_snapshot_support': False, + 'share_replicas_migration_support': False, 'share_group_stats': { 'consistent_snapshot_support': None, }, @@ -885,6 +887,7 @@ class HPE3ParDriverTestCase(test.TestCase): 'security_service_update_support': False, 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, 'mount_snapshot_support': False, 'share_group_stats': { 'consistent_snapshot_support': None, diff --git a/manila/tests/share/drivers/huawei/test_huawei_nas.py b/manila/tests/share/drivers/huawei/test_huawei_nas.py index c53f27c18a..b0372062c7 100644 --- a/manila/tests/share/drivers/huawei/test_huawei_nas.py +++ b/manila/tests/share/drivers/huawei/test_huawei_nas.py @@ -2439,6 +2439,7 @@ class HuaweiShareDriverTestCase(test.TestCase): "security_service_update_support": False, "share_server_multiple_subnet_support": False, "network_allocation_update_support": False, + "share_replicas_migration_support": False, } if replication_support: diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py index aff9354900..d13fdb2361 100644 --- a/manila/tests/share/drivers/netapp/dataontap/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py @@ -1081,6 +1081,7 @@ POOLS = [ 'netapp_flexgroup': False, 'netapp_cluster_name': 'fake_cluster_name', 'netapp_snaplock_type': 'compliance', + 'share_replicas_migration_support': True, }, { 'pool_name': AGGREGATES[1], @@ -1111,6 +1112,7 @@ POOLS = [ 'netapp_flexgroup': False, 'netapp_cluster_name': 'fake_cluster_name', 'netapp_snaplock_type': 'compliance', + 'share_replicas_migration_support': True }, ] @@ -1141,6 +1143,7 @@ POOLS_VSERVER_CREDS = [ 'security_service_update_support': True, 'share_server_multiple_subnet_support': True, 'netapp_flexgroup': False, + 'share_replicas_migration_support': True }, { 'pool_name': AGGREGATES[1], @@ -1164,6 +1167,7 @@ POOLS_VSERVER_CREDS = [ 'security_service_update_support': True, 'share_server_multiple_subnet_support': True, 'netapp_flexgroup': False, + 'share_replicas_migration_support': True }, ] diff --git a/manila/tests/share/drivers/veritas/test_veritas_isa.py b/manila/tests/share/drivers/veritas/test_veritas_isa.py index 08b0183c84..1309fe7c3e 100644 --- a/manila/tests/share/drivers/veritas/test_veritas_isa.py +++ b/manila/tests/share/drivers/veritas/test_veritas_isa.py @@ -451,6 +451,7 @@ class ACCESSShareDriverTestCase(test.TestCase): 'security_service_update_support': False, 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, } self.assertEqual(data, self._driver._stats) diff --git a/manila/tests/share/drivers/zfsonlinux/test_driver.py b/manila/tests/share/drivers/zfsonlinux/test_driver.py index 262360816b..7bde56b05b 100644 --- a/manila/tests/share/drivers/zfsonlinux/test_driver.py +++ b/manila/tests/share/drivers/zfsonlinux/test_driver.py @@ -382,6 +382,7 @@ class ZFSonLinuxShareDriverTestCase(test.TestCase): 'security_service_update_support': False, 'share_server_multiple_subnet_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, } if replication_domain: expected['replication_type'] = 'readable' diff --git a/manila/tests/share/test_manager.py b/manila/tests/share/test_manager.py index 5684f913c6..408eaed0c1 100644 --- a/manila/tests/share/test_manager.py +++ b/manila/tests/share/test_manager.py @@ -3469,6 +3469,7 @@ class ShareManagerTestCase(test.TestCase): 'status': constants.STATUS_CREATING, 'security_service_update_support': False, 'network_allocation_update_support': False, + 'share_replicas_migration_support': False, } fake_metadata = { 'migration_destination': True, @@ -7421,7 +7422,8 @@ class ShareManagerTestCase(test.TestCase): utils.IsAMatcher(context.RequestContext), fake_share_server['id'], {'status': constants.STATUS_ACTIVE, 'identifier': driver_return[0] or share_server['id'], - 'network_allocation_update_support': False} + 'network_allocation_update_support': False, + 'share_replicas_migration_support': False} ) mock_set_backend_details.assert_called_once_with( utils.IsAMatcher(context.RequestContext), share_server['id'], diff --git a/releasenotes/notes/bug-2052785-netapp-allow-share-server-migration-with-replicas-971fece378440aba.yaml b/releasenotes/notes/bug-2052785-netapp-allow-share-server-migration-with-replicas-971fece378440aba.yaml new file mode 100644 index 0000000000..8314bb80cf --- /dev/null +++ b/releasenotes/notes/bug-2052785-netapp-allow-share-server-migration-with-replicas-971fece378440aba.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Netapp ONTAP driver now allows migration of share server even if one or + more shares on share server has replicas. For more details, please check + `Launchpad bug #2052785 `_