diff --git a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/BUILD index 5354b9e31b13..506240f67642 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/BUILD @@ -19,6 +19,7 @@ go_library( deps = [ "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers/aws:go_default_library", + "//pkg/features:go_default_library", "//pkg/util/mount:go_default_library", "//pkg/util/strings:go_default_library", "//pkg/volume:go_default_library", @@ -29,6 +30,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go index 869d06773c10..630aefc42464 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go @@ -29,7 +29,9 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/mount" kstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" @@ -508,5 +510,9 @@ func (c *awsElasticBlockStoreProvisioner) Provision() (*v1.PersistentVolume, err } } + if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { + pv.Spec.VolumeMode = c.options.PVC.Spec.VolumeMode + } + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD index 163c75e25240..794b9294cb4f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/BUILD @@ -55,6 +55,7 @@ go_library( "//pkg/apis/core:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers/azure:go_default_library", + "//pkg/features:go_default_library", "//pkg/util/keymutex:go_default_library", "//pkg/util/mount:go_default_library", "//pkg/util/strings:go_default_library", @@ -69,6 +70,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_provision.go b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_provision.go index 6888bfc4ee90..5153582e4a98 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_provision.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_provision.go @@ -71,6 +71,10 @@ func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) { } supportedModes := p.plugin.GetAccessModes() + if util.CheckPersistentVolumeClaimModeBlock(p.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", p.plugin.GetPluginName()) + } + // perform static validation first if p.options.PVC.Spec.Selector != nil { return nil, fmt.Errorf("azureDisk - claim.Spec.Selector is not supported for dynamic provisioning on Azure disk") @@ -187,5 +191,6 @@ func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) { MountOptions: p.options.MountOptions, }, } + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go b/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go index dc155334ff91..ca344c7061e4 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go @@ -135,6 +135,9 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) { if !util.AccessModesContainedInAll(a.plugin.GetAccessModes(), a.options.PVC.Spec.AccessModes) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", a.options.PVC.Spec.AccessModes, a.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(a.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", a.plugin.GetPluginName()) + } var sku, location, account string diff --git a/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go b/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go index 121972c46138..5216c8dee911 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go @@ -508,6 +508,10 @@ func (c *cinderVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) + } + volumeID, sizeGB, labels, fstype, err := c.manager.CreateVolume(c) if err != nil { return nil, err diff --git a/vendor/k8s.io/kubernetes/pkg/volume/flocker/flocker_volume.go b/vendor/k8s.io/kubernetes/pkg/volume/flocker/flocker_volume.go index d7f245d15a23..ef81dd7cc269 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/flocker/flocker_volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/flocker/flocker_volume.go @@ -67,6 +67,10 @@ func (c *flockerVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { return nil, fmt.Errorf("Provisioning failed: Specified unsupported selector") } + if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) + } + datasetUUID, sizeGB, labels, err := c.manager.CreateVolume(c) if err != nil { return nil, err diff --git a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go index 8c78c6754af3..9c2be1c8133f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go @@ -27,6 +27,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/mount" kstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" @@ -448,5 +450,9 @@ func (c *gcePersistentDiskProvisioner) Provision() (*v1.PersistentVolume, error) } } + if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { + pv.Spec.VolumeMode = c.options.PVC.Spec.VolumeMode + } + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go b/vendor/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go index d77eb5898bb2..f7653bb71cf0 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go @@ -676,6 +676,11 @@ func (p *glusterfsVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { glog.V(4).Infof("not able to parse your claim Selector") return nil, fmt.Errorf("not able to parse your claim Selector") } + + if volutil.CheckPersistentVolumeClaimModeBlock(p.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", p.plugin.GetPluginName()) + } + glog.V(4).Infof("Provision VolumeOptions %v", p.options) scName := v1helper.GetPersistentVolumeClaimClass(p.options.PVC) cfg, err := parseClassParameters(p.options.Parameters, p.plugin.host.GetKubeClient()) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go index 4a3cb76b6af2..178a8248905d 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go @@ -266,6 +266,10 @@ type hostPathProvisioner struct { // Create for hostPath simply creates a local /tmp/hostpath_pv/%s directory as a new PersistentVolume. // This Provisioner is meant for development and testing only and WILL NOT WORK in a multi-node cluster. func (r *hostPathProvisioner) Provision() (*v1.PersistentVolume, error) { + if util.CheckPersistentVolumeClaimModeBlock(r.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", r.plugin.GetPluginName()) + } + fullpath := fmt.Sprintf("/tmp/hostpath_pv/%s", uuid.NewUUID()) capacity := r.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] diff --git a/vendor/k8s.io/kubernetes/pkg/volume/photon_pd/photon_pd.go b/vendor/k8s.io/kubernetes/pkg/volume/photon_pd/photon_pd.go index 25ca23928d09..3f615ed7f2f8 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/photon_pd/photon_pd.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/photon_pd/photon_pd.go @@ -345,6 +345,10 @@ func (p *photonPersistentDiskProvisioner) Provision() (*v1.PersistentVolume, err return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", p.options.PVC.Spec.AccessModes, p.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(p.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", p.plugin.GetPluginName()) + } + pdID, sizeGB, fstype, err := p.manager.CreateVolume(p) if err != nil { return nil, err diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go index 70b6ece93666..946b78b86873 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go @@ -362,6 +362,10 @@ func (c *portworxVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) + } + volumeID, sizeGB, labels, err := c.manager.CreateVolume(c) if err != nil { return nil, err diff --git a/vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go b/vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go index 0a5990b2900b..f919166a3228 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/quobyte/quobyte.go @@ -359,6 +359,10 @@ func (provisioner *quobyteVolumeProvisioner) Provision() (*v1.PersistentVolume, return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", provisioner.options.PVC.Spec.AccessModes, provisioner.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(provisioner.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", provisioner.plugin.GetPluginName()) + } + if provisioner.options.PVC.Spec.Selector != nil { return nil, fmt.Errorf("claim Selector is not supported") } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/rbd/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/rbd/BUILD index 65042418cd43..e6b7fe8aeada 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/rbd/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/rbd/BUILD @@ -17,6 +17,7 @@ go_library( ], importpath = "k8s.io/kubernetes/pkg/volume/rbd", deps = [ + "//pkg/features:go_default_library", "//pkg/util/file:go_default_library", "//pkg/util/mount:go_default_library", "//pkg/util/node:go_default_library", @@ -33,6 +34,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library", ], ) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/rbd/rbd.go b/vendor/k8s.io/kubernetes/pkg/volume/rbd/rbd.go index ffc5c03c1051..ab024bf19f6b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/rbd/rbd.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/rbd/rbd.go @@ -30,7 +30,9 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/uuid" + utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" @@ -691,6 +693,11 @@ func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dMi", sizeMB)), } pv.Spec.MountOptions = r.options.MountOptions + + if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { + pv.Spec.VolumeMode = r.options.PVC.Spec.VolumeMode + } + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/scaleio/sio_volume.go b/vendor/k8s.io/kubernetes/pkg/volume/scaleio/sio_volume.go index b7f02701118d..3c1cb2da8b54 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/scaleio/sio_volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/scaleio/sio_volume.go @@ -259,6 +259,10 @@ func (v *sioVolume) Provision() (*api.PersistentVolume, error) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", v.options.PVC.Spec.AccessModes, v.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(v.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", v.plugin.GetPluginName()) + } + // setup volume attrributes genName := v.generateName("k8svol", 11) var oneGig int64 = 1024 * 1024 * 1024 diff --git a/vendor/k8s.io/kubernetes/pkg/volume/storageos/storageos.go b/vendor/k8s.io/kubernetes/pkg/volume/storageos/storageos.go index a814c438dd15..42a5df7f0503 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/storageos/storageos.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/storageos/storageos.go @@ -564,6 +564,9 @@ func (c *storageosProvisioner) Provision() (*v1.PersistentVolume, error) { if !util.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) + } var adminSecretName, adminSecretNamespace string diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go index 0459a6cdab5b..583786e5ca33 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go @@ -753,3 +753,10 @@ func CheckVolumeModeFilesystem(volumeSpec *volume.Spec) (bool, error) { } return true, nil } + +// CheckPersistentVolumeClaimModeBlock checks VolumeMode. +// If the mode is Block, return true otherwise return false. +func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool { + return utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock +} + diff --git a/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go index 7b1e611df54d..377622c7a3ab 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go @@ -352,6 +352,9 @@ func (v *vsphereVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { if !util.AccessModesContainedInAll(v.plugin.GetAccessModes(), v.options.PVC.Spec.AccessModes) { return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", v.options.PVC.Spec.AccessModes, v.plugin.GetAccessModes()) } + if util.CheckPersistentVolumeClaimModeBlock(v.options.PVC) { + return nil, fmt.Errorf("%s does not support block volume provisioning", v.plugin.GetPluginName()) + } volSpec, err := v.manager.CreateVolume(v) if err != nil { diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/volume_provisioning.go b/vendor/k8s.io/kubernetes/test/e2e/storage/volume_provisioning.go index 97cbaa72c7aa..493902734bb3 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/volume_provisioning.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/volume_provisioning.go @@ -57,6 +57,7 @@ type storageClassTest struct { expectedSize string pvCheck func(volume *v1.PersistentVolume) error nodeName string + volumeMode *v1.PersistentVolumeMode } const ( @@ -120,6 +121,10 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(Equal(*class.ReclaimPolicy)) Expect(pv.Spec.MountOptions).To(Equal(class.MountOptions)) } + if t.volumeMode != nil { + Expect(pv.Spec.VolumeMode).NotTo(BeNil()) + Expect(*pv.Spec.VolumeMode).To(Equal(*t.volumeMode)) + } // Run the checker if t.pvCheck != nil { @@ -790,6 +795,34 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() { Expect(claim.Status.Phase).To(Equal(v1.ClaimPending)) }) }) + + Describe("Block volume provisioning [Feature:BlockVolume]", func() { + It("should create and delete block persistent volumes", func() { + + // TODO: add openstack once Cinder volume plugin supports block volumes + framework.SkipUnlessProviderIs("gce", "aws", "gke", "vsphere", "azure") + + By("creating a claim with default class") + block := v1.PersistentVolumeBlock + test := storageClassTest{ + name: "default", + claimSize: "2Gi", + expectedSize: "2Gi", + volumeMode: &block, + } + // gce or gke + if getDefaultPluginName() == "kubernetes.io/gce-pd" { + // using GB not GiB as e2e test unit since gce-pd returns GB, + // or expectedSize may be greater than claimSize. + test.claimSize = "2G" + test.expectedSize = "2G" + } + + claim := newClaim(test, ns, "default") + claim.Spec.VolumeMode = &block + testDynamicProvisioning(test, c, claim, nil) + }) + }) }) func getDefaultStorageClassName(c clientset.Interface) string {