From: Vipin Balachandran <vbala@vmware.com>
Date: Thu, 17 Dec 2015 07:57:47 +0000 (-0800)
Subject: VMware: Add support for VVOL datastores
X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=8df5f91dd2ac8415c271a8897cc6703c73736221;p=openstack-build%2Fcinder-build.git

VMware: Add support for VVOL datastores

vCenter 6.0 added support for a new type of datastore called VVOL
datastore. A VVOL datastore represents a storage container which
is a logical grouping of virtual volumes in an array that supports
VVOL. A virtual disk in a VVOL datastore corresponds to a virtual
volume in the array. Since VVOL datastores are treated like VMFS
or NFS datastores by vCenter APIs, the changes in the VMDK driver
to support VVOL datastores are minimal.

This patch adds the following changes in the VMDK driver to support
VVOL datastores:

* Add VVOL datastore type to the list of allowed datastore types

* Skip VVOL datastore while creating a volume from a preallocated
glance image because it involves replacing the data file of a
temporary virtual disk with the downloaded preallocated image
which VVOL cannot support.

Implements: blueprint vmdk-vvol-support
Change-Id: I528e4caed616dfd9bd85c7de113024bea6709fc1
---

diff --git a/cinder/tests/unit/test_vmware_vmdk.py b/cinder/tests/unit/test_vmware_vmdk.py
index e867fdb61..cb1006975 100644
--- a/cinder/tests/unit/test_vmware_vmdk.py
+++ b/cinder/tests/unit/test_vmware_vmdk.py
@@ -687,6 +687,32 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
             dc_ref, src_path, dc_ref, dest_path)
         self.assertEqual(dest_path, ret)
 
+    @mock.patch.object(VMDK_DRIVER, '_select_datastore')
+    @mock.patch.object(VMDK_DRIVER, 'volumeops')
+    def test_get_temp_image_folder(self, vops, select_datastore):
+        host = mock.sentinel.host
+        resource_pool = mock.sentinel.rp
+        summary = mock.Mock()
+        ds_name = mock.sentinel.ds_name
+        summary.name = ds_name
+        select_datastore.return_value = (host, resource_pool, summary)
+
+        dc = mock.sentinel.dc
+        vops.get_dc.return_value = dc
+
+        image_size = 2 * units.Gi
+        ret = self._driver._get_temp_image_folder(image_size)
+
+        self.assertEqual((dc, ds_name, vmdk.TMP_IMAGES_DATASTORE_FOLDER_PATH),
+                         ret)
+        exp_req = {
+            hub.DatastoreSelector.SIZE_BYTES: image_size,
+            hub.DatastoreSelector.HARD_AFFINITY_DS_TYPE:
+                {hub.DatastoreType.VMFS, hub.DatastoreType.NFS}}
+        select_datastore.assert_called_once_with(exp_req)
+        vops.create_datastore_folder.assert_called_once_with(
+            ds_name, vmdk.TMP_IMAGES_DATASTORE_FOLDER_PATH, dc)
+
     @mock.patch.object(VMDK_DRIVER, '_select_ds_for_volume')
     @mock.patch.object(VMDK_DRIVER, '_get_storage_profile_id')
     @mock.patch('cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver.'
diff --git a/cinder/volume/drivers/vmware/datastore.py b/cinder/volume/drivers/vmware/datastore.py
index e2a46a5a5..ec7b8b17e 100644
--- a/cinder/volume/drivers/vmware/datastore.py
+++ b/cinder/volume/drivers/vmware/datastore.py
@@ -35,8 +35,9 @@ class DatastoreType(object):
     NFS = "nfs"
     VMFS = "vmfs"
     VSAN = "vsan"
+    VVOL = "vvol"
 
-    _ALL_TYPES = {NFS, VMFS, VSAN}
+    _ALL_TYPES = {NFS, VMFS, VSAN, VVOL}
 
     @staticmethod
     def get_all_types():
diff --git a/cinder/volume/drivers/vmware/vmdk.py b/cinder/volume/drivers/vmware/vmdk.py
index d01b87ebc..6903e0322 100644
--- a/cinder/volume/drivers/vmware/vmdk.py
+++ b/cinder/volume/drivers/vmware/vmdk.py
@@ -731,10 +731,11 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
         # Form requirements for datastore selection.
         req = {}
         req[hub.DatastoreSelector.SIZE_BYTES] = image_size_in_bytes
-        # vSAN datastores don't support virtual disk with
+        # vSAN/VVOL datastores don't support virtual disk with
         # flat extent; skip such datastores.
         req[hub.DatastoreSelector.HARD_AFFINITY_DS_TYPE] = (
-            hub.DatastoreType.get_all_types() - {hub.DatastoreType.VSAN})
+            hub.DatastoreType.get_all_types() -
+            {hub.DatastoreType.VSAN, hub.DatastoreType.VVOL})
 
         # Select datastore satisfying the requirements.
         (host_ref, _resource_pool, summary) = self._select_datastore(req)