VMware: Storage policy support

vSphere 6.7 added storage policy support for vStorageObject
APIs. Adding vSphere storage policy support in vStorageObject
driver.

Change-Id: I300ecddaac0d882ae32c289d183882c10e3d1aae
This commit is contained in:
Vipin Balachandran 2018-09-19 14:18:25 -07:00
parent 85c13f73f2
commit af54b296e3
5 changed files with 202 additions and 31 deletions

View File

@ -65,16 +65,19 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
self._driver = fcd.VMwareVStorageObjectDriver(
configuration=self._config)
self._driver._vc_version = self.VC_VERSION
self._driver._storage_policy_enabled = True
self._context = context.get_admin_context()
@mock.patch.object(VMDK_DRIVER, 'do_setup')
@mock.patch.object(FCD_DRIVER, 'volumeops')
def test_do_setup(self, vops, vmdk_do_setup):
self._driver._storage_policy_enabled = False
self._driver.do_setup(self._context)
vmdk_do_setup.assert_called_once_with(self._context)
self.assertFalse(self._driver._storage_policy_enabled)
vops.set_vmx_version.assert_called_once_with('vmx-13')
self.assertTrue(self._driver._use_fcd_snapshot)
self.assertTrue(self._driver._storage_policy_enabled)
def test_get_volume_stats(self):
stats = self._driver.get_volume_stats()
@ -117,8 +120,12 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
project_id)
return fake_volume.fake_volume_obj(self._context, **vol)
@mock.patch.object(FCD_DRIVER, '_get_storage_profile')
@mock.patch.object(FCD_DRIVER, '_select_datastore')
def test_select_ds_fcd(self, select_datastore):
def test_select_ds_fcd(self, select_datastore, get_storage_profile):
profile = mock.sentinel.profile
get_storage_profile.return_value = profile
datastore = mock.sentinel.datastore
summary = mock.Mock(datastore=datastore)
select_datastore.return_value = (mock.ANY, mock.ANY, summary)
@ -126,7 +133,8 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
volume = self._create_volume_obj()
ret = self._driver._select_ds_fcd(volume)
self.assertEqual(datastore, ret)
exp_req = {hub.DatastoreSelector.SIZE_BYTES: volume.size * units.Gi}
exp_req = {hub.DatastoreSelector.SIZE_BYTES: volume.size * units.Gi,
hub.DatastoreSelector.PROFILE_NAME: profile}
select_datastore.assert_called_once_with(exp_req)
@mock.patch.object(FCD_DRIVER, '_select_datastore')
@ -177,14 +185,19 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
@mock.patch.object(FCD_DRIVER, '_select_ds_fcd')
@mock.patch.object(FCD_DRIVER, '_get_disk_type')
@mock.patch.object(FCD_DRIVER, '_get_storage_profile_id')
@mock.patch.object(FCD_DRIVER, 'volumeops')
def test_create_volume(self, vops, get_disk_type, select_ds_fcd):
def test_create_volume(self, vops, get_storage_profile_id, get_disk_type,
select_ds_fcd):
ds_ref = mock.sentinel.ds_ref
select_ds_fcd.return_value = ds_ref
disk_type = mock.sentinel.disk_type
get_disk_type.return_value = disk_type
profile_id = mock.sentinel.profile_id
get_storage_profile_id.return_value = profile_id
fcd_loc = mock.Mock()
provider_loc = mock.sentinel.provider_loc
fcd_loc.provider_location.return_value = provider_loc
@ -196,7 +209,8 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
select_ds_fcd.assert_called_once_with(volume)
get_disk_type.assert_called_once_with(volume)
vops.create_fcd.assert_called_once_with(
volume.name, volume.size * units.Ki, ds_ref, disk_type)
volume.name, volume.size * units.Ki, ds_ref, disk_type,
profile_id=profile_id)
@mock.patch.object(volumeops.FcdLocation, 'from_provider_location')
@mock.patch.object(FCD_DRIVER, 'volumeops')
@ -269,10 +283,12 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
'_create_virtual_disk_from_preallocated_image')
@mock.patch.object(FCD_DRIVER, 'volumeops')
@mock.patch.object(datastore, 'DatastoreURL')
@mock.patch.object(FCD_DRIVER, '_get_storage_profile_id')
@ddt.data(vmdk.ImageDiskType.PREALLOCATED, vmdk.ImageDiskType.SPARSE,
vmdk.ImageDiskType.STREAM_OPTIMIZED)
def test_copy_image_to_volume(self,
disk_type,
get_storage_profile_id,
datastore_url_cls,
vops,
create_disk_from_preallocated_image,
@ -303,6 +319,9 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
ds_url = mock.sentinel.ds_url
datastore_url_cls.return_value = ds_url
profile_id = mock.sentinel.profile_id
get_storage_profile_id.return_value = profile_id
fcd_loc = mock.Mock()
provider_location = mock.sentinel.provider_location
fcd_loc.provider_location.return_value = provider_location
@ -331,6 +350,7 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
str(ds_url),
volume.name,
summary.datastore)
vops.update_fcd_policy.assert_called_once_with(fcd_loc, profile_id)
@mock.patch.object(volumeops.FcdLocation, 'from_provider_location')
@mock.patch.object(FCD_DRIVER, 'volumeops')
@ -420,7 +440,7 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
self.assertEqual(dest_fcd_loc, ret)
from_provider_loc.assert_called_once_with(provider_loc)
vops.clone_fcd.assert_called_once_with(
name, fcd_loc, dest_ds_ref, disk_type)
name, fcd_loc, dest_ds_ref, disk_type, profile_id=None)
@mock.patch.object(FCD_DRIVER, '_select_ds_fcd')
@mock.patch.object(FCD_DRIVER, '_clone_fcd')
@ -519,16 +539,21 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
@mock.patch.object(FCD_DRIVER, '_select_ds_fcd')
@mock.patch.object(FCD_DRIVER, '_get_disk_type')
@mock.patch.object(FCD_DRIVER, '_get_storage_profile_id')
@mock.patch.object(FCD_DRIVER, '_clone_fcd')
@mock.patch.object(FCD_DRIVER, '_extend_if_needed')
def test_create_volume_from_fcd(
self, extend_if_needed, clone_fcd, get_disk_type, select_ds_fcd):
self, extend_if_needed, clone_fcd, get_storage_profile_id,
get_disk_type, select_ds_fcd):
ds_ref = mock.sentinel.ds_ref
select_ds_fcd.return_value = ds_ref
disk_type = mock.sentinel.disk_type
get_disk_type.return_value = disk_type
profile_id = mock.sentinel.profile_id
get_storage_profile_id.return_value = profile_id
cloned_fcd_loc = mock.Mock()
dest_provider_loc = mock.sentinel.dest_provider_loc
cloned_fcd_loc.provider_location.return_value = dest_provider_loc
@ -543,17 +568,19 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
select_ds_fcd.test_assert_called_once_with(volume)
get_disk_type.test_assert_called_once_with(volume)
clone_fcd.assert_called_once_with(
provider_loc, volume.name, ds_ref, disk_type=disk_type)
provider_loc, volume.name, ds_ref, disk_type=disk_type,
profile_id=profile_id)
extend_if_needed.assert_called_once_with(
cloned_fcd_loc, cur_size, volume.size)
@mock.patch.object(FCD_DRIVER, '_create_volume_from_fcd')
@mock.patch.object(volumeops.FcdSnapshotLocation, 'from_provider_location')
@mock.patch.object(FCD_DRIVER, '_get_storage_profile_id')
@mock.patch.object(FCD_DRIVER, 'volumeops')
@mock.patch.object(FCD_DRIVER, '_extend_if_needed')
def _test_create_volume_from_snapshot(
self, extend_if_needed, vops, from_provider_loc,
create_volume_from_fcd, use_fcd_snapshot=False):
self, extend_if_needed, vops, get_storage_profile_id,
from_provider_loc, create_volume_from_fcd, use_fcd_snapshot=False):
src_volume = self._create_volume_obj(vol_id=self.SRC_VOL_ID)
snapshot = fake_snapshot.fake_snapshot_obj(
self._context, volume=src_volume)
@ -563,6 +590,9 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
fcd_snap_loc = mock.sentinel.fcd_snap_loc
from_provider_loc.return_value = fcd_snap_loc
profile_id = mock.sentinel.profile_id
get_storage_profile_id.return_value = profile_id
fcd_loc = mock.Mock()
provider_loc = mock.sentinel.provider_loc
fcd_loc.provider_location.return_value = provider_loc
@ -574,7 +604,7 @@ class VMwareVStorageObjectDriverTestCase(test.TestCase):
if use_fcd_snapshot:
self.assertEqual({'provider_location': provider_loc}, ret)
vops.create_fcd_from_snapshot.assert_called_once_with(
fcd_snap_loc, volume.name)
fcd_snap_loc, volume.name, profile_id=profile_id)
extend_if_needed.assert_called_once_with(
fcd_loc, snapshot.volume_size, volume.size)
else:

View File

@ -1925,13 +1925,18 @@ class VolumeOpsTestCase(test.TestCase):
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_fcd_backing_spec')
def test_create_fcd(self, create_fcd_backing_spec):
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_profile_spec')
def test_create_fcd(self, create_profile_spec, create_fcd_backing_spec):
spec = mock.Mock()
self.session.vim.client.factory.create.return_value = spec
backing_spec = mock.sentinel.backing_spec
create_fcd_backing_spec.return_value = backing_spec
profile_spec = mock.sentinel.profile_spec
create_profile_spec.return_value = profile_spec
task = mock.sentinel.task
self.session.invoke_api.return_value = task
@ -1945,7 +1950,9 @@ class VolumeOpsTestCase(test.TestCase):
ds_ref_val = mock.sentinel.ds_ref_val
ds_ref = mock.Mock(value=ds_ref_val)
disk_type = mock.sentinel.disk_type
ret = self.vops.create_fcd(name, size_mb, ds_ref, disk_type)
profile_id = mock.sentinel.profile_id
ret = self.vops.create_fcd(
name, size_mb, ds_ref, disk_type, profile_id=profile_id)
self.assertEqual(fcd_id, ret.fcd_id)
self.assertEqual(ds_ref_val, ret.ds_ref_val)
@ -1955,6 +1962,9 @@ class VolumeOpsTestCase(test.TestCase):
self.assertEqual(1024, spec.capacityInMB)
self.assertEqual(name, spec.name)
self.assertEqual(backing_spec, spec.backingSpec)
self.assertEqual([profile_spec], spec.profile)
create_profile_spec.assert_called_once_with(
self.session.vim.client.factory, profile_id)
self.session.invoke_api.assert_called_once_with(
self.session.vim,
'CreateDisk_Task',
@ -1983,13 +1993,18 @@ class VolumeOpsTestCase(test.TestCase):
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_fcd_backing_spec')
def test_clone_fcd(self, create_fcd_backing_spec):
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_profile_spec')
def test_clone_fcd(self, create_profile_spec, create_fcd_backing_spec):
spec = mock.Mock()
self.session.vim.client.factory.create.return_value = spec
backing_spec = mock.sentinel.backing_spec
create_fcd_backing_spec.return_value = backing_spec
profile_spec = mock.sentinel.profile_spec
create_profile_spec.return_value = profile_spec
task = mock.sentinel.task
self.session.invoke_api.return_value = task
@ -2008,7 +2023,9 @@ class VolumeOpsTestCase(test.TestCase):
dest_ds_ref_val = mock.sentinel.dest_ds_ref_val
dest_ds_ref = mock.Mock(value=dest_ds_ref_val)
disk_type = mock.sentinel.disk_type
ret = self.vops.clone_fcd(name, fcd_location, dest_ds_ref, disk_type)
profile_id = mock.sentinel.profile_id
ret = self.vops.clone_fcd(
name, fcd_location, dest_ds_ref, disk_type, profile_id=profile_id)
self.assertEqual(fcd_id, ret.fcd_id)
self.assertEqual(dest_ds_ref_val, ret.ds_ref_val)
@ -2017,6 +2034,9 @@ class VolumeOpsTestCase(test.TestCase):
create_fcd_backing_spec.assert_called_once_with(disk_type, dest_ds_ref)
self.assertEqual(name, spec.name)
self.assertEqual(backing_spec, spec.backingSpec)
self.assertEqual([profile_spec], spec.profile)
create_profile_spec.assert_called_once_with(
self.session.vim.client.factory, profile_id)
self.session.invoke_api.assert_called_once_with(
self.session.vim,
'CloneVStorageObject_Task',
@ -2172,10 +2192,15 @@ class VolumeOpsTestCase(test.TestCase):
snapshotId=fcd_snap_id)
self.session.wait_for_task(task)
def test_create_fcd_from_snapshot(self):
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_profile_spec')
def test_create_fcd_from_snapshot(self, create_profile_spec):
task = mock.sentinel.task
self.session.invoke_api.return_value = task
profile_spec = mock.sentinel.profile_spec
create_profile_spec.return_value = profile_spec
task_info = mock.Mock()
fcd_id = mock.sentinel.fcd_id
task_info.result.config.id.id = fcd_id
@ -2192,10 +2217,14 @@ class VolumeOpsTestCase(test.TestCase):
fcd_snap_loc.id.return_value = fcd_snap_id
name = mock.sentinel.name
ret = self.vops.create_fcd_from_snapshot(fcd_snap_loc, name)
profile_id = mock.sentinel.profile_id
ret = self.vops.create_fcd_from_snapshot(
fcd_snap_loc, name, profile_id=profile_id)
self.assertEqual(fcd_id, ret.fcd_id)
self.assertEqual(ds_ref_val, ret.ds_ref_val)
create_profile_spec.assert_called_once_with(
self.session.vim.client.factory, profile_id)
self.session.invoke_api.assert_called_once_with(
self.session.vim,
'CreateDiskFromSnapshot_Task',
@ -2203,9 +2232,48 @@ class VolumeOpsTestCase(test.TestCase):
id=fcd_id,
datastore=ds_ref,
snapshotId=fcd_snap_id,
name=name)
name=name,
profile=[profile_spec])
self.session.wait_for_task.assert_called_once_with(task)
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
'_create_profile_spec')
@ddt.data(mock.sentinel.profile_id, None)
def test_update_fcd_policy(self, profile_id, create_profile_spec):
cf = self.session.vim.client.factory
if profile_id:
profile_spec = mock.sentinel.profile_spec
create_profile_spec.return_value = profile_spec
else:
empty_profile_spec = mock.sentinel.empty_profile_spec
cf.create.return_value = empty_profile_spec
task = mock.sentinel.task
self.session.invoke_api.return_value = task
fcd_location = mock.Mock()
fcd_id = mock.sentinel.fcd_id
fcd_location.id.return_value = fcd_id
ds_ref = mock.Mock()
fcd_location.ds_ref.return_value = ds_ref
self.vops.update_fcd_policy(fcd_location, profile_id)
if profile_id:
create_profile_spec.assert_called_once_with(cf, profile_id)
exp_profile_spec = profile_spec
else:
cf.create.assert_called_once_with(
'ns0:VirtualMachineEmptyProfileSpec')
exp_profile_spec = empty_profile_spec
self.session.invoke_api.assert_called_once_with(
self.session.vim,
'UpdateVStorageObjectPolicy_Task',
self.session.vim.service_content.vStorageObjectManager,
id=fcd_id,
datastore=ds_ref,
profile=[exp_profile_spec])
self.session.wait_for_task(task)
class VirtualDiskPathTest(test.TestCase):
"""Unit tests for VirtualDiskPath."""

View File

@ -44,7 +44,8 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
# 1.0 - initial version based on vSphere 6.5 vStorageObject APIs
# 1.1 - support for vStorageObject snapshot APIs
VERSION = '1.1.0'
# 1.2 - support for SPBM storage policies
VERSION = '1.2.0'
# ThirdPartySystems wiki page
CI_WIKI_NAME = "VMware_CI"
@ -60,10 +61,11 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
:param context: The admin context.
"""
super(VMwareVStorageObjectDriver, self).do_setup(context)
self._storage_policy_enabled = False
self.volumeops.set_vmx_version('vmx-13')
self._use_fcd_snapshot = versionutils.is_compatible(
vc_67_compatible = versionutils.is_compatible(
'6.7.0', self._vc_version, same_major=False)
self._use_fcd_snapshot = vc_67_compatible
self._storage_policy_enabled = vc_67_compatible
def get_volume_stats(self, refresh=False):
"""Collects volume backend stats.
@ -80,6 +82,10 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
def _select_ds_fcd(self, volume):
req = {}
req[hub.DatastoreSelector.SIZE_BYTES] = volume.size * units.Gi
if self._storage_policy_enabled:
req[hub.DatastoreSelector.PROFILE_NAME] = (
self._get_storage_profile(volume))
(_host_ref, _resource_pool, summary) = self._select_datastore(req)
return summary.datastore
@ -106,6 +112,12 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
VMwareVStorageObjectDriver, self)._get_disk_type(volume)
return vops.VirtualDiskType.get_virtual_disk_type(extra_spec_disk_type)
def _get_storage_profile_id(self, volume):
if self._storage_policy_enabled:
return super(
VMwareVStorageObjectDriver, self)._get_storage_profile_id(
volume)
def create_volume(self, volume):
"""Create a new volume on the backend.
@ -114,8 +126,10 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
"""
disk_type = self._get_disk_type(volume)
ds_ref = self._select_ds_fcd(volume)
profile_id = self._get_storage_profile_id(volume)
fcd_loc = self.volumeops.create_fcd(
volume.name, volume.size * units.Ki, ds_ref, disk_type)
volume.name, volume.size * units.Ki, ds_ref, disk_type,
profile_id=profile_id)
return {'provider_location': fcd_loc.provider_location()}
def _delete_fcd(self, provider_loc):
@ -204,6 +218,11 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
fcd_loc = self.volumeops.register_disk(
str(vmdk_url), volume.name, summary.datastore)
profile_id = self._get_storage_profile_id(volume)
if profile_id:
self.volumeops.update_fcd_policy(fcd_loc, profile_id)
return {'provider_location': fcd_loc.provider_location()}
def copy_volume_to_image(self, context, volume, image_service, image_meta):
@ -264,9 +283,11 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
self.volumeops.extend_fcd(fcd_loc, new_size * units.Ki)
def _clone_fcd(self, provider_loc, name, dest_ds_ref,
disk_type=vops.VirtualDiskType.THIN):
disk_type=vops.VirtualDiskType.THIN,
profile_id=None):
fcd_loc = vops.FcdLocation.from_provider_location(provider_loc)
return self.volumeops.clone_fcd(name, fcd_loc, dest_ds_ref, disk_type)
return self.volumeops.clone_fcd(
name, fcd_loc, dest_ds_ref, disk_type, profile_id=profile_id)
def create_snapshot(self, snapshot):
"""Creates a snapshot.
@ -309,8 +330,10 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
def _create_volume_from_fcd(self, provider_loc, cur_size, volume):
ds_ref = self._select_ds_fcd(volume)
disk_type = self._get_disk_type(volume)
profile_id = self._get_storage_profile_id(volume)
cloned_fcd_loc = self._clone_fcd(
provider_loc, volume.name, ds_ref, disk_type=disk_type)
provider_loc, volume.name, ds_ref, disk_type=disk_type,
profile_id=profile_id)
self._extend_if_needed(cloned_fcd_loc, cur_size, volume.size)
return {'provider_location': cloned_fcd_loc.provider_location()}
@ -324,8 +347,9 @@ class VMwareVStorageObjectDriver(vmdk.VMwareVcVmdkDriver):
fcd_snap_loc = vops.FcdSnapshotLocation.from_provider_location(
snapshot.provider_location)
if fcd_snap_loc:
profile_id = self._get_storage_profile_id(volume)
fcd_loc = self.volumeops.create_fcd_from_snapshot(
fcd_snap_loc, volume.name)
fcd_snap_loc, volume.name, profile_id=profile_id)
self._extend_if_needed(fcd_loc, snapshot.volume_size, volume.size)
return {'provider_location': fcd_loc.provider_location()}
else:

View File

@ -1783,12 +1783,22 @@ class VMwareVolumeOps(object):
backing_spec.datastore = ds_ref
return backing_spec
def create_fcd(self, name, size_mb, ds_ref, disk_type):
spec = self._session.vim.client.factory.create('ns0:VslmCreateSpec')
def _create_profile_spec(self, cf, profile_id):
profile_spec = cf.create('ns0:VirtualMachineDefinedProfileSpec')
profile_spec.profileId = profile_id
return profile_spec
def create_fcd(self, name, size_mb, ds_ref, disk_type, profile_id=None):
cf = self._session.vim.client.factory
spec = cf.create('ns0:VslmCreateSpec')
spec.capacityInMB = size_mb
spec.name = name
spec.backingSpec = self._create_fcd_backing_spec(disk_type, ds_ref)
if profile_id:
profile_spec = self._create_profile_spec(cf, profile_id)
spec.profile = [profile_spec]
LOG.debug("Creating fcd with spec: %(spec)s on datastore: %(ds_ref)s.",
{'spec': spec, 'ds_ref': ds_ref})
vstorage_mgr = self._session.vim.service_content.vStorageObjectManager
@ -1812,13 +1822,18 @@ class VMwareVolumeOps(object):
datastore=fcd_location.ds_ref())
self._session.wait_for_task(task)
def clone_fcd(self, name, fcd_location, dest_ds_ref, disk_type):
def clone_fcd(
self, name, fcd_location, dest_ds_ref, disk_type, profile_id=None):
cf = self._session.vim.client.factory
spec = cf.create('ns0:VslmCloneSpec')
spec.name = name
spec.backingSpec = self._create_fcd_backing_spec(disk_type,
dest_ds_ref)
if profile_id:
profile_spec = self._create_profile_spec(cf, profile_id)
spec.profile = [profile_spec]
LOG.debug("Copying fcd: %(fcd_loc)s to datastore: %(ds_ref)s with "
"spec: %(spec)s.",
{'fcd_loc': fcd_location,
@ -1921,12 +1936,16 @@ class VMwareVolumeOps(object):
snapshotId=fcd_snap_loc.id(cf))
self._session.wait_for_task(task)
def create_fcd_from_snapshot(self, fcd_snap_loc, name):
def create_fcd_from_snapshot(self, fcd_snap_loc, name, profile_id=None):
LOG.debug("Creating fcd with name: %(name)s from fcd snapshot: "
"%(snap)s.", {'name': name, 'snap': fcd_snap_loc})
vstorage_mgr = self._session.vim.service_content.vStorageObjectManager
cf = self._session.vim.client.factory
if profile_id:
profile = [self._create_profile_spec(cf, profile_id)]
else:
profile = None
task = self._session.invoke_api(
self._session.vim,
'CreateDiskFromSnapshot_Task',
@ -1934,7 +1953,8 @@ class VMwareVolumeOps(object):
id=fcd_snap_loc.fcd_loc.id(cf),
datastore=fcd_snap_loc.fcd_loc.ds_ref(),
snapshotId=fcd_snap_loc.id(cf),
name=name)
name=name,
profile=profile)
task_info = self._session.wait_for_task(task)
fcd_loc = FcdLocation.create(task_info.result.config.id,
fcd_snap_loc.fcd_loc.ds_ref())
@ -1942,6 +1962,27 @@ class VMwareVolumeOps(object):
LOG.debug("Created fcd: %s.", fcd_loc)
return fcd_loc
def update_fcd_policy(self, fcd_location, profile_id):
LOG.debug("Changing fcd: %(fcd_loc)s storage policy to %(policy)s.",
{'fcd_loc': fcd_location, 'policy': profile_id})
vstorage_mgr = self._session.vim.service_content.vStorageObjectManager
cf = self._session.vim.client.factory
if profile_id is None:
profile_spec = cf.create('ns0:VirtualMachineEmptyProfileSpec')
else:
profile_spec = self._create_profile_spec(cf, profile_id)
task = self._session.invoke_api(
self._session.vim,
'UpdateVStorageObjectPolicy_Task',
vstorage_mgr,
id=fcd_location.id(cf),
datastore=fcd_location.ds_ref(),
profile=[profile_spec])
self._session.wait_for_task(task)
LOG.debug("Updated fcd storage policy to %s.", profile_id)
class FcdLocation(object):

View File

@ -0,0 +1,8 @@
---
features:
- |
Added vSphere storage policy support in VMwareVStorageObjectDriver.
The storage policies that must be associated with the volumes can
be specified using volume type extra-spec key 'vmware:storage_profile'
similar to VMware VMDK driver. The vSphere version must be 6.7 or
above to use this feature.