mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
Move CSIInlineVolume feature to GA
This commit is contained in:
parent
897cdea783
commit
5f774832a5
@ -43,7 +43,6 @@ import (
|
|||||||
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
persistentvolumeconfig "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/config"
|
persistentvolumeconfig "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/config"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/utils/exec"
|
"k8s.io/utils/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -128,10 +127,7 @@ func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config persiste
|
|||||||
}
|
}
|
||||||
|
|
||||||
allPlugins = append(allPlugins, local.ProbeVolumePlugins()...)
|
allPlugins = append(allPlugins, local.ProbeVolumePlugins()...)
|
||||||
|
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return allPlugins, nil
|
return allPlugins, nil
|
||||||
}
|
}
|
||||||
|
@ -542,8 +542,6 @@ func dropDisabledFields(
|
|||||||
|
|
||||||
dropDisabledProcMountField(podSpec, oldPodSpec)
|
dropDisabledProcMountField(podSpec, oldPodSpec)
|
||||||
|
|
||||||
dropDisabledCSIVolumeSourceAlphaFields(podSpec, oldPodSpec)
|
|
||||||
|
|
||||||
dropDisabledTopologySpreadConstraintsFields(podSpec, oldPodSpec)
|
dropDisabledTopologySpreadConstraintsFields(podSpec, oldPodSpec)
|
||||||
dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec)
|
dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec)
|
||||||
dropDisabledMatchLabelKeysField(podSpec, oldPodSpec)
|
dropDisabledMatchLabelKeysField(podSpec, oldPodSpec)
|
||||||
@ -593,16 +591,6 @@ func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) && !csiInUse(oldPodSpec) {
|
|
||||||
for i := range podSpec.Volumes {
|
|
||||||
podSpec.Volumes[i].CSI = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dropDisabledNodeInclusionPolicyFields removes disabled fields from PodSpec related
|
// dropDisabledNodeInclusionPolicyFields removes disabled fields from PodSpec related
|
||||||
// to NodeInclusionPolicy only if it is not used by the old spec.
|
// to NodeInclusionPolicy only if it is not used by the old spec.
|
||||||
func dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec *api.PodSpec) {
|
func dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec *api.PodSpec) {
|
||||||
@ -734,19 +722,6 @@ func probeGracePeriodInUse(podSpec *api.PodSpec) bool {
|
|||||||
return inUse
|
return inUse
|
||||||
}
|
}
|
||||||
|
|
||||||
// csiInUse returns true if any pod's spec include inline CSI volumes.
|
|
||||||
func csiInUse(podSpec *api.PodSpec) bool {
|
|
||||||
if podSpec == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := range podSpec.Volumes {
|
|
||||||
if podSpec.Volumes[i].CSI != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// SeccompAnnotationForField takes a pod seccomp profile field and returns the
|
// SeccompAnnotationForField takes a pod seccomp profile field and returns the
|
||||||
// converted annotation value
|
// converted annotation value
|
||||||
func SeccompAnnotationForField(field *api.SeccompProfile) string {
|
func SeccompAnnotationForField(field *api.SeccompProfile) string {
|
||||||
|
@ -28,9 +28,6 @@ func DropDisabledFields(pspSpec, oldPSPSpec *policy.PodSecurityPolicySpec) {
|
|||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ProcMountType) && !allowedProcMountTypesInUse(oldPSPSpec) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.ProcMountType) && !allowedProcMountTypesInUse(oldPSPSpec) {
|
||||||
pspSpec.AllowedProcMountTypes = nil
|
pspSpec.AllowedProcMountTypes = nil
|
||||||
}
|
}
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
pspSpec.AllowedCSIDrivers = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func allowedProcMountTypesInUse(oldPSPSpec *policy.PodSecurityPolicySpec) bool {
|
func allowedProcMountTypesInUse(oldPSPSpec *policy.PodSecurityPolicySpec) bool {
|
||||||
|
@ -214,7 +214,6 @@ type PodSecurityPolicySpec struct {
|
|||||||
AllowedFlexVolumes []AllowedFlexVolume
|
AllowedFlexVolumes []AllowedFlexVolume
|
||||||
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
||||||
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
||||||
// This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.
|
|
||||||
// +optional
|
// +optional
|
||||||
AllowedCSIDrivers []AllowedCSIDriver
|
AllowedCSIDrivers []AllowedCSIDriver
|
||||||
// AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.
|
// AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.
|
||||||
|
@ -57,7 +57,7 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
|
|||||||
obj.Spec.FSGroupPolicy = new(storagev1.FSGroupPolicy)
|
obj.Spec.FSGroupPolicy = new(storagev1.FSGroupPolicy)
|
||||||
*obj.Spec.FSGroupPolicy = storagev1.ReadWriteOnceWithFSTypeFSGroupPolicy
|
*obj.Spec.FSGroupPolicy = storagev1.ReadWriteOnceWithFSTypeFSGroupPolicy
|
||||||
}
|
}
|
||||||
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if len(obj.Spec.VolumeLifecycleModes) == 0 {
|
||||||
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1.VolumeLifecyclePersistent)
|
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1.VolumeLifecyclePersistent)
|
||||||
}
|
}
|
||||||
if obj.Spec.RequiresRepublish == nil {
|
if obj.Spec.RequiresRepublish == nil {
|
||||||
|
@ -80,8 +80,6 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultCSIDriver(t *testing.T) {
|
func TestSetDefaultCSIDriver(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
enabled := true
|
enabled := true
|
||||||
disabled := false
|
disabled := false
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -57,7 +57,7 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
|
|||||||
obj.Spec.FSGroupPolicy = new(storagev1beta1.FSGroupPolicy)
|
obj.Spec.FSGroupPolicy = new(storagev1beta1.FSGroupPolicy)
|
||||||
*obj.Spec.FSGroupPolicy = storagev1beta1.ReadWriteOnceWithFSTypeFSGroupPolicy
|
*obj.Spec.FSGroupPolicy = storagev1beta1.ReadWriteOnceWithFSTypeFSGroupPolicy
|
||||||
}
|
}
|
||||||
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if len(obj.Spec.VolumeLifecycleModes) == 0 {
|
||||||
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1beta1.VolumeLifecyclePersistent)
|
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1beta1.VolumeLifecyclePersistent)
|
||||||
}
|
}
|
||||||
if obj.Spec.RequiresRepublish == nil {
|
if obj.Spec.RequiresRepublish == nil {
|
||||||
|
@ -101,7 +101,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
|
func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
driver := &storagev1beta1.CSIDriver{}
|
driver := &storagev1beta1.CSIDriver{}
|
||||||
|
|
||||||
// field should be defaulted
|
// field should be defaulted
|
||||||
@ -115,21 +114,7 @@ func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultVolumeLifecycleModesDisabled(t *testing.T) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, false)()
|
|
||||||
driver := &storagev1beta1.CSIDriver{}
|
|
||||||
|
|
||||||
// field should not be defaulted
|
|
||||||
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
|
|
||||||
outModes := output.Spec.VolumeLifecycleModes
|
|
||||||
if outModes != nil {
|
|
||||||
t.Errorf("Expected VolumeLifecycleModes to remain nil, got: %+v", outModes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetDefaultCSIDriver(t *testing.T) {
|
func TestSetDefaultCSIDriver(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
enabled := true
|
enabled := true
|
||||||
disabled := false
|
disabled := false
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -97,6 +97,7 @@ const (
|
|||||||
// owner: @pohly
|
// owner: @pohly
|
||||||
// alpha: v1.14
|
// alpha: v1.14
|
||||||
// beta: v1.16
|
// beta: v1.16
|
||||||
|
// GA: v1.25
|
||||||
//
|
//
|
||||||
// Enables CSI Inline volumes support for pods
|
// Enables CSI Inline volumes support for pods
|
||||||
CSIInlineVolume featuregate.Feature = "CSIInlineVolume"
|
CSIInlineVolume featuregate.Feature = "CSIInlineVolume"
|
||||||
@ -895,7 +896,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
|
||||||
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
CSIInlineVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27
|
||||||
|
|
||||||
CSIMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27
|
CSIMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27
|
||||||
|
|
||||||
|
2
pkg/generated/openapi/zz_generated.openapi.go
generated
2
pkg/generated/openapi/zz_generated.openapi.go
generated
@ -36304,7 +36304,7 @@ func schema_k8sio_api_policy_v1beta1_PodSecurityPolicySpec(ref common.ReferenceC
|
|||||||
},
|
},
|
||||||
"allowedCSIDrivers": {
|
"allowedCSIDrivers": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes. This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.",
|
Description: "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.",
|
||||||
Type: []string{"array"},
|
Type: []string{"array"},
|
||||||
Items: &spec.SchemaOrArray{
|
Items: &spec.SchemaOrArray{
|
||||||
Schema: &spec.Schema{
|
Schema: &spec.Schema{
|
||||||
|
@ -47,9 +47,6 @@ func (csiDriverStrategy) NamespaceScoped() bool {
|
|||||||
// PrepareForCreate clears the fields for which the corresponding feature is disabled.
|
// PrepareForCreate clears the fields for which the corresponding feature is disabled.
|
||||||
func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
||||||
csiDriver := obj.(*storage.CSIDriver)
|
csiDriver := obj.(*storage.CSIDriver)
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
csiDriver.Spec.VolumeLifecycleModes = nil
|
|
||||||
}
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
csiDriver.Spec.SELinuxMount = nil
|
csiDriver.Spec.SELinuxMount = nil
|
||||||
}
|
}
|
||||||
@ -81,11 +78,6 @@ func (csiDriverStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
|
|||||||
newCSIDriver := obj.(*storage.CSIDriver)
|
newCSIDriver := obj.(*storage.CSIDriver)
|
||||||
oldCSIDriver := old.(*storage.CSIDriver)
|
oldCSIDriver := old.(*storage.CSIDriver)
|
||||||
|
|
||||||
if oldCSIDriver.Spec.VolumeLifecycleModes == nil &&
|
|
||||||
!utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
newCSIDriver.Spec.VolumeLifecycleModes = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if oldCSIDriver.Spec.SELinuxMount == nil &&
|
if oldCSIDriver.Spec.SELinuxMount == nil &&
|
||||||
!utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
!utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
newCSIDriver.Spec.SELinuxMount = nil
|
newCSIDriver.Spec.SELinuxMount = nil
|
||||||
|
@ -79,72 +79,6 @@ func TestCSIDriverStrategy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCSIDriverPrepareForCreate(t *testing.T) {
|
|
||||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{
|
|
||||||
APIGroup: "storage.k8s.io",
|
|
||||||
APIVersion: "v1",
|
|
||||||
Resource: "csidrivers",
|
|
||||||
})
|
|
||||||
|
|
||||||
attachRequired := true
|
|
||||||
podInfoOnMount := true
|
|
||||||
storageCapacity := true
|
|
||||||
requiresRepublish := true
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
withInline bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "inline enabled",
|
|
||||||
withInline: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "inline disabled",
|
|
||||||
withInline: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)()
|
|
||||||
|
|
||||||
csiDriver := &storage.CSIDriver{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Spec: storage.CSIDriverSpec{
|
|
||||||
AttachRequired: &attachRequired,
|
|
||||||
PodInfoOnMount: &podInfoOnMount,
|
|
||||||
StorageCapacity: &storageCapacity,
|
|
||||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
|
||||||
storage.VolumeLifecyclePersistent,
|
|
||||||
},
|
|
||||||
TokenRequests: []storage.TokenRequest{},
|
|
||||||
RequiresRepublish: &requiresRepublish,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
Strategy.PrepareForCreate(ctx, csiDriver)
|
|
||||||
errs := Strategy.Validate(ctx, csiDriver)
|
|
||||||
if len(errs) != 0 {
|
|
||||||
t.Errorf("unexpected validating errors: %v", errs)
|
|
||||||
}
|
|
||||||
if csiDriver.Spec.StorageCapacity == nil || *csiDriver.Spec.StorageCapacity != storageCapacity {
|
|
||||||
t.Errorf("StorageCapacity modified: %v", csiDriver.Spec.StorageCapacity)
|
|
||||||
}
|
|
||||||
if test.withInline {
|
|
||||||
if len(csiDriver.Spec.VolumeLifecycleModes) != 1 {
|
|
||||||
t.Errorf("VolumeLifecycleModes modified: %v", csiDriver.Spec)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(csiDriver.Spec.VolumeLifecycleModes) != 0 {
|
|
||||||
t.Errorf("VolumeLifecycleModes not stripped: %v", csiDriver.Spec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
||||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{
|
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{
|
||||||
APIGroup: "storage.k8s.io",
|
APIGroup: "storage.k8s.io",
|
||||||
@ -171,18 +105,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
driverWithEphemeral := &storage.CSIDriver{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Spec: storage.CSIDriverSpec{
|
|
||||||
AttachRequired: &attachRequired,
|
|
||||||
PodInfoOnMount: &podInfoOnMount,
|
|
||||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{
|
|
||||||
storage.VolumeLifecycleEphemeral,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
enabled := true
|
enabled := true
|
||||||
disabled := false
|
disabled := false
|
||||||
gcp := "gcp"
|
gcp := "gcp"
|
||||||
@ -233,7 +155,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
old, update *storage.CSIDriver
|
old, update *storage.CSIDriver
|
||||||
csiInlineVolumeEnabled bool
|
|
||||||
seLinuxMountReadWriteOncePodEnabled bool
|
seLinuxMountReadWriteOncePodEnabled bool
|
||||||
wantCapacity *bool
|
wantCapacity *bool
|
||||||
wantModes []storage.VolumeLifecycleMode
|
wantModes []storage.VolumeLifecycleMode
|
||||||
@ -255,22 +176,9 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
wantCapacity: &disabled,
|
wantCapacity: &disabled,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inline feature enabled, before: none, update: persistent",
|
name: "inline feature enabled, before: none, update: persistent",
|
||||||
csiInlineVolumeEnabled: true,
|
|
||||||
old: driverWithNothing,
|
|
||||||
update: driverWithPersistent,
|
|
||||||
wantModes: resultPersistent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "inline feature disabled, before: none, update: persistent",
|
|
||||||
old: driverWithNothing,
|
old: driverWithNothing,
|
||||||
update: driverWithPersistent,
|
update: driverWithPersistent,
|
||||||
wantModes: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "inline feature disabled, before: ephemeral, update: persistent",
|
|
||||||
old: driverWithEphemeral,
|
|
||||||
update: driverWithPersistent,
|
|
||||||
wantModes: resultPersistent,
|
wantModes: resultPersistent,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -333,7 +241,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.seLinuxMountReadWriteOncePodEnabled)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.seLinuxMountReadWriteOncePodEnabled)()
|
||||||
|
|
||||||
csiDriver := test.update.DeepCopy()
|
csiDriver := test.update.DeepCopy()
|
||||||
|
@ -249,7 +249,6 @@ func TestAttacherAttach(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAttacherAttachWithInline(t *testing.T) {
|
func TestAttacherAttachWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
nodeName string
|
nodeName string
|
||||||
@ -574,8 +573,6 @@ func TestAttacherWaitForAttach(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAttacherWaitForAttachWithInline(t *testing.T) {
|
func TestAttacherWaitForAttachWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
driver string
|
driver string
|
||||||
@ -862,7 +859,6 @@ func TestAttacherVolumesAreAttached(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAttacherVolumesAreAttachedWithInline(t *testing.T) {
|
func TestAttacherVolumesAreAttachedWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
type attachedSpec struct {
|
type attachedSpec struct {
|
||||||
volName string
|
volName string
|
||||||
spec *volume.Spec
|
spec *volume.Spec
|
||||||
@ -1424,7 +1420,6 @@ func TestAttacherMountDevice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAttacherMountDeviceWithInline(t *testing.T) {
|
func TestAttacherMountDeviceWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DelegateFSGroupToCSIDriver, true)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DelegateFSGroupToCSIDriver, true)()
|
||||||
pvName := "test-pv"
|
pvName := "test-pv"
|
||||||
var testFSGroup int64 = 3000
|
var testFSGroup int64 = 3000
|
||||||
|
@ -134,9 +134,6 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case volSrc != nil:
|
case volSrc != nil:
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
return fmt.Errorf("CSIInlineVolume feature required")
|
|
||||||
}
|
|
||||||
if c.volumeLifecycleMode != storage.VolumeLifecycleEphemeral {
|
if c.volumeLifecycleMode != storage.VolumeLifecycleEphemeral {
|
||||||
return fmt.Errorf("unexpected volume mode: %s", c.volumeLifecycleMode)
|
return fmt.Errorf("unexpected volume mode: %s", c.volumeLifecycleMode)
|
||||||
}
|
}
|
||||||
@ -430,10 +427,6 @@ func (c *csiMountMgr) supportsFSGroup(fsType string, fsGroup *int64, driverPolic
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else if c.spec.Volume != nil && c.spec.Volume.CSI != nil {
|
} else if c.spec.Volume != nil && c.spec.Volume.CSI != nil {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
klog.V(4).Info(log("mounter.SetupAt WARNING: skipping fsGroup, CSIInlineVolume feature required"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// Inline CSI volumes are always mounted with RWO AccessMode by SetUpAt
|
// Inline CSI volumes are always mounted with RWO AccessMode by SetUpAt
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,6 @@ func TestMounterSetUp(t *testing.T) {
|
|||||||
driver string
|
driver string
|
||||||
volumeContext map[string]string
|
volumeContext map[string]string
|
||||||
expectedVolumeContext map[string]string
|
expectedVolumeContext map[string]string
|
||||||
csiInlineVolume bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no pod info",
|
name: "no pod info",
|
||||||
@ -141,20 +140,19 @@ func TestMounterSetUp(t *testing.T) {
|
|||||||
name: "add pod info",
|
name: "add pod info",
|
||||||
driver: "info",
|
driver: "info",
|
||||||
volumeContext: nil,
|
volumeContext: nil,
|
||||||
expectedVolumeContext: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"},
|
expectedVolumeContext: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns", "csi.storage.k8s.io/ephemeral": "false"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add pod info -> keep existing volumeContext",
|
name: "add pod info -> keep existing volumeContext",
|
||||||
driver: "info",
|
driver: "info",
|
||||||
volumeContext: map[string]string{"foo": "bar"},
|
volumeContext: map[string]string{"foo": "bar"},
|
||||||
expectedVolumeContext: map[string]string{"foo": "bar", "csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"},
|
expectedVolumeContext: map[string]string{"foo": "bar", "csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns", "csi.storage.k8s.io/ephemeral": "false"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "CSIInlineVolume pod info",
|
name: "CSIInlineVolume pod info",
|
||||||
driver: "info",
|
driver: "info",
|
||||||
volumeContext: nil,
|
volumeContext: nil,
|
||||||
expectedVolumeContext: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns", "csi.storage.k8s.io/ephemeral": "false"},
|
expectedVolumeContext: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns", "csi.storage.k8s.io/ephemeral": "false"},
|
||||||
csiInlineVolume: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,11 +160,8 @@ func TestMounterSetUp(t *testing.T) {
|
|||||||
currentPodInfoMount := true
|
currentPodInfoMount := true
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
// Modes must be set if (and only if) CSIInlineVolume is enabled.
|
modes := []storage.VolumeLifecycleMode{
|
||||||
var modes []storage.VolumeLifecycleMode
|
storage.VolumeLifecyclePersistent,
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolume)()
|
|
||||||
if test.csiInlineVolume {
|
|
||||||
modes = append(modes, storage.VolumeLifecyclePersistent)
|
|
||||||
}
|
}
|
||||||
fakeClient := fakeclient.NewSimpleClientset(
|
fakeClient := fakeclient.NewSimpleClientset(
|
||||||
getTestCSIDriver("no-info", &noPodMountInfo, nil, modes),
|
getTestCSIDriver("no-info", &noPodMountInfo, nil, modes),
|
||||||
@ -500,8 +495,6 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMounterSetUpWithInline(t *testing.T) {
|
func TestMounterSetUpWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
podUID types.UID
|
podUID types.UID
|
||||||
@ -983,7 +976,6 @@ func TestIsCorruptedDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPodServiceAccountTokenAttrs(t *testing.T) {
|
func TestPodServiceAccountTokenAttrs(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
scheme := runtime.NewScheme()
|
scheme := runtime.NewScheme()
|
||||||
utilruntime.Must(pkgauthenticationv1.RegisterDefaults(scheme))
|
utilruntime.Must(pkgauthenticationv1.RegisterDefaults(scheme))
|
||||||
utilruntime.Must(pkgstoragev1.RegisterDefaults(scheme))
|
utilruntime.Must(pkgstoragev1.RegisterDefaults(scheme))
|
||||||
|
@ -334,12 +334,8 @@ func (p *csiPlugin) CanSupport(spec *volume.Spec) bool {
|
|||||||
if spec == nil {
|
if spec == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil) ||
|
||||||
return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil) ||
|
(spec.Volume != nil && spec.Volume.CSI != nil)
|
||||||
(spec.Volume != nil && spec.Volume.CSI != nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *csiPlugin) RequiresRemount(spec *volume.Spec) bool {
|
func (p *csiPlugin) RequiresRemount(spec *volume.Spec) bool {
|
||||||
@ -376,7 +372,7 @@ func (p *csiPlugin) NewMounter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case volSrc != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume):
|
case volSrc != nil:
|
||||||
volumeHandle = makeVolumeHandle(string(pod.UID), spec.Name())
|
volumeHandle = makeVolumeHandle(string(pod.UID), spec.Name())
|
||||||
driverName = volSrc.Driver
|
driverName = volSrc.Driver
|
||||||
if volSrc.ReadOnly != nil {
|
if volSrc.ReadOnly != nil {
|
||||||
@ -520,13 +516,10 @@ func (p *csiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.S
|
|||||||
klog.V(4).Info(log("plugin.ConstructVolumeSpec extracted [%#v]", volData))
|
klog.V(4).Info(log("plugin.ConstructVolumeSpec extracted [%#v]", volData))
|
||||||
|
|
||||||
var spec *volume.Spec
|
var spec *volume.Spec
|
||||||
inlineEnabled := utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume)
|
// If mode is VolumeLifecycleEphemeral, use constructVolSourceSpec
|
||||||
|
// to construct volume source spec. If mode is VolumeLifecyclePersistent,
|
||||||
// If inlineEnabled is true and mode is VolumeLifecycleEphemeral,
|
|
||||||
// use constructVolSourceSpec to construct volume source spec.
|
|
||||||
// If inlineEnabled is false or mode is VolumeLifecyclePersistent,
|
|
||||||
// use constructPVSourceSpec to construct volume construct pv source spec.
|
// use constructPVSourceSpec to construct volume construct pv source spec.
|
||||||
if inlineEnabled && storage.VolumeLifecycleMode(volData[volDataKey.volumeLifecycleMode]) == storage.VolumeLifecycleEphemeral {
|
if storage.VolumeLifecycleMode(volData[volDataKey.volumeLifecycleMode]) == storage.VolumeLifecycleEphemeral {
|
||||||
spec = p.constructVolSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName])
|
spec = p.constructVolSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName])
|
||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
@ -617,17 +610,14 @@ func (p *csiPlugin) NewDetacher() (volume.Detacher, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *csiPlugin) CanAttach(spec *volume.Spec) (bool, error) {
|
func (p *csiPlugin) CanAttach(spec *volume.Spec) (bool, error) {
|
||||||
inlineEnabled := utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume)
|
volumeLifecycleMode, err := p.getVolumeLifecycleMode(spec)
|
||||||
if inlineEnabled {
|
if err != nil {
|
||||||
volumeLifecycleMode, err := p.getVolumeLifecycleMode(spec)
|
return false, err
|
||||||
if err != nil {
|
}
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if volumeLifecycleMode == storage.VolumeLifecycleEphemeral {
|
if volumeLifecycleMode == storage.VolumeLifecycleEphemeral {
|
||||||
klog.V(5).Info(log("plugin.CanAttach = false, ephemeral mode detected for spec %v", spec.Name()))
|
klog.V(5).Info(log("plugin.CanAttach = false, ephemeral mode detected for spec %v", spec.Name()))
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pvSrc, err := getCSISourceFromSpec(spec)
|
pvSrc, err := getCSISourceFromSpec(spec)
|
||||||
@ -647,12 +637,6 @@ func (p *csiPlugin) CanAttach(spec *volume.Spec) (bool, error) {
|
|||||||
|
|
||||||
// CanDeviceMount returns true if the spec supports device mount
|
// CanDeviceMount returns true if the spec supports device mount
|
||||||
func (p *csiPlugin) CanDeviceMount(spec *volume.Spec) (bool, error) {
|
func (p *csiPlugin) CanDeviceMount(spec *volume.Spec) (bool, error) {
|
||||||
inlineEnabled := utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume)
|
|
||||||
if !inlineEnabled {
|
|
||||||
// No need to check anything, we assume it is a persistent volume.
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
volumeLifecycleMode, err := p.getVolumeLifecycleMode(spec)
|
volumeLifecycleMode, err := p.getVolumeLifecycleMode(spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -841,14 +825,6 @@ func (p *csiPlugin) getCSIDriver(driver string) (*storage.CSIDriver, error) {
|
|||||||
// supportsVolumeMode checks whether the CSI driver supports a volume in the given mode.
|
// supportsVolumeMode checks whether the CSI driver supports a volume in the given mode.
|
||||||
// An error indicates that it isn't supported and explains why.
|
// An error indicates that it isn't supported and explains why.
|
||||||
func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storage.VolumeLifecycleMode) error {
|
func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storage.VolumeLifecycleMode) error {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
// Feature disabled, therefore only "persistent" volumes are supported.
|
|
||||||
if volumeMode != storage.VolumeLifecyclePersistent {
|
|
||||||
return fmt.Errorf("CSIInlineVolume feature not enabled, %q volumes not supported", volumeMode)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve CSIDriver. It's not an error if that isn't
|
// Retrieve CSIDriver. It's not an error if that isn't
|
||||||
// possible (we don't have the lister if CSIDriverRegistry is
|
// possible (we don't have the lister if CSIDriverRegistry is
|
||||||
// disabled) or the driver isn't found (CSIDriver is
|
// disabled) or the driver isn't found (CSIDriver is
|
||||||
@ -901,7 +877,7 @@ func (p *csiPlugin) getVolumeLifecycleMode(spec *volume.Spec) (storage.VolumeLif
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if volSrc != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if volSrc != nil {
|
||||||
return storage.VolumeLifecycleEphemeral, nil
|
return storage.VolumeLifecycleEphemeral, nil
|
||||||
}
|
}
|
||||||
return storage.VolumeLifecyclePersistent, nil
|
return storage.VolumeLifecyclePersistent, nil
|
||||||
|
@ -29,12 +29,9 @@ import (
|
|||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||||
)
|
)
|
||||||
@ -278,8 +275,6 @@ func TestPluginGetVolumeName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginGetVolumeNameWithInline(t *testing.T) {
|
func TestPluginGetVolumeNameWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
modes := []storage.VolumeLifecycleMode{
|
modes := []storage.VolumeLifecycleMode{
|
||||||
storage.VolumeLifecyclePersistent,
|
storage.VolumeLifecyclePersistent,
|
||||||
}
|
}
|
||||||
@ -331,47 +326,6 @@ func TestPluginGetVolumeNameWithInline(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginCanSupport(t *testing.T) {
|
func TestPluginCanSupport(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, false)()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
spec *volume.Spec
|
|
||||||
canSupport bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "no spec provided",
|
|
||||||
canSupport: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "can support volume source",
|
|
||||||
spec: volume.NewSpecFromVolume(makeTestVol("test-vol", testDriver)),
|
|
||||||
canSupport: false, // csi inline not enabled
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "can support persistent volume source",
|
|
||||||
spec: volume.NewSpecFromPersistentVolume(makeTestPV("test-pv", 20, testDriver, testVol), true),
|
|
||||||
canSupport: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
plug, tmpDir := newTestPlugin(t, nil)
|
|
||||||
defer os.RemoveAll(tmpDir)
|
|
||||||
registerFakePlugin(testDriver, "endpoint", []string{"1.0.0"}, t)
|
|
||||||
|
|
||||||
for _, tc := range tests {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
|
|
||||||
actual := plug.CanSupport(tc.spec)
|
|
||||||
if tc.canSupport != actual {
|
|
||||||
t.Errorf("expecting canSupport %t, got %t", tc.canSupport, actual)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginCanSupportWithInline(t *testing.T) {
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
spec *volume.Spec
|
spec *volume.Spec
|
||||||
@ -504,8 +458,6 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginConstructVolumeSpecWithInline(t *testing.T) {
|
func TestPluginConstructVolumeSpecWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
originSpec *volume.Spec
|
originSpec *volume.Spec
|
||||||
@ -755,7 +707,6 @@ func TestPluginNewMounter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginNewMounterWithInline(t *testing.T) {
|
func TestPluginNewMounterWithInline(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
bothModes := []storage.VolumeLifecycleMode{
|
bothModes := []storage.VolumeLifecycleMode{
|
||||||
storage.VolumeLifecycleEphemeral,
|
storage.VolumeLifecycleEphemeral,
|
||||||
storage.VolumeLifecyclePersistent,
|
storage.VolumeLifecyclePersistent,
|
||||||
@ -993,7 +944,6 @@ func TestPluginNewDetacher(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginCanAttach(t *testing.T) {
|
func TestPluginCanAttach(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
driverName string
|
driverName string
|
||||||
@ -1047,7 +997,6 @@ func TestPluginCanAttach(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginFindAttachablePlugin(t *testing.T) {
|
func TestPluginFindAttachablePlugin(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
driverName string
|
driverName string
|
||||||
@ -1123,7 +1072,6 @@ func TestPluginFindAttachablePlugin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginCanDeviceMount(t *testing.T) {
|
func TestPluginCanDeviceMount(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
driverName string
|
driverName string
|
||||||
@ -1175,7 +1123,6 @@ func TestPluginCanDeviceMount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginFindDeviceMountablePluginBySpec(t *testing.T) {
|
func TestPluginFindDeviceMountablePluginBySpec(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
driverName string
|
driverName string
|
||||||
|
@ -30,12 +30,9 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||||
)
|
)
|
||||||
@ -43,21 +40,19 @@ import (
|
|||||||
// TestCSI_VolumeAll runs a close approximation of volume workflow
|
// TestCSI_VolumeAll runs a close approximation of volume workflow
|
||||||
// based on operations from the volume manager/reconciler/operation executor
|
// based on operations from the volume manager/reconciler/operation executor
|
||||||
func TestCSI_VolumeAll(t *testing.T) {
|
func TestCSI_VolumeAll(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
|
|
||||||
defaultFSGroupPolicy := storage.ReadWriteOnceWithFSTypeFSGroupPolicy
|
defaultFSGroupPolicy := storage.ReadWriteOnceWithFSTypeFSGroupPolicy
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
specName string
|
specName string
|
||||||
driver string
|
driver string
|
||||||
volName string
|
volName string
|
||||||
specFunc func(specName, driver, volName string) *volume.Spec
|
specFunc func(specName, driver, volName string) *volume.Spec
|
||||||
podFunc func() *api.Pod
|
podFunc func() *api.Pod
|
||||||
isInline bool
|
isInline bool
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
disableFSGroupPolicyFeatureGate bool
|
driverSpec *storage.CSIDriverSpec
|
||||||
driverSpec *storage.CSIDriverSpec
|
watchTimeout time.Duration
|
||||||
watchTimeout time.Duration
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "PersistentVolume",
|
name: "PersistentVolume",
|
||||||
@ -90,25 +85,6 @@ func TestCSI_VolumeAll(t *testing.T) {
|
|||||||
FSGroupPolicy: &defaultFSGroupPolicy,
|
FSGroupPolicy: &defaultFSGroupPolicy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "PersistentVolume with driver info and FSGroup disabled",
|
|
||||||
specName: "pv2",
|
|
||||||
driver: "simple-driver",
|
|
||||||
volName: "vol2",
|
|
||||||
specFunc: func(specName, driver, volName string) *volume.Spec {
|
|
||||||
return volume.NewSpecFromPersistentVolume(makeTestPV(specName, 20, driver, volName), false)
|
|
||||||
},
|
|
||||||
podFunc: func() *api.Pod {
|
|
||||||
podUID := types.UID(fmt.Sprintf("%08X", rand.Uint64()))
|
|
||||||
return &api.Pod{ObjectMeta: meta.ObjectMeta{UID: podUID, Namespace: testns}}
|
|
||||||
},
|
|
||||||
disableFSGroupPolicyFeatureGate: true,
|
|
||||||
driverSpec: &storage.CSIDriverSpec{
|
|
||||||
// Required for the driver to be accepted for the persistent volume.
|
|
||||||
VolumeLifecycleModes: []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent},
|
|
||||||
FSGroupPolicy: &defaultFSGroupPolicy,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "PersistentVolume with wrong mode in driver info",
|
name: "PersistentVolume with wrong mode in driver info",
|
||||||
specName: "pv2",
|
specName: "pv2",
|
||||||
@ -244,8 +220,6 @@ func TestCSI_VolumeAll(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, !test.disableFSGroupPolicyFeatureGate)()
|
|
||||||
|
|
||||||
tmpDir, err := utiltesting.MkTmpdir("csi-test")
|
tmpDir, err := utiltesting.MkTmpdir("csi-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't create temp dir: %v", err)
|
t.Fatalf("can't create temp dir: %v", err)
|
||||||
|
@ -29,10 +29,8 @@ import (
|
|||||||
api "k8s.io/api/core/v1"
|
api "k8s.io/api/core/v1"
|
||||||
storage "k8s.io/api/storage/v1"
|
storage "k8s.io/api/storage/v1"
|
||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
utilstrings "k8s.io/utils/strings"
|
utilstrings "k8s.io/utils/strings"
|
||||||
)
|
)
|
||||||
@ -151,7 +149,7 @@ func getSourceFromSpec(spec *volume.Spec) (*api.CSIVolumeSource, *api.CSIPersist
|
|||||||
if spec.Volume != nil && spec.PersistentVolume != nil {
|
if spec.Volume != nil && spec.PersistentVolume != nil {
|
||||||
return nil, nil, fmt.Errorf("volume.Spec has both volume and persistent volume sources")
|
return nil, nil, fmt.Errorf("volume.Spec has both volume and persistent volume sources")
|
||||||
}
|
}
|
||||||
if spec.Volume != nil && spec.Volume.CSI != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if spec.Volume != nil && spec.Volume.CSI != nil {
|
||||||
return spec.Volume.CSI, nil, nil
|
return spec.Volume.CSI, nil, nil
|
||||||
}
|
}
|
||||||
if spec.PersistentVolume != nil &&
|
if spec.PersistentVolume != nil &&
|
||||||
@ -187,7 +185,7 @@ func GetCSIDriverName(spec *volume.Spec) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case volSrc != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume):
|
case volSrc != nil:
|
||||||
return volSrc.Driver, nil
|
return volSrc.Driver, nil
|
||||||
case pvSrc != nil:
|
case pvSrc != nil:
|
||||||
return pvSrc.Driver, nil
|
return pvSrc.Driver, nil
|
||||||
@ -212,9 +210,7 @@ func getPodInfoAttrs(pod *api.Pod, volumeMode storage.VolumeLifecycleMode) map[s
|
|||||||
"csi.storage.k8s.io/pod.namespace": pod.Namespace,
|
"csi.storage.k8s.io/pod.namespace": pod.Namespace,
|
||||||
"csi.storage.k8s.io/pod.uid": string(pod.UID),
|
"csi.storage.k8s.io/pod.uid": string(pod.UID),
|
||||||
"csi.storage.k8s.io/serviceAccount.name": pod.Spec.ServiceAccountName,
|
"csi.storage.k8s.io/serviceAccount.name": pod.Spec.ServiceAccountName,
|
||||||
}
|
"csi.storage.k8s.io/ephemeral": strconv.FormatBool(volumeMode == storage.VolumeLifecycleEphemeral),
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
|
||||||
attrs["csi.storage.k8s.io/ephemeral"] = strconv.FormatBool(volumeMode == storage.VolumeLifecycleEphemeral)
|
|
||||||
}
|
}
|
||||||
return attrs
|
return attrs
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,8 @@ import (
|
|||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/component-base/metrics"
|
"k8s.io/component-base/metrics"
|
||||||
"k8s.io/component-base/metrics/legacyregistry"
|
"k8s.io/component-base/metrics/legacyregistry"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||||
)
|
)
|
||||||
@ -120,7 +118,7 @@ func FSGroupCompleteHook(plugin volume.VolumePlugin, spec *volume.Spec) func(typ
|
|||||||
// CSI plugin drivers.
|
// CSI plugin drivers.
|
||||||
func GetFullQualifiedPluginNameForVolume(pluginName string, spec *volume.Spec) string {
|
func GetFullQualifiedPluginNameForVolume(pluginName string, spec *volume.Spec) string {
|
||||||
if spec != nil {
|
if spec != nil {
|
||||||
if spec.Volume != nil && spec.Volume.CSI != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if spec.Volume != nil && spec.Volume.CSI != nil {
|
||||||
return fmt.Sprintf("%s:%s", pluginName, spec.Volume.CSI.Driver)
|
return fmt.Sprintf("%s:%s", pluginName, spec.Volume.CSI.Driver)
|
||||||
}
|
}
|
||||||
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil {
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil {
|
||||||
|
@ -329,7 +329,6 @@ message PodSecurityPolicySpec {
|
|||||||
|
|
||||||
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
||||||
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
||||||
// This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.
|
|
||||||
// +optional
|
// +optional
|
||||||
repeated AllowedCSIDriver allowedCSIDrivers = 23;
|
repeated AllowedCSIDriver allowedCSIDrivers = 23;
|
||||||
|
|
||||||
|
@ -278,7 +278,6 @@ type PodSecurityPolicySpec struct {
|
|||||||
AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"`
|
AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"`
|
||||||
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
// AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
|
||||||
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
// An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
|
||||||
// This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.
|
|
||||||
// +optional
|
// +optional
|
||||||
AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"`
|
AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"`
|
||||||
// allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.
|
// allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.
|
||||||
|
@ -183,7 +183,7 @@ var map_PodSecurityPolicySpec = map[string]string{
|
|||||||
"allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.",
|
"allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.",
|
||||||
"allowedHostPaths": "allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.",
|
"allowedHostPaths": "allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.",
|
||||||
"allowedFlexVolumes": "allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.",
|
"allowedFlexVolumes": "allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.",
|
||||||
"allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes. This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.",
|
"allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.",
|
||||||
"allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.",
|
"allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.",
|
||||||
"forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.",
|
"forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.",
|
||||||
"allowedProcMountTypes": "AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.",
|
"allowedProcMountTypes": "AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.",
|
||||||
|
Loading…
Reference in New Issue
Block a user