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:
parent
85c13f73f2
commit
af54b296e3
@ -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:
|
||||
|
@ -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."""
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user