From 9b418e76ac5d9447fc3dbc3a2299639930535ccb Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Mon, 14 Dec 2020 16:26:08 +0200 Subject: [PATCH] smbfs: set VHD UUID using volume UUID The SMBFS driver stores volumes as VHD/x image files. This change will set the unique id VHD field using the volume id. Hyper-V propagates this id to the guest through the SCSI VPD, which allows it to safely identify the disk. The kubernetes openstack provider will also benefit from this change. Here's an example: http://paste.openstack.org/raw/801011/ This operation requires os-win 5.4.0, for which reason we're bumping the requirement. Depends-On: Ied73997e6f5f3ded9827703867f059ef3dfca159 Change-Id: I459ff3c8798e218919b6b2f9e1c2200203efeeff --- cinder/tests/unit/windows/test_smbfs.py | 33 ++++++++++++++++++++++++- cinder/volume/drivers/windows/smbfs.py | 19 ++++++++++++-- lower-constraints.txt | 2 +- requirements.txt | 2 +- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/cinder/tests/unit/windows/test_smbfs.py b/cinder/tests/unit/windows/test_smbfs.py index 3636b35fb4f..5a76b7ecaac 100644 --- a/cinder/tests/unit/windows/test_smbfs.py +++ b/cinder/tests/unit/windows/test_smbfs.py @@ -428,7 +428,8 @@ class WindowsSmbFsTestCase(test.TestCase): self._smbfs_driver._do_create_volume(self.volume) fake_create.assert_called_once_with( fake_vol_path, mock_get_vhd_type.return_value, - max_internal_size=self.volume.size << 30) + max_internal_size=self.volume.size << 30, + guid=self.volume.id) def test_create_volume(self): self._test_create_volume() @@ -820,6 +821,9 @@ class WindowsSmbFsTestCase(test.TestCase): self._FAKE_VOLUME_PATH, self.volume.size * units.Gi, is_file_max_size=False) + drv._vhdutils.set_vhd_guid.assert_called_once_with( + self._FAKE_VOLUME_PATH, + self.volume.id) @mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_vhd_type') def test_copy_volume_from_snapshot(self, mock_get_vhd_type): @@ -842,6 +846,9 @@ class WindowsSmbFsTestCase(test.TestCase): self._FAKE_VOLUME_PATH, mock.sentinel.new_volume_path, vhd_type=mock_get_vhd_type.return_value) + drv._vhdutils.set_vhd_guid.assert_called_once_with( + mock.sentinel.new_volume_path, + self.volume.id) drv._vhdutils.resize_vhd.assert_called_once_with( mock.sentinel.new_volume_path, self.volume.size * units.Gi, @@ -921,3 +928,27 @@ class WindowsSmbFsTestCase(test.TestCase): self._vhdutils.get_vhd_format.assert_called_once_with( mock.sentinel.image_path) + + @mock.patch.object(remotefs.RemoteFSManageableVolumesMixin, + 'manage_existing') + def test_manage_existing(self, remotefs_manage): + model_update = dict(provider_location=self._FAKE_SHARE) + remotefs_manage.return_value = model_update + self._smbfs_driver.local_path = mock.Mock( + return_value=mock.sentinel.vol_path) + + # Let's make sure that the provider location gets set. + # It's needed by self.local_path. + self.volume.provider_location = None + + ret_val = self._smbfs_driver.manage_existing( + self.volume, mock.sentinel.ref) + + self.assertEqual(model_update, ret_val) + self.assertEqual(self._FAKE_SHARE, self.volume.provider_location) + + self._vhdutils.set_vhd_guid.assert_called_once_with( + mock.sentinel.vol_path, + self.volume.id) + self._smbfs_driver.local_path.assert_called_once_with(self.volume) + remotefs_manage.assert_called_once_with(self.volume, mock.sentinel.ref) diff --git a/cinder/volume/drivers/windows/smbfs.py b/cinder/volume/drivers/windows/smbfs.py index b9362f4822e..3b53556ea9d 100644 --- a/cinder/volume/drivers/windows/smbfs.py +++ b/cinder/volume/drivers/windows/smbfs.py @@ -335,7 +335,8 @@ class WindowsSmbfsDriver(remotefs_drv.RevertToSnapshotMixin, vhd_type = self._get_vhd_type() self._vhdutils.create_vhd(volume_path, vhd_type, - max_internal_size=volume_size_bytes) + max_internal_size=volume_size_bytes, + guid=volume.id) def _ensure_share_mounted(self, smbfs_share): mnt_flags = None @@ -602,7 +603,9 @@ class WindowsSmbfsDriver(remotefs_drv.RevertToSnapshotMixin, self.configuration.volume_dd_blocksize, volume_subformat) - self._vhdutils.resize_vhd(self.local_path(volume), + volume_path = self.local_path(volume) + self._vhdutils.set_vhd_guid(volume_path, volume.id) + self._vhdutils.resize_vhd(volume_path, volume.size * units.Gi, is_file_max_size=False) @@ -637,6 +640,7 @@ class WindowsSmbfsDriver(remotefs_drv.RevertToSnapshotMixin, self._vhdutils.convert_vhd(snapshot_path, volume_path, vhd_type=vhd_type) + self._vhdutils.set_vhd_guid(volume_path, volume.id) self._vhdutils.resize_vhd(volume_path, volume_size * units.Gi, is_file_max_size=False) @@ -677,6 +681,17 @@ class WindowsSmbfsDriver(remotefs_drv.RevertToSnapshotMixin, return os.path.join(volume_location['mountpoint'], volume.name + ".%s" % fmt).lower() + def manage_existing(self, volume, existing_ref): + model_update = super(WindowsSmbfsDriver, self).manage_existing( + volume, existing_ref) + + volume.provider_location = model_update['provider_location'] + volume_path = self.local_path(volume) + + self._vhdutils.set_vhd_guid(volume_path, volume.id) + + return model_update + def _set_rw_permissions(self, path): # The SMBFS driver does not manage file permissions. We chose # to let this up to the deployer. diff --git a/lower-constraints.txt b/lower-constraints.txt index 53283e51fb4..5ecd707f644 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -54,7 +54,7 @@ networkx==2.5 oauth2client==4.1.3 os-api-ref==1.4.0 os-brick==4.2.0 -os-win==5.1.0 +os-win==5.4.0 oslo.cache==2.6.1 oslo.concurrency==4.3.0 oslo.config==8.3.2 diff --git a/requirements.txt b/requirements.txt index 4d316748311..5e303247fb6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,7 @@ WebOb>=1.8.6 # MIT oslo.i18n>=5.0.1 # Apache-2.0 oslo.vmware>=3.7.0 # Apache-2.0 os-brick>=4.2.0 # Apache-2.0 -os-win>=5.1.0 # Apache-2.0 +os-win>=5.4.0 # Apache-2.0 tooz>=2.7.1 # Apache-2.0 google-api-python-client>=1.11.0 # Apache-2.0 castellan>=3.6.0 # Apache-2.0