Merge pull request #88673 from jsafrane/block-feature-ga

Promote block volumes to GA
This commit is contained in:
Kubernetes Prow Robot 2020-03-03 12:17:12 -08:00 committed by GitHub
commit 9d0cbb7503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 125 additions and 878 deletions

View File

@ -5632,7 +5632,7 @@
"type": "boolean"
},
"volumeDevices": {
"description": "volumeDevices is the list of block devices to be used by the container. This is a beta feature.",
"description": "volumeDevices is the list of block devices to be used by the container.",
"items": {
"$ref": "#/definitions/io.k8s.api.core.v1.VolumeDevice"
},
@ -6234,7 +6234,7 @@
"type": "boolean"
},
"volumeDevices": {
"description": "volumeDevices is the list of block devices to be used by the container. This is a beta feature.",
"description": "volumeDevices is the list of block devices to be used by the container.",
"items": {
"$ref": "#/definitions/io.k8s.api.core.v1.VolumeDevice"
},
@ -7847,7 +7847,7 @@
"type": "string"
},
"volumeMode": {
"description": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. This is a beta feature.",
"description": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.",
"type": "string"
},
"volumeName": {
@ -8067,7 +8067,7 @@
"description": "StorageOS represents a StorageOS volume that is attached to the kubelet's host machine and mounted into the pod More info: https://examples.k8s.io/volumes/storageos/README.md"
},
"volumeMode": {
"description": "volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec. This is a beta feature.",
"description": "volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec.",
"type": "string"
},
"vsphereVolume": {

View File

@ -25,10 +25,6 @@ import (
// DropDisabledFields removes disabled fields from the pv spec.
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pv spec.
func DropDisabledFields(pvSpec *api.PersistentVolumeSpec, oldPVSpec *api.PersistentVolumeSpec) {
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && !volumeModeInUse(oldPVSpec) {
pvSpec.VolumeMode = nil
}
if !utilfeature.DefaultFeatureGate.Enabled(features.ExpandCSIVolumes) && !hasExpansionSecrets(oldPVSpec) {
if pvSpec.CSI != nil {
pvSpec.CSI.ControllerExpandSecretRef = nil
@ -46,13 +42,3 @@ func hasExpansionSecrets(oldPVSpec *api.PersistentVolumeSpec) bool {
}
return false
}
func volumeModeInUse(oldPVSpec *api.PersistentVolumeSpec) bool {
if oldPVSpec == nil {
return false
}
if oldPVSpec.VolumeMode != nil {
return true
}
return false
}

View File

@ -28,68 +28,18 @@ import (
)
func TestDropDisabledFields(t *testing.T) {
specWithMode := func(mode *api.PersistentVolumeMode) *api.PersistentVolumeSpec {
return &api.PersistentVolumeSpec{VolumeMode: mode}
}
secretRef := &api.SecretReference{
Name: "expansion-secret",
Namespace: "default",
}
modeBlock := api.PersistentVolumeBlock
tests := map[string]struct {
oldSpec *api.PersistentVolumeSpec
newSpec *api.PersistentVolumeSpec
expectOldSpec *api.PersistentVolumeSpec
expectNewSpec *api.PersistentVolumeSpec
blockEnabled bool
csiExpansionEnabled bool
}{
"disabled block clears new": {
blockEnabled: false,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(nil),
oldSpec: nil,
expectOldSpec: nil,
},
"disabled block clears update when old pv did not use block": {
blockEnabled: false,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(nil),
oldSpec: specWithMode(nil),
expectOldSpec: specWithMode(nil),
},
"disabled block does not clear new on update when old pv did use block": {
blockEnabled: false,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(&modeBlock),
oldSpec: specWithMode(&modeBlock),
expectOldSpec: specWithMode(&modeBlock),
},
"enabled block preserves new": {
blockEnabled: true,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(&modeBlock),
oldSpec: nil,
expectOldSpec: nil,
},
"enabled block preserves update when old pv did not use block": {
blockEnabled: true,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(&modeBlock),
oldSpec: specWithMode(nil),
expectOldSpec: specWithMode(nil),
},
"enabled block preserves update when old pv did use block": {
blockEnabled: true,
newSpec: specWithMode(&modeBlock),
expectNewSpec: specWithMode(&modeBlock),
oldSpec: specWithMode(&modeBlock),
expectOldSpec: specWithMode(&modeBlock),
},
"disabled csi expansion clears secrets": {
csiExpansionEnabled: false,
newSpec: specWithCSISecrets(secretRef),
@ -129,7 +79,6 @@ func TestDropDisabledFields(t *testing.T) {
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, tc.blockEnabled)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandCSIVolumes, tc.csiExpansionEnabled)()
DropDisabledFields(tc.newSpec, tc.oldSpec)

View File

@ -30,24 +30,11 @@ const (
// DropDisabledFields removes disabled fields from the pvc spec.
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pvc spec.
func DropDisabledFields(pvcSpec, oldPVCSpec *core.PersistentVolumeClaimSpec) {
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && !volumeModeInUse(oldPVCSpec) {
pvcSpec.VolumeMode = nil
}
if !dataSourceIsEnabled(pvcSpec) && !dataSourceInUse(oldPVCSpec) {
pvcSpec.DataSource = nil
}
}
func volumeModeInUse(oldPVCSpec *core.PersistentVolumeClaimSpec) bool {
if oldPVCSpec == nil {
return false
}
if oldPVCSpec.VolumeMode != nil {
return true
}
return false
}
func dataSourceInUse(oldPVCSpec *core.PersistentVolumeClaimSpec) bool {
if oldPVCSpec == nil {
return false

View File

@ -28,96 +28,6 @@ import (
"k8s.io/kubernetes/pkg/features"
)
func TestDropAlphaPVCVolumeMode(t *testing.T) {
vmode := core.PersistentVolumeFilesystem
pvcWithoutVolumeMode := func() *core.PersistentVolumeClaim {
return &core.PersistentVolumeClaim{
Spec: core.PersistentVolumeClaimSpec{
VolumeMode: nil,
},
}
}
pvcWithVolumeMode := func() *core.PersistentVolumeClaim {
return &core.PersistentVolumeClaim{
Spec: core.PersistentVolumeClaimSpec{
VolumeMode: &vmode,
},
}
}
pvcInfo := []struct {
description string
hasVolumeMode bool
pvc func() *core.PersistentVolumeClaim
}{
{
description: "pvc without VolumeMode",
hasVolumeMode: false,
pvc: pvcWithoutVolumeMode,
},
{
description: "pvc with Filesystem VolumeMode",
hasVolumeMode: true,
pvc: pvcWithVolumeMode,
},
{
description: "is nil",
hasVolumeMode: false,
pvc: func() *core.PersistentVolumeClaim { return nil },
},
}
for _, enabled := range []bool{true, false} {
for _, oldpvcInfo := range pvcInfo {
for _, newpvcInfo := range pvcInfo {
oldpvcHasVolumeMode, oldpvc := oldpvcInfo.hasVolumeMode, oldpvcInfo.pvc()
newpvcHasVolumeMode, newpvc := newpvcInfo.hasVolumeMode, newpvcInfo.pvc()
if newpvc == nil {
continue
}
t.Run(fmt.Sprintf("feature enabled=%v, old pvc %v, new pvc %v", enabled, oldpvcInfo.description, newpvcInfo.description), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, enabled)()
var oldpvcSpec *core.PersistentVolumeClaimSpec
if oldpvc != nil {
oldpvcSpec = &oldpvc.Spec
}
DropDisabledFields(&newpvc.Spec, oldpvcSpec)
// old pvc should never be changed
if !reflect.DeepEqual(oldpvc, oldpvcInfo.pvc()) {
t.Errorf("old pvc changed: %v", diff.ObjectReflectDiff(oldpvc, oldpvcInfo.pvc()))
}
switch {
case enabled || oldpvcHasVolumeMode:
// new pvc should not be changed if the feature is enabled, or if the old pvc had BlockVolume
if !reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc changed: %v", diff.ObjectReflectDiff(newpvc, newpvcInfo.pvc()))
}
case newpvcHasVolumeMode:
// new pvc should be changed
if reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc was not changed")
}
// new pvc should not have BlockVolume
if !reflect.DeepEqual(newpvc, pvcWithoutVolumeMode()) {
t.Errorf("new pvc had pvcBlockVolume: %v", diff.ObjectReflectDiff(newpvc, pvcWithoutVolumeMode()))
}
default:
// new pvc should not need to be changed
if !reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc changed: %v", diff.ObjectReflectDiff(newpvc, newpvcInfo.pvc()))
}
}
})
}
}
}
}
func TestDropDisabledSnapshotDataSource(t *testing.T) {
pvcWithoutDataSource := func() *core.PersistentVolumeClaim {
return &core.PersistentVolumeClaim{

View File

@ -385,8 +385,6 @@ func dropDisabledFields(
})
}
dropDisabledVolumeDevicesFields(podSpec, oldPodSpec)
dropDisabledRunAsGroupField(podSpec, oldPodSpec)
dropDisabledGMSAFields(podSpec, oldPodSpec)
@ -484,17 +482,6 @@ func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {
}
}
// dropDisabledVolumeDevicesFields removes disabled fields from []VolumeDevice if it has not been already populated.
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a VolumeDevice
func dropDisabledVolumeDevicesFields(podSpec, oldPodSpec *api.PodSpec) {
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && !volumeDevicesInUse(oldPodSpec) {
VisitContainers(podSpec, func(c *api.Container) bool {
c.VolumeDevices = nil
return true
})
}
}
// dropDisabledCSIVolumeSourceAlphaFields removes disabled alpha fields from []CSIVolumeSource.
// This should be called from PrepareForCreate/PrepareForUpdate for all pod specs resources containing a CSIVolumeSource
func dropDisabledCSIVolumeSourceAlphaFields(podSpec, oldPodSpec *api.PodSpec) {
@ -646,24 +633,6 @@ func emptyDirSizeLimitInUse(podSpec *api.PodSpec) bool {
return false
}
// volumeDevicesInUse returns true if the pod spec is non-nil and has VolumeDevices set.
func volumeDevicesInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
var inUse bool
VisitContainers(podSpec, func(c *api.Container) bool {
if c.VolumeDevices != nil {
inUse = true
return false
}
return true
})
return inUse
}
// runAsGroupInUse returns true if the pod spec is non-nil and has a SecurityContext's RunAsGroup field set
func runAsGroupInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {

View File

@ -435,150 +435,6 @@ func TestPodConfigmaps(t *testing.T) {
}
}
func TestDropAlphaVolumeDevices(t *testing.T) {
podWithVolumeDevices := func() *api.Pod {
return &api.Pod{
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyNever,
Containers: []api.Container{
{
Name: "container1",
Image: "testimage",
VolumeDevices: []api.VolumeDevice{
{
Name: "myvolume",
DevicePath: "/usr/test",
},
},
},
},
InitContainers: []api.Container{
{
Name: "container1",
Image: "testimage",
VolumeDevices: []api.VolumeDevice{
{
Name: "myvolume",
DevicePath: "/usr/test",
},
},
},
},
Volumes: []api.Volume{
{
Name: "myvolume",
VolumeSource: api.VolumeSource{
HostPath: &api.HostPathVolumeSource{
Path: "/dev/xvdc",
},
},
},
},
},
}
}
podWithoutVolumeDevices := func() *api.Pod {
return &api.Pod{
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyNever,
Containers: []api.Container{
{
Name: "container1",
Image: "testimage",
},
},
InitContainers: []api.Container{
{
Name: "container1",
Image: "testimage",
},
},
Volumes: []api.Volume{
{
Name: "myvolume",
VolumeSource: api.VolumeSource{
HostPath: &api.HostPathVolumeSource{
Path: "/dev/xvdc",
},
},
},
},
},
}
}
podInfo := []struct {
description string
hasVolumeDevices bool
pod func() *api.Pod
}{
{
description: "has VolumeDevices",
hasVolumeDevices: true,
pod: podWithVolumeDevices,
},
{
description: "does not have VolumeDevices",
hasVolumeDevices: false,
pod: podWithoutVolumeDevices,
},
{
description: "is nil",
hasVolumeDevices: false,
pod: func() *api.Pod { return nil },
},
}
for _, enabled := range []bool{true, false} {
for _, oldPodInfo := range podInfo {
for _, newPodInfo := range podInfo {
oldPodHasVolumeDevices, oldPod := oldPodInfo.hasVolumeDevices, oldPodInfo.pod()
newPodHasVolumeDevices, newPod := newPodInfo.hasVolumeDevices, newPodInfo.pod()
if newPod == nil {
continue
}
t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, enabled)()
var oldPodSpec *api.PodSpec
if oldPod != nil {
oldPodSpec = &oldPod.Spec
}
dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil)
// old pod should never be changed
if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) {
t.Errorf("old pod changed: %v", diff.ObjectReflectDiff(oldPod, oldPodInfo.pod()))
}
switch {
case enabled || oldPodHasVolumeDevices:
// new pod should not be changed if the feature is enabled, or if the old pod had VolumeDevices
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
}
case newPodHasVolumeDevices:
// new pod should be changed
if reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod was not changed")
}
// new pod should not have VolumeDevices
if !reflect.DeepEqual(newPod, podWithoutVolumeDevices()) {
t.Errorf("new pod had VolumeDevices: %v", diff.ObjectReflectDiff(newPod, podWithoutVolumeDevices()))
}
default:
// new pod should not need to be changed
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
}
}
})
}
}
}
}
func TestDropSubPath(t *testing.T) {
podWithSubpaths := func() *api.Pod {
return &api.Pod{

View File

@ -302,7 +302,6 @@ type PersistentVolumeSpec struct {
MountOptions []string
// volumeMode defines if a volume is intended to be used with a formatted filesystem
// or to remain in raw block state. Value of Filesystem is implied when not included in spec.
// This is a beta feature.
// +optional
VolumeMode *PersistentVolumeMode
// NodeAffinity defines constraints that limit what nodes this volume can be accessed from.
@ -416,7 +415,6 @@ type PersistentVolumeClaimSpec struct {
StorageClassName *string
// volumeMode defines what type of volume is required by the claim.
// Value of Filesystem is implied when not included in claim spec.
// This is a beta feature.
// +optional
VolumeMode *PersistentVolumeMode
// This field can be used to specify either:
@ -2057,7 +2055,6 @@ type Container struct {
// +optional
VolumeMounts []VolumeMount
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +optional
VolumeDevices []VolumeDevice
// +optional
@ -2969,7 +2966,6 @@ type EphemeralContainerCommon struct {
// +optional
VolumeMounts []VolumeMount
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +optional
VolumeDevices []VolumeDevice
// Probes are not allowed for ephemeral containers.

View File

@ -1475,204 +1475,168 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) {
oldClaim *core.PersistentVolumeClaim
newClaim *core.PersistentVolumeClaim
enableResize bool
enableBlock bool
}{
"valid-update-volumeName-only": {
isExpectedFailure: false,
oldClaim: validClaim,
newClaim: validUpdateClaim,
enableResize: false,
enableBlock: false,
},
"valid-no-op-update": {
isExpectedFailure: false,
oldClaim: validUpdateClaim,
newClaim: validUpdateClaim,
enableResize: false,
enableBlock: false,
},
"invalid-update-change-resources-on-bound-claim": {
isExpectedFailure: true,
oldClaim: validUpdateClaim,
newClaim: invalidUpdateClaimResources,
enableResize: false,
enableBlock: false,
},
"invalid-update-change-access-modes-on-bound-claim": {
isExpectedFailure: true,
oldClaim: validUpdateClaim,
newClaim: invalidUpdateClaimAccessModes,
enableResize: false,
enableBlock: false,
},
"valid-update-volume-mode-block-to-block": {
isExpectedFailure: false,
oldClaim: validClaimVolumeModeBlock,
newClaim: validClaimVolumeModeBlock,
enableResize: false,
enableBlock: true,
},
"valid-update-volume-mode-file-to-file": {
isExpectedFailure: false,
oldClaim: validClaimVolumeModeFile,
newClaim: validClaimVolumeModeFile,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-to-block": {
isExpectedFailure: true,
oldClaim: validClaimVolumeModeFile,
newClaim: validClaimVolumeModeBlock,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-to-file": {
isExpectedFailure: true,
oldClaim: validClaimVolumeModeBlock,
newClaim: validClaimVolumeModeFile,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-nil-to-file": {
isExpectedFailure: true,
oldClaim: invalidClaimVolumeModeNil,
newClaim: validClaimVolumeModeFile,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-nil-to-block": {
isExpectedFailure: true,
oldClaim: invalidClaimVolumeModeNil,
newClaim: validClaimVolumeModeBlock,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-block-to-nil": {
isExpectedFailure: true,
oldClaim: validClaimVolumeModeBlock,
newClaim: invalidClaimVolumeModeNil,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-file-to-nil": {
isExpectedFailure: true,
oldClaim: validClaimVolumeModeFile,
newClaim: invalidClaimVolumeModeNil,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-empty-to-mode": {
isExpectedFailure: true,
oldClaim: validClaim,
newClaim: validClaimVolumeModeBlock,
enableResize: false,
enableBlock: true,
},
"invalid-update-volume-mode-mode-to-empty": {
isExpectedFailure: true,
oldClaim: validClaimVolumeModeBlock,
newClaim: validClaim,
enableResize: false,
enableBlock: true,
},
// with the new validation changes this test should not fail
"noop-update-volumemode-allowed": {
isExpectedFailure: false,
oldClaim: validClaimVolumeModeFile,
newClaim: validClaimVolumeModeFile,
enableResize: false,
enableBlock: false,
},
"invalid-update-change-storage-class-annotation-after-creation": {
isExpectedFailure: true,
oldClaim: validClaimStorageClass,
newClaim: invalidUpdateClaimStorageClass,
enableResize: false,
enableBlock: false,
},
"valid-update-mutable-annotation": {
isExpectedFailure: false,
oldClaim: validClaimAnnotation,
newClaim: validUpdateClaimMutableAnnotation,
enableResize: false,
enableBlock: false,
},
"valid-update-add-annotation": {
isExpectedFailure: false,
oldClaim: validClaim,
newClaim: validAddClaimAnnotation,
enableResize: false,
enableBlock: false,
},
"valid-size-update-resize-disabled": {
isExpectedFailure: true,
oldClaim: validClaim,
newClaim: validSizeUpdate,
enableResize: false,
enableBlock: false,
},
"valid-size-update-resize-enabled": {
isExpectedFailure: false,
oldClaim: validClaim,
newClaim: validSizeUpdate,
enableResize: true,
enableBlock: false,
},
"invalid-size-update-resize-enabled": {
isExpectedFailure: true,
oldClaim: validClaim,
newClaim: invalidSizeUpdate,
enableResize: true,
enableBlock: false,
},
"unbound-size-update-resize-enabled": {
isExpectedFailure: true,
oldClaim: validClaim,
newClaim: unboundSizeUpdate,
enableResize: true,
enableBlock: false,
},
"valid-upgrade-storage-class-annotation-to-spec": {
isExpectedFailure: false,
oldClaim: validClaimStorageClass,
newClaim: validClaimStorageClassInSpec,
enableResize: false,
enableBlock: false,
},
"invalid-upgrade-storage-class-annotation-to-spec": {
isExpectedFailure: true,
oldClaim: validClaimStorageClass,
newClaim: invalidClaimStorageClassInSpec,
enableResize: false,
enableBlock: false,
},
"valid-upgrade-storage-class-annotation-to-annotation-and-spec": {
isExpectedFailure: false,
oldClaim: validClaimStorageClass,
newClaim: validClaimStorageClassInAnnotationAndSpec,
enableResize: false,
enableBlock: false,
},
"invalid-upgrade-storage-class-annotation-to-annotation-and-spec": {
isExpectedFailure: true,
oldClaim: validClaimStorageClass,
newClaim: invalidClaimStorageClassInAnnotationAndSpec,
enableResize: false,
enableBlock: false,
},
"invalid-upgrade-storage-class-in-spec": {
isExpectedFailure: true,
oldClaim: validClaimStorageClassInSpec,
newClaim: invalidClaimStorageClassInSpec,
enableResize: false,
enableBlock: false,
},
"invalid-downgrade-storage-class-spec-to-annotation": {
isExpectedFailure: true,
oldClaim: validClaimStorageClassInSpec,
newClaim: validClaimStorageClass,
enableResize: false,
enableBlock: false,
},
}
@ -1680,7 +1644,6 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) {
t.Run(name, func(t *testing.T) {
// ensure we have a resource version specified for updates
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, scenario.enableResize)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)()
scenario.oldClaim.ResourceVersion = "1"
scenario.newClaim.ResourceVersion = "1"
errs := ValidatePersistentVolumeClaimUpdate(scenario.newClaim, scenario.oldClaim)
@ -4092,9 +4055,6 @@ func TestHugePagesIsolation(t *testing.T) {
}
func TestPVCVolumeMode(t *testing.T) {
// Enable feature BlockVolume for PVC
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
block := core.PersistentVolumeBlock
file := core.PersistentVolumeFilesystem
fake := core.PersistentVolumeMode("fake")
@ -4125,9 +4085,6 @@ func TestPVCVolumeMode(t *testing.T) {
}
func TestPVVolumeMode(t *testing.T) {
// Enable feature BlockVolume for PVC
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
block := core.PersistentVolumeBlock
file := core.PersistentVolumeFilesystem
fake := core.PersistentVolumeMode("fake")

View File

@ -22,10 +22,7 @@ import (
v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util"
"k8s.io/kubernetes/pkg/features"
)
// Test single call to syncClaim and syncVolume methods.
@ -611,68 +608,6 @@ func TestSync(t *testing.T) {
}, []*v1.Pod{})
}
func TestSyncBlockVolumeDisabled(t *testing.T) {
modeBlock := v1.PersistentVolumeBlock
modeFile := v1.PersistentVolumeFilesystem
// All of these should bind as feature set is not enabled for BlockVolume
// meaning volumeMode will be ignored and dropped
tests := []controllerTest{
{
// syncVolume binds a requested block claim to a block volume
"14-1 - binding to volumeMode block",
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-1", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-1", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withClaimVolumeMode(&modeBlock, newClaimArray("claim14-1", "uid14-1", "10Gi", "", v1.ClaimPending, nil)),
withClaimVolumeMode(&modeBlock, newClaimArray("claim14-1", "uid14-1", "10Gi", "", v1.ClaimPending, nil)),
noevents, noerrors, testSyncClaim,
},
{
// syncVolume binds a requested filesystem claim to a filesystem volume
"14-2 - binding to volumeMode filesystem",
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-2", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-2", "10Gi", "uid14-2", "claim14-2", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-2", "uid14-2", "10Gi", "", v1.ClaimPending, nil)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-2", "uid14-2", "10Gi", "volume14-2", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
noevents, noerrors, testSyncClaim,
},
{
// syncVolume binds an unspecified volumemode for claim to a specified filesystem volume
"14-3 - binding to volumeMode filesystem using default for claim",
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-3", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-3", "10Gi", "uid14-3", "claim14-3", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
withClaimVolumeMode(nil, newClaimArray("claim14-3", "uid14-3", "10Gi", "", v1.ClaimPending, nil)),
withClaimVolumeMode(nil, newClaimArray("claim14-3", "uid14-3", "10Gi", "volume14-3", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
noevents, noerrors, testSyncClaim,
},
{
// syncVolume binds a requested filesystem claim to an unspecified volumeMode for volume
"14-4 - binding to unspecified volumeMode using requested filesystem for claim",
withVolumeVolumeMode(nil, newVolumeArray("volume14-4", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withVolumeVolumeMode(nil, newVolumeArray("volume14-4", "10Gi", "uid14-4", "claim14-4", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-4", "uid14-4", "10Gi", "", v1.ClaimPending, nil)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-4", "uid14-4", "10Gi", "volume14-4", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
noevents, noerrors, testSyncClaim,
},
{
// syncVolume binds a requested filesystem claim to an unspecified volumeMode for volume
"14-5 - binding different volumeModes should be ignored",
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-5", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-5", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-5", "uid14-5", "10Gi", "", v1.ClaimPending, nil)),
withClaimVolumeMode(&modeFile, newClaimArray("claim14-5", "uid14-5", "10Gi", "", v1.ClaimPending, nil)),
noevents, noerrors, testSyncClaim,
},
}
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
runSyncTests(t, tests, []*storage.StorageClass{
{
ObjectMeta: metav1.ObjectMeta{Name: classWait},
VolumeBindingMode: &modeWait,
},
}, []*v1.Pod{})
}
func TestSyncBlockVolume(t *testing.T) {
modeBlock := v1.PersistentVolumeBlock
modeFile := v1.PersistentVolumeFilesystem
@ -853,8 +788,6 @@ func TestSyncBlockVolume(t *testing.T) {
},
}
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
runSyncTests(t, tests, []*storage.StorageClass{}, []*v1.Pod{})
}

View File

@ -1060,91 +1060,56 @@ func TestVolumeModeCheck(t *testing.T) {
isExpectedMismatch bool
vol *v1.PersistentVolume
pvc *v1.PersistentVolumeClaim
enableBlock bool
}{
"feature enabled - pvc block and pv filesystem": {
"pvc block and pv filesystem": {
isExpectedMismatch: true,
vol: createVolumeModeFilesystemTestVolume(),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"feature enabled - pvc filesystem and pv block": {
"pvc filesystem and pv block": {
isExpectedMismatch: true,
vol: createVolumeModeBlockTestVolume(),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"feature enabled - pvc block and pv block": {
"pvc block and pv block": {
isExpectedMismatch: false,
vol: createVolumeModeBlockTestVolume(),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"feature enabled - pvc filesystem and pv filesystem": {
"pvc filesystem and pv filesystem": {
isExpectedMismatch: false,
vol: createVolumeModeFilesystemTestVolume(),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"feature enabled - pvc filesystem and pv nil": {
"pvc filesystem and pv nil": {
isExpectedMismatch: false,
vol: createVolumeModeNilTestVolume(),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"feature enabled - pvc nil and pv filesystem": {
"pvc nil and pv filesystem": {
isExpectedMismatch: false,
vol: createVolumeModeFilesystemTestVolume(),
pvc: makeVolumeModePVC("8G", nil, nil),
enableBlock: true,
},
"feature enabled - pvc nil and pv nil": {
"pvc nil and pv nil": {
isExpectedMismatch: false,
vol: createVolumeModeNilTestVolume(),
pvc: makeVolumeModePVC("8G", nil, nil),
enableBlock: true,
},
"feature enabled - pvc nil and pv block": {
"pvc nil and pv block": {
isExpectedMismatch: true,
vol: createVolumeModeBlockTestVolume(),
pvc: makeVolumeModePVC("8G", nil, nil),
enableBlock: true,
},
"feature enabled - pvc block and pv nil": {
"pvc block and pv nil": {
isExpectedMismatch: true,
vol: createVolumeModeNilTestVolume(),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"feature disabled - pvc block and pv filesystem": {
isExpectedMismatch: true,
vol: createVolumeModeFilesystemTestVolume(),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: false,
},
"feature disabled - pvc filesystem and pv block": {
isExpectedMismatch: true,
vol: createVolumeModeBlockTestVolume(),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: false,
},
"feature disabled - pvc block and pv block": {
isExpectedMismatch: true,
vol: createVolumeModeBlockTestVolume(),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: false,
},
"feature disabled - pvc filesystem and pv filesystem": {
isExpectedMismatch: false,
vol: createVolumeModeFilesystemTestVolume(),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: false,
},
}
for name, scenario := range scenarios {
t.Run(name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)()
expectedMismatch := pvutil.CheckVolumeModeMismatches(&scenario.pvc.Spec, &scenario.vol.Spec)
// expected to match but either got an error or no returned pvmatch
if expectedMismatch && !scenario.isExpectedMismatch {
@ -1167,73 +1132,46 @@ func TestFilteringVolumeModes(t *testing.T) {
isExpectedMatch bool
vol persistentVolumeOrderedIndex
pvc *v1.PersistentVolumeClaim
enableBlock bool
}{
"1-1 feature enabled - pvc block and pv filesystem": {
"pvc block and pv filesystem": {
isExpectedMatch: false,
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"1-2 feature enabled - pvc filesystem and pv block": {
"pvc filesystem and pv block": {
isExpectedMatch: false,
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"1-3 feature enabled - pvc block and pv no mode with default filesystem": {
"pvc block and pv no mode with default filesystem": {
isExpectedMatch: false,
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"1-4 feature enabled - pvc no mode defaulted to filesystem and pv block": {
"pvc no mode defaulted to filesystem and pv block": {
isExpectedMatch: false,
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"1-5 feature enabled - pvc block and pv block": {
"pvc block and pv block": {
isExpectedMatch: true,
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: true,
},
"1-6 feature enabled - pvc filesystem and pv filesystem": {
"pvc filesystem and pv filesystem": {
isExpectedMatch: true,
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"1-7 feature enabled - pvc mode is nil and defaulted and pv mode is nil and defaulted": {
"pvc mode is nil and defaulted and pv mode is nil and defaulted": {
isExpectedMatch: true,
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: true,
},
"2-1 feature disabled - pvc mode is nil and pv mode is nil": {
isExpectedMatch: true,
vol: createTestVolOrderedIndex(testVolume("nomode-1", "8G")),
pvc: makeVolumeModePVC("8G", nil, nil),
enableBlock: false,
},
"2-2 feature disabled - pvc mode is block and pv mode is block - fields should be dropped by api and not analyzed with gate disabled": {
isExpectedMatch: false,
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
pvc: makeVolumeModePVC("8G", &blockMode, nil),
enableBlock: false,
},
"2-3 feature disabled - pvc mode is filesystem and pv mode is filesystem - fields should be dropped by api and not analyzed with gate disabled": {
isExpectedMatch: true,
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
enableBlock: false,
},
}
for name, scenario := range scenarios {
t.Run(name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)()
pvmatch, err := scenario.vol.findBestMatchForClaim(scenario.pvc, false)
// expected to match but either got an error or no returned pvmatch
if pvmatch == nil && scenario.isExpectedMatch {

View File

@ -6,7 +6,6 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/testing",
visibility = ["//visibility:public"],
deps = [
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@ -14,7 +13,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
"//vendor/k8s.io/klog:go_default_library",

View File

@ -30,11 +30,9 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/watch"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/features"
)
// ErrVersionConflict is the error returned when resource version of requested
@ -114,7 +112,7 @@ func (r *VolumeReactor) React(action core.Action) (handled bool, ret runtime.Obj
}
// mimic apiserver defaulting
if volume.Spec.VolumeMode == nil && utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
if volume.Spec.VolumeMode == nil {
volume.Spec.VolumeMode = new(v1.PersistentVolumeMode)
*volume.Spec.VolumeMode = v1.PersistentVolumeFilesystem
}

View File

@ -307,23 +307,6 @@ func FindMatchingVolume(
// CheckVolumeModeMismatches is a convenience method that checks volumeMode for PersistentVolume
// and PersistentVolumeClaims
func CheckVolumeModeMismatches(pvcSpec *v1.PersistentVolumeClaimSpec, pvSpec *v1.PersistentVolumeSpec) bool {
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
if pvcSpec.VolumeMode != nil && *pvcSpec.VolumeMode == v1.PersistentVolumeBlock {
// Block PVC does not match anything when the feature is off. We explicitly want
// to prevent binding block PVC to filesystem PV.
// The PVC should be ignored by PV controller.
return true
}
if pvSpec.VolumeMode != nil && *pvSpec.VolumeMode == v1.PersistentVolumeBlock {
// Block PV does not match anything when the feature is off. We explicitly want
// to prevent binding block PV to filesystem PVC.
// The PV should be ignored by PV controller.
return true
}
// Both PV + PVC are not block.
return false
}
// In HA upgrades, we cannot guarantee that the apiserver is on a version >= controller-manager.
// So we default a nil volumeMode to filesystem
requestedVolumeMode := v1.PersistentVolumeFilesystem

View File

@ -183,7 +183,8 @@ const (
// owner: @screeley44
// alpha: v1.9
// beta: v1.13
// beta: v1.13
// ga: v1.18
//
// Enable Block volume support in containers.
BlockVolume featuregate.Feature = "BlockVolume"
@ -295,7 +296,8 @@ const (
// owner: @vladimirvivien
// alpha: v1.11
// beta: v1.14
// beta: v1.14
// ga: v1.18
//
// Enables CSI to use raw block storage volumes
CSIBlockVolume featuregate.Feature = "CSIBlockVolume"
@ -594,7 +596,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
NodeDisruptionExclusion: {Default: false, PreRelease: featuregate.Alpha},
CSIDriverRegistry: {Default: true, PreRelease: featuregate.Beta},
CSINodeInfo: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.19
BlockVolume: {Default: true, PreRelease: featuregate.Beta},
BlockVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20
StorageObjectInUseProtection: {Default: true, PreRelease: featuregate.GA},
ResourceLimitsPriorityFunction: {Default: false, PreRelease: featuregate.Alpha},
SupportIPVSProxyMode: {Default: true, PreRelease: featuregate.GA},
@ -621,7 +623,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
VolumeSubpath: {Default: true, PreRelease: featuregate.GA},
BalanceAttachedNodeVolumes: {Default: false, PreRelease: featuregate.Alpha},
VolumeSubpathEnvExpansion: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.19,
CSIBlockVolume: {Default: true, PreRelease: featuregate.Beta},
CSIBlockVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
RuntimeClass: {Default: true, PreRelease: featuregate.Beta},
NodeLease: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},

View File

@ -457,15 +457,12 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
opts.PortMappings = kubecontainer.MakePortMappings(container)
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
blkutil := volumepathhandler.NewBlockVolumePathHandler()
blkVolumes, err := kl.makeBlockVolumes(pod, container, volumes, blkutil)
if err != nil {
return nil, nil, err
}
opts.Devices = append(opts.Devices, blkVolumes...)
blkutil := volumepathhandler.NewBlockVolumePathHandler()
blkVolumes, err := kl.makeBlockVolumes(pod, container, volumes, blkutil)
if err != nil {
return nil, nil, err
}
opts.Devices = append(opts.Devices, blkVolumes...)
envs, err := kl.makeEnvironmentVariables(pod, container, podIP, podIPs)
if err != nil {

View File

@ -48,7 +48,6 @@ go_test(
srcs = ["volume_manager_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/features:go_default_library",
"//pkg/kubelet/config:go_default_library",
"//pkg/kubelet/configmap:go_default_library",
"//pkg/kubelet/container/testing:go_default_library",
@ -66,12 +65,10 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/k8s.io/utils/mount:go_default_library",
],
)

View File

@ -541,14 +541,12 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
podVolume.Name,
volumeMode)
}
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
// Error if a container has volumeDevices but the volumeMode of PVC isn't Block
if devices.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeBlock {
return nil, nil, "", fmt.Errorf(
"volume %s has volumeMode %s, but is specified in volumeDevices",
podVolume.Name,
volumeMode)
}
// Error if a container has volumeDevices but the volumeMode of PVC isn't Block
if devices.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeBlock {
return nil, nil, "", fmt.Errorf(
"volume %s has volumeMode %s, but is specified in volumeDevices",
podVolume.Name,
volumeMode)
}
return pvc, volumeSpec, volumeGidValue, nil
}

View File

@ -269,9 +269,6 @@ func TestFindAndRemoveDeletedPodsWithActualState(t *testing.T) {
}
func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp
mode := v1.PersistentVolumeBlock
pv := &v1.PersistentVolume{
@ -471,9 +468,6 @@ func TestCreateVolumeSpec_Valid_Nil_VolumeMounts(t *testing.T) {
}
func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp
mode := v1.PersistentVolumeBlock
pv := &v1.PersistentVolume{
@ -520,9 +514,6 @@ func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) {
}
func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp
mode := v1.PersistentVolumeFilesystem
pv := &v1.PersistentVolume{
@ -569,9 +560,6 @@ func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) {
}
func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp
mode := v1.PersistentVolumeBlock
pv := &v1.PersistentVolume{
@ -617,56 +605,6 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
}
}
func TestCreateVolumeSpec_Invalid_Block_VolumeMounts_Disabled(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
// create dswp
mode := v1.PersistentVolumeBlock
pv := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: "dswp-test-volume-name",
},
Spec: v1.PersistentVolumeSpec{
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "block-bound"},
VolumeMode: &mode,
},
}
pvc := &v1.PersistentVolumeClaim{
Spec: v1.PersistentVolumeClaimSpec{
VolumeName: "dswp-test-volume-name",
VolumeMode: &mode,
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
}
dswp, fakePodManager, _ := createDswpWithVolume(t, pv, pvc)
// create pod
containers := []v1.Container{
{
VolumeMounts: []v1.VolumeMount{
{
Name: "dswp-test-volume-name",
MountPath: "/mnt",
},
},
},
}
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers)
fakePodManager.AddPod(pod)
mountsMap, devicesMap := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod.Name, pod.Namespace, mountsMap, devicesMap)
// Assert
if volumeSpec != nil || err == nil {
t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted")
}
}
func TestCheckVolumeFSResize(t *testing.T) {
setCapacity := func(pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim, capacity int) {
pv.Spec.Capacity = volumeCapacity(capacity)

View File

@ -487,8 +487,7 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
if err != nil {
return nil, err
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && volume.volumeMode == v1.PersistentVolumeBlock && mapperPlugin == nil {
if volume.volumeMode == v1.PersistentVolumeBlock && mapperPlugin == nil {
return nil, fmt.Errorf("could not find block volume plugin %q (spec.Name: %q) pod %q (UID: %q)", volume.pluginName, volume.volumeSpecName, volume.podName, pod.UID)
}
@ -521,8 +520,7 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
// Path to the mount or block device to check
var checkPath string
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && volume.volumeMode == v1.PersistentVolumeBlock {
if volume.volumeMode == v1.PersistentVolumeBlock {
var newMapperErr error
volumeMapper, newMapperErr = mapperPlugin.NewBlockVolumeMapper(
volumeSpec,
@ -697,12 +695,10 @@ func getVolumesFromPodDir(podDir string) ([]podVolume, error) {
volumesDirs := map[v1.PersistentVolumeMode]string{
v1.PersistentVolumeFilesystem: path.Join(podDir, config.DefaultKubeletVolumesDirName),
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
// Find block volume information
// ex. block volume: /pods/{podUid}/volumeDevices/{escapeQualifiedPluginName}/{volumeName}
volumesDirs[v1.PersistentVolumeBlock] = path.Join(podDir, config.DefaultKubeletVolumeDevicesDirName)
}
// Find block volume information
// ex. block volume: /pods/{podUid}/volumeDevices/{escapeQualifiedPluginName}/{volumeName}
volumesDirs[v1.PersistentVolumeBlock] = path.Join(podDir, config.DefaultKubeletVolumeDevicesDirName)
for volumeMode, volumesDir := range volumesDirs {
var volumesDirInfo []os.FileInfo
if volumesDirInfo, err = ioutil.ReadDir(volumesDir); err != nil {

View File

@ -443,9 +443,6 @@ func Test_Run_Positive_VolumeUnmountControllerAttachEnabled(t *testing.T) {
// Verifies there are attach/get map paths/setupDevice calls and
// no detach/teardownDevice calls.
func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -543,9 +540,6 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
// and no teardownDevice call.
// Verifies there are no attach/detach calls.
func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -647,9 +641,6 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
// Deletes volume/pod from desired state of world.
// Verifies one detach/teardownDevice calls are issued.
func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -758,9 +749,6 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
// Verifies one teardownDevice call is made.
// Verifies there are no attach/detach calls made.
func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) {
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
@ -883,9 +871,6 @@ func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) {
},
}
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{}
@ -937,9 +922,6 @@ func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) {
},
}
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{}
@ -983,9 +965,6 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
},
}
// Enable BlockVolume feature gate
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{}

View File

@ -30,13 +30,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/tools/record"
utiltesting "k8s.io/client-go/util/testing"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/kubelet/configmap"
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
@ -58,11 +55,10 @@ const (
func TestGetMountedVolumesForPodAndGetVolumesInUse(t *testing.T) {
tests := []struct {
name string
pvMode, podMode v1.PersistentVolumeMode
disableBlockFeature bool
expectMount bool
expectError bool
name string
pvMode, podMode v1.PersistentVolumeMode
expectMount bool
expectError bool
}{
{
name: "filesystem volume",
@ -78,14 +74,6 @@ func TestGetMountedVolumesForPodAndGetVolumesInUse(t *testing.T) {
expectMount: true,
expectError: false,
},
{
name: "block volume with block feature off",
pvMode: v1.PersistentVolumeBlock,
podMode: v1.PersistentVolumeBlock,
disableBlockFeature: true,
expectMount: false,
expectError: false,
},
{
name: "mismatched volume",
pvMode: v1.PersistentVolumeBlock,
@ -97,10 +85,6 @@ func TestGetMountedVolumesForPodAndGetVolumesInUse(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.disableBlockFeature {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
}
tmpDir, err := utiltesting.MkTmpdir("volumeManagerTest")
if err != nil {
t.Fatalf("can't make a temp dir: %v", err)

View File

@ -20,7 +20,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/awsebs",
deps = [
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
@ -29,7 +28,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/aws:go_default_library",

View File

@ -35,8 +35,6 @@ 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/volume"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/legacy-cloud-providers/aws"
@ -501,13 +499,10 @@ func (c *awsElasticBlockStoreProvisioner) Provision(selectedNode *v1.Node, allow
fstype = "ext4"
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
volumeMode := c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
pv := &v1.PersistentVolume{

View File

@ -24,7 +24,6 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/volume/azure_dd",
deps = [
"//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
@ -34,7 +33,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure:go_default_library",

View File

@ -29,9 +29,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature"
volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/legacy-cloud-providers/azure"
@ -286,13 +284,10 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
}
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = p.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fsType = ""
}
volumeMode := p.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fsType = ""
}
pv := &v1.PersistentVolume{

View File

@ -17,7 +17,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/cinder",
deps = [
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
@ -27,7 +26,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",

View File

@ -34,9 +34,7 @@ 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"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/legacy-cloud-providers/openstack"
@ -572,13 +570,10 @@ func (c *cinderVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopolo
return nil, err
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
volumeMode := c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
pv := &v1.PersistentVolume{

View File

@ -17,14 +17,12 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/fc",
deps = [
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/mount:go_default_library",

View File

@ -28,8 +28,6 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
)
@ -209,26 +207,17 @@ func volumeSpecToMounter(spec *volume.Spec, host volume.VolumeHost) (*fcDiskMoun
wwids: wwids,
io: &osIOHandler{},
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode, err := volumeutil.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("fc: volumeSpecToMounter volumeMode %s", volumeMode)
return &fcDiskMounter{
fcDisk: fcDisk,
fsType: fc.FSType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: volumeutil.NewSafeFormatAndMountFromHost(fcPluginName, host),
deviceUtil: volumeutil.NewDeviceHandler(volumeutil.NewIOHandler()),
mountOptions: volumeutil.MountOptionFromSpec(spec),
}, nil
volumeMode, err := volumeutil.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("fc: volumeSpecToMounter volumeMode %s", volumeMode)
return &fcDiskMounter{
fcDisk: fcDisk,
fsType: fc.FSType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: volumeutil.NewSafeFormatAndMountFromHost(fcPluginName, host),
deviceUtil: volumeutil.NewDeviceHandler(volumeutil.NewIOHandler()),

View File

@ -31,8 +31,6 @@ import (
v1 "k8s.io/api/core/v1"
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/volume"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
@ -134,32 +132,22 @@ func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID,
io: &osIOHandler{},
plugin: plugin,
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode, err := util.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("fc: newMounterInternal volumeMode %s", volumeMode)
return &fcDiskMounter{
fcDisk: fcDisk,
fsType: fc.FSType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
deviceUtil: util.NewDeviceHandler(util.NewIOHandler()),
mountOptions: util.MountOptionFromSpec(spec),
}, nil
volumeMode, err := util.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("fc: newMounterInternal volumeMode %s", volumeMode)
return &fcDiskMounter{
fcDisk: fcDisk,
fsType: fc.FSType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
deviceUtil: util.NewDeviceHandler(util.NewIOHandler()),
mountOptions: util.MountOptionFromSpec(spec),
}, nil
}
func (plugin *fcPlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.BlockVolumeMapper, error) {

View File

@ -28,8 +28,6 @@ import (
"k8s.io/utils/mount"
v1 "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
)
@ -243,14 +241,12 @@ func (util *fcUtil) AttachDisk(b fcDiskMounter) (string, error) {
if err != nil {
return "", err
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
// If the volumeMode is 'Block', plugin don't have to format the volume.
// The globalPDPath will be created by operationexecutor. Just return devicePath here.
klog.V(5).Infof("fc: AttachDisk volumeMode: %s, devicePath: %s", b.volumeMode, devicePath)
if b.volumeMode == v1.PersistentVolumeBlock {
return devicePath, nil
}
// If the volumeMode is 'Block', plugin don't have to format the volume.
// The globalPDPath will be created by operationexecutor. Just return devicePath here.
klog.V(5).Infof("fc: AttachDisk volumeMode: %s, devicePath: %s", b.volumeMode, devicePath)
if b.volumeMode == v1.PersistentVolumeBlock {
return devicePath, nil
}
// mount it

View File

@ -17,7 +17,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/gcepd",
deps = [
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
@ -26,7 +25,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",

View File

@ -34,9 +34,7 @@ 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"
volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
gcecloud "k8s.io/legacy-cloud-providers/gce"
@ -500,13 +498,10 @@ func (c *gcePersistentDiskProvisioner) Provision(selectedNode *v1.Node, allowedT
fstype = "ext4"
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
volumeMode := c.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
pv := &v1.PersistentVolume{

View File

@ -17,7 +17,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/iscsi",
deps = [
"//pkg/features:go_default_library",
"//pkg/kubelet/config:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
@ -25,7 +24,6 @@ go_library(
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/keymutex:go_default_library",

View File

@ -27,8 +27,6 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
)
@ -209,26 +207,17 @@ func volumeSpecToMounter(spec *volume.Spec, host volume.VolumeHost, targetLocks
return nil, err
}
exec := host.GetExec(iscsiPluginName)
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode, err := volumeutil.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("iscsi: VolumeSpecToMounter volumeMode %s", volumeMode)
return &iscsiDiskMounter{
iscsiDisk: iscsiDisk,
fsType: fsType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: host.GetMounter(iscsiPluginName), Exec: exec},
exec: exec,
deviceUtil: volumeutil.NewDeviceHandler(volumeutil.NewIOHandler()),
}, nil
volumeMode, err := volumeutil.GetVolumeMode(spec)
if err != nil {
return nil, err
}
klog.V(5).Infof("iscsi: VolumeSpecToMounter volumeMode %s", volumeMode)
return &iscsiDiskMounter{
iscsiDisk: iscsiDisk,
fsType: fsType,
volumeMode: volumeMode,
readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: host.GetMounter(iscsiPluginName), Exec: exec},
exec: exec,

View File

@ -34,8 +34,6 @@ import (
"k8s.io/utils/mount"
v1 "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
@ -469,25 +467,23 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) (string, error) {
// If the volumeMode is 'Block', plugin creates a dir and persists iscsi configurations.
// Since volume type is block, plugin doesn't need to format/mount the volume.
func globalPDPathOperation(b iscsiDiskMounter) func(iscsiDiskMounter, string, *ISCSIUtil) (string, error) {
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
klog.V(5).Infof("iscsi: AttachDisk volumeMode: %s", b.volumeMode)
if b.volumeMode == v1.PersistentVolumeBlock {
// If the volumeMode is 'Block', plugin don't need to format the volume.
return func(b iscsiDiskMounter, devicePath string, util *ISCSIUtil) (string, error) {
globalPDPath := b.manager.MakeGlobalVDPDName(*b.iscsiDisk)
// Create dir like /var/lib/kubelet/plugins/kubernetes.io/iscsi/volumeDevices/{ifaceName}/{portal-some_iqn-lun-lun_id}
if err := os.MkdirAll(globalPDPath, 0750); err != nil {
klog.Errorf("iscsi: failed to mkdir %s, error", globalPDPath)
return "", err
}
// Persist iscsi disk config to json file for DetachDisk path
util.persistISCSI(*(b.iscsiDisk), globalPDPath)
return devicePath, nil
klog.V(5).Infof("iscsi: AttachDisk volumeMode: %s", b.volumeMode)
if b.volumeMode == v1.PersistentVolumeBlock {
// If the volumeMode is 'Block', plugin don't need to format the volume.
return func(b iscsiDiskMounter, devicePath string, util *ISCSIUtil) (string, error) {
globalPDPath := b.manager.MakeGlobalVDPDName(*b.iscsiDisk)
// Create dir like /var/lib/kubelet/plugins/kubernetes.io/iscsi/volumeDevices/{ifaceName}/{portal-some_iqn-lun-lun_id}
if err := os.MkdirAll(globalPDPath, 0750); err != nil {
klog.Errorf("iscsi: failed to mkdir %s, error", globalPDPath)
return "", err
}
// Persist iscsi disk config to json file for DetachDisk path
util.persistISCSI(*(b.iscsiDisk), globalPDPath)
return devicePath, nil
}
}
// If the volumeMode is 'Filesystem', plugin needs to format the volume
// and mount it to globalPDPath.
return func(b iscsiDiskMounter, devicePath string, util *ISCSIUtil) (string, error) {

View File

@ -17,7 +17,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/rbd",
deps = [
"//pkg/features:go_default_library",
"//pkg/util/node:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
@ -30,7 +29,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",
"//vendor/k8s.io/klog:go_default_library",

View File

@ -35,9 +35,7 @@ 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/volume"
"k8s.io/kubernetes/pkg/volume/util"
volutil "k8s.io/kubernetes/pkg/volume/util"
@ -717,13 +715,10 @@ func (r *rbdVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
rbd.Keyring = keyring
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = r.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
volumeMode := r.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
// Block volumes should not have any FSType
fstype = ""
}
rbd.RadosUser = r.ID

View File

@ -22,7 +22,6 @@ go_library(
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/v1/pod:go_default_library",
"//pkg/apis/core/v1/helper:go_default_library",
"//pkg/features:go_default_library",
"//pkg/util/resizefs:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util/types:go_default_library",
@ -38,7 +37,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/component-base/metrics:go_default_library",
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",

View File

@ -39,12 +39,10 @@ import (
apiruntime "k8s.io/apimachinery/pkg/runtime"
utypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/api/legacyscheme"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
@ -436,14 +434,12 @@ func GetPersistentVolumeClaimQualifiedName(claim *v1.PersistentVolumeClaim) stri
// CheckVolumeModeFilesystem checks VolumeMode.
// If the mode is Filesystem, return true otherwise return false.
func CheckVolumeModeFilesystem(volumeSpec *volume.Spec) (bool, error) {
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode, err := GetVolumeMode(volumeSpec)
if err != nil {
return true, err
}
if volumeMode == v1.PersistentVolumeBlock {
return false, nil
}
volumeMode, err := GetVolumeMode(volumeSpec)
if err != nil {
return true, err
}
if volumeMode == v1.PersistentVolumeBlock {
return false, nil
}
return true, nil
}
@ -451,7 +447,7 @@ func CheckVolumeModeFilesystem(volumeSpec *volume.Spec) (bool, error) {
// 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
return pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock
}
// IsWindowsUNCPath checks if path is prefixed with \\
@ -602,9 +598,7 @@ func GetPodVolumeNames(pod *v1.Pod) (mounts sets.String, devices sets.String) {
mounts.Insert(mount.Name)
}
}
// TODO: remove feature gate check after no longer needed
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) &&
container.VolumeDevices != nil {
if container.VolumeDevices != nil {
for _, device := range container.VolumeDevices {
devices.Insert(device.Name)
}

View File

@ -20,7 +20,6 @@ go_library(
],
importpath = "k8s.io/kubernetes/pkg/volume/vsphere_volume",
deps = [
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library",
@ -28,7 +27,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/vsphere:go_default_library",

View File

@ -33,9 +33,7 @@ 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"
volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
)
@ -382,13 +380,10 @@ func (v *vsphereVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopol
volSpec.Fstype = "ext4"
}
var volumeMode *v1.PersistentVolumeMode
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
volumeMode = v.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
klog.V(5).Infof("vSphere block volume should not have any FSType")
volSpec.Fstype = ""
}
volumeMode := v.options.PVC.Spec.VolumeMode
if volumeMode != nil && *volumeMode == v1.PersistentVolumeBlock {
klog.V(5).Infof("vSphere block volume should not have any FSType")
volSpec.Fstype = ""
}
pv := &v1.PersistentVolume{

View File

@ -689,7 +689,6 @@ message Container {
repeated VolumeMount volumeMounts = 9;
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +patchMergeKey=devicePath
// +patchStrategy=merge
// +optional
@ -1276,7 +1275,6 @@ message EphemeralContainerCommon {
repeated VolumeMount volumeMounts = 9;
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +patchMergeKey=devicePath
// +patchStrategy=merge
// +optional
@ -2636,7 +2634,6 @@ message PersistentVolumeClaimSpec {
// volumeMode defines what type of volume is required by the claim.
// Value of Filesystem is implied when not included in claim spec.
// This is a beta feature.
// +optional
optional string volumeMode = 6;
@ -2852,7 +2849,6 @@ message PersistentVolumeSpec {
// volumeMode defines if a volume is intended to be used with a formatted filesystem
// or to remain in raw block state. Value of Filesystem is implied when not included in spec.
// This is a beta feature.
// +optional
optional string volumeMode = 8;

View File

@ -331,7 +331,6 @@ type PersistentVolumeSpec struct {
MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,7,opt,name=mountOptions"`
// volumeMode defines if a volume is intended to be used with a formatted filesystem
// or to remain in raw block state. Value of Filesystem is implied when not included in spec.
// This is a beta feature.
// +optional
VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,8,opt,name=volumeMode,casttype=PersistentVolumeMode"`
// NodeAffinity defines constraints that limit what nodes this volume can be accessed from.
@ -460,7 +459,6 @@ type PersistentVolumeClaimSpec struct {
StorageClassName *string `json:"storageClassName,omitempty" protobuf:"bytes,5,opt,name=storageClassName"`
// volumeMode defines what type of volume is required by the claim.
// Value of Filesystem is implied when not included in claim spec.
// This is a beta feature.
// +optional
VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,6,opt,name=volumeMode,casttype=PersistentVolumeMode"`
// This field requires the VolumeSnapshotDataSource alpha feature gate to be
@ -2181,7 +2179,6 @@ type Container struct {
// +patchStrategy=merge
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"`
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +patchMergeKey=devicePath
// +patchStrategy=merge
// +optional
@ -3298,7 +3295,6 @@ type EphemeralContainerCommon struct {
// +patchStrategy=merge
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"`
// volumeDevices is the list of block devices to be used by the container.
// This is a beta feature.
// +patchMergeKey=devicePath
// +patchStrategy=merge
// +optional

View File

@ -336,7 +336,7 @@ var map_Container = map[string]string{
"env": "List of environment variables to set in the container. Cannot be updated.",
"resources": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/",
"volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.",
"volumeDevices": "volumeDevices is the list of block devices to be used by the container. This is a beta feature.",
"volumeDevices": "volumeDevices is the list of block devices to be used by the container.",
"livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
"readinessProbe": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
"startupProbe": "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
@ -599,7 +599,7 @@ var map_EphemeralContainerCommon = map[string]string{
"env": "List of environment variables to set in the container. Cannot be updated.",
"resources": "Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod.",
"volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.",
"volumeDevices": "volumeDevices is the list of block devices to be used by the container. This is a beta feature.",
"volumeDevices": "volumeDevices is the list of block devices to be used by the container.",
"livenessProbe": "Probes are not allowed for ephemeral containers.",
"readinessProbe": "Probes are not allowed for ephemeral containers.",
"startupProbe": "Probes are not allowed for ephemeral containers.",
@ -1300,7 +1300,7 @@ var map_PersistentVolumeClaimSpec = map[string]string{
"resources": "Resources represents the minimum resources the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources",
"volumeName": "VolumeName is the binding reference to the PersistentVolume backing this claim.",
"storageClassName": "Name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1",
"volumeMode": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. This is a beta feature.",
"volumeMode": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.",
"dataSource": "This field requires the VolumeSnapshotDataSource alpha feature gate to be enabled and currently VolumeSnapshot is the only supported data source. If the provisioner can support VolumeSnapshot data source, it will create a new volume and data will be restored to the volume at the same time. If the provisioner does not support VolumeSnapshot data source, volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change.",
}
@ -1378,7 +1378,7 @@ var map_PersistentVolumeSpec = map[string]string{
"persistentVolumeReclaimPolicy": "What happens to a persistent volume when released from its claim. Valid options are Retain (default for manually created PersistentVolumes), Delete (default for dynamically provisioned PersistentVolumes), and Recycle (deprecated). Recycle must be supported by the volume plugin underlying this PersistentVolume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming",
"storageClassName": "Name of StorageClass to which this persistent volume belongs. Empty value means that this volume does not belong to any StorageClass.",
"mountOptions": "A list of mount options, e.g. [\"ro\", \"soft\"]. Not validated - mount will simply fail if one is invalid. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#mount-options",
"volumeMode": "volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec. This is a beta feature.",
"volumeMode": "volumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state. Value of Filesystem is implied when not included in spec.",
"nodeAffinity": "NodeAffinity defines constraints that limit what nodes this volume can be accessed from. This field influences the scheduling of pods that use this volume.",
}