Browse Source

NetApp cDOT: Fix share specs on migration

Administrators may request to change the share type
during a migration, and if optimized migration
is possible, the driver must set the required
specs on the destination.

Change-Id: I11498058a3c80c8bd26be9d0bbf0459b4b2b2108
Closes-Bug: #1704622
(cherry picked from commit 96a037fb67)
Goutham Pacha Ravi 1 year ago
parent
commit
171636c778

+ 23
- 2
manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py View File

@@ -1719,14 +1719,23 @@ class NetAppCmodeFileStorageLibrary(object):
1719 1719
             try:
1720 1720
                 backend = share_utils.extract_host(
1721 1721
                     destination_host, level='backend_name')
1722
+                destination_aggregate = share_utils.extract_host(
1723
+                    destination_host, level='pool')
1724
+                # Validate new share type extra-specs are valid on the
1725
+                # destination
1726
+                extra_specs = share_types.get_extra_specs_from_share(
1727
+                    destination_share)
1728
+                self._check_extra_specs_validity(
1729
+                    destination_share, extra_specs)
1730
+                self._check_aggregate_extra_specs_validity(
1731
+                    destination_aggregate, extra_specs)
1732
+
1722 1733
                 data_motion.get_backend_configuration(backend)
1723 1734
 
1724 1735
                 source_vserver, __ = self._get_vserver(
1725 1736
                     share_server=share_server)
1726 1737
                 share_volume = self._get_backend_share_name(
1727 1738
                     source_share['id'])
1728
-                destination_aggregate = share_utils.extract_host(
1729
-                    destination_host, level='pool')
1730 1739
 
1731 1740
                 self._check_destination_vserver_for_vol_move(
1732 1741
                     source_share, source_vserver, destination_share_server)
@@ -1903,6 +1912,18 @@ class NetAppCmodeFileStorageLibrary(object):
1903 1912
             destination_share['id'])
1904 1913
         vserver_client.set_volume_name(share_volume, new_share_volume_name)
1905 1914
 
1915
+        # Modify volume properties per share type extra-specs
1916
+        extra_specs = share_types.get_extra_specs_from_share(
1917
+            destination_share)
1918
+        provisioning_options = self._get_provisioning_options(extra_specs)
1919
+        destination_aggregate = share_utils.extract_host(
1920
+            destination_share['host'], level='pool')
1921
+
1922
+        # Modify volume to match extra specs
1923
+        vserver_client.manage_volume(destination_aggregate,
1924
+                                     new_share_volume_name,
1925
+                                     **provisioning_options)
1926
+
1906 1927
         msg = _LI("Volume move operation for share %(shr)s has completed "
1907 1928
                   "successfully. Share has been moved from %(src)s to "
1908 1929
                   "%(dest)s.")

+ 57
- 0
manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py View File

@@ -3894,6 +3894,39 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3894 3894
         mock_warning_log.assert_called_once()
3895 3895
         self.assertFalse(data_motion.get_backend_configuration.called)
3896 3896
 
3897
+    @ddt.data((None, exception.NetAppException),
3898
+              (exception.Invalid, None))
3899
+    @ddt.unpack
3900
+    def test_migration_check_compatibility_extra_specs_invalid(
3901
+            self, side_effect_1, side_effect_2):
3902
+        self.library._have_cluster_creds = True
3903
+        self.mock_object(self.library, '_get_backend_share_name',
3904
+                         mock.Mock(return_value=fake.SHARE_NAME))
3905
+        mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
3906
+        self.mock_object(share_types, 'get_extra_specs_from_share')
3907
+        self.mock_object(self.library, '_check_extra_specs_validity',
3908
+                         mock.Mock(side_effect=side_effect_1))
3909
+        self.mock_object(self.library,
3910
+                         '_check_aggregate_extra_specs_validity',
3911
+                         mock.Mock(side_effect=side_effect_2))
3912
+        self.mock_object(data_motion, 'get_backend_configuration')
3913
+
3914
+        migration_compatibility = self.library.migration_check_compatibility(
3915
+            self.context, fake_share.fake_share_instance(),
3916
+            fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
3917
+            destination_share_server=None)
3918
+
3919
+        expected_compatibility = {
3920
+            'compatible': False,
3921
+            'writable': False,
3922
+            'nondisruptive': False,
3923
+            'preserve_metadata': False,
3924
+            'preserve_snapshots': False,
3925
+        }
3926
+        self.assertDictMatch(expected_compatibility, migration_compatibility)
3927
+        mock_exception_log.assert_called_once()
3928
+        self.assertFalse(data_motion.get_backend_configuration.called)
3929
+
3897 3930
     def test_migration_check_compatibility_destination_not_configured(self):
3898 3931
         self.library._have_cluster_creds = True
3899 3932
         self.mock_object(self.library, '_get_backend_share_name',
@@ -3905,6 +3938,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3905 3938
         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
3906 3939
         self.mock_object(share_utils, 'extract_host', mock.Mock(
3907 3940
             return_value='destination_backend'))
3941
+        self.mock_object(share_types, 'get_extra_specs_from_share')
3942
+        self.mock_object(self.library, '_check_extra_specs_validity')
3943
+        self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
3908 3944
         mock_vserver_compatibility_check = self.mock_object(
3909 3945
             self.library, '_check_destination_vserver_for_vol_move')
3910 3946
 
@@ -3936,6 +3972,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3936 3972
             (exception.InvalidParameterValue, ('dest_vserver', None))))
3937 3973
     def test_migration_check_compatibility_errors(self, side_effects):
3938 3974
         self.library._have_cluster_creds = True
3975
+        self.mock_object(share_types, 'get_extra_specs_from_share')
3976
+        self.mock_object(self.library, '_check_extra_specs_validity')
3977
+        self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
3939 3978
         self.mock_object(self.library, '_get_backend_share_name',
3940 3979
                          mock.Mock(return_value=fake.SHARE_NAME))
3941 3980
         self.mock_object(data_motion, 'get_backend_configuration')
@@ -3967,6 +4006,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3967 4006
 
3968 4007
     def test_migration_check_compatibility_incompatible_vservers(self):
3969 4008
         self.library._have_cluster_creds = True
4009
+        self.mock_object(share_types, 'get_extra_specs_from_share')
4010
+        self.mock_object(self.library, '_check_extra_specs_validity')
4011
+        self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
3970 4012
         self.mock_object(self.library, '_get_backend_share_name',
3971 4013
                          mock.Mock(return_value=fake.SHARE_NAME))
3972 4014
         self.mock_object(data_motion, 'get_backend_configuration')
@@ -4004,6 +4046,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
4004 4046
 
4005 4047
     def test_migration_check_compatibility_client_error(self):
4006 4048
         self.library._have_cluster_creds = True
4049
+        self.mock_object(share_types, 'get_extra_specs_from_share')
4050
+        self.mock_object(self.library, '_check_extra_specs_validity')
4051
+        self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
4007 4052
         self.mock_object(self.library, '_get_backend_share_name',
4008 4053
                          mock.Mock(return_value=fake.SHARE_NAME))
4009 4054
         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
@@ -4040,6 +4085,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
4040 4085
 
4041 4086
     def test_migration_check_compatibility(self):
4042 4087
         self.library._have_cluster_creds = True
4088
+        self.mock_object(share_types, 'get_extra_specs_from_share')
4089
+        self.mock_object(self.library, '_check_extra_specs_validity')
4090
+        self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
4043 4091
         self.mock_object(self.library, '_get_backend_share_name',
4044 4092
                          mock.Mock(return_value=fake.SHARE_NAME))
4045 4093
         self.mock_object(data_motion, 'get_backend_configuration')
@@ -4303,8 +4351,15 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
4303 4351
         mock_move_status_check = self.mock_object(
4304 4352
             self.library, '_get_volume_move_status',
4305 4353
             mock.Mock(side_effect=vol_move_side_effects))
4354
+        self.mock_object(share_types, 'get_extra_specs_from_share',
4355
+                         mock.Mock(return_value=fake.EXTRA_SPEC))
4356
+        self.mock_object(self.library, '_get_provisioning_options',
4357
+                         mock.Mock(return_value=fake.PROVISIONING_OPTIONS))
4358
+        self.mock_object(vserver_client, 'manage_volume')
4359
+
4306 4360
         src_share = fake_share.fake_share_instance(id='source-share-instance')
4307 4361
         dest_share = fake_share.fake_share_instance(id='dest-share-instance')
4362
+        dest_aggr = share_utils.extract_host(dest_share['host'], level='pool')
4308 4363
 
4309 4364
         data_updates = self.library.migration_complete(
4310 4365
             self.context, src_share, dest_share, source_snapshots,
@@ -4323,6 +4378,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
4323 4378
         self.library._create_export.assert_called_once_with(
4324 4379
             dest_share, fake.SHARE_SERVER, fake.VSERVER1, vserver_client,
4325 4380
             clear_current_export_policy=False)
4381
+        vserver_client.manage_volume.assert_called_once_with(
4382
+            dest_aggr, 'new_share_name', **fake.PROVISIONING_OPTIONS)
4326 4383
         mock_info_log.assert_called_once()
4327 4384
         if phase != 'completed':
4328 4385
             self.assertEqual(2, mock_warning_log.call_count)

+ 5
- 0
releasenotes/notes/bug-1704622-netapp-cdot-fix-share-specs-on-migration-bfbbebec26533652.yaml View File

@@ -0,0 +1,5 @@
1
+---
2
+fixes:
3
+  - The NetApp driver has been fixed to ensure that share type changes
4
+    during driver optimized share migration will result in correction
5
+    of share properties as per the requested extra-specs.

Loading…
Cancel
Save