mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
Graduate ReadWriteOncePod to GA
This commit is contained in:
parent
f7cb8a5e8a
commit
2dbd405583
@ -1653,33 +1653,20 @@ var allowedTemplateObjectMetaFields = map[string]bool{
|
||||
|
||||
// PersistentVolumeSpecValidationOptions contains the different settings for PeristentVolume validation
|
||||
type PersistentVolumeSpecValidationOptions struct {
|
||||
// Allow spec to contain the "ReadWiteOncePod" access mode
|
||||
AllowReadWriteOncePod bool
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeName checks that a name is appropriate for a
|
||||
// PersistentVolumeName object.
|
||||
var ValidatePersistentVolumeName = apimachineryvalidation.NameIsDNSSubdomain
|
||||
|
||||
var supportedAccessModes = sets.NewString(string(core.ReadWriteOnce), string(core.ReadOnlyMany), string(core.ReadWriteMany))
|
||||
var supportedAccessModes = sets.NewString(string(core.ReadWriteOnce), string(core.ReadOnlyMany), string(core.ReadWriteMany), string(core.ReadWriteOncePod))
|
||||
|
||||
var supportedReclaimPolicy = sets.NewString(string(core.PersistentVolumeReclaimDelete), string(core.PersistentVolumeReclaimRecycle), string(core.PersistentVolumeReclaimRetain))
|
||||
|
||||
var supportedVolumeModes = sets.NewString(string(core.PersistentVolumeBlock), string(core.PersistentVolumeFilesystem))
|
||||
|
||||
func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) PersistentVolumeSpecValidationOptions {
|
||||
opts := PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
}
|
||||
if oldPv == nil {
|
||||
// If there's no old PV, use the options based solely on feature enablement
|
||||
return opts
|
||||
}
|
||||
if helper.ContainsAccessMode(oldPv.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
return opts
|
||||
return PersistentVolumeSpecValidationOptions{}
|
||||
}
|
||||
|
||||
func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName string, validateInlinePersistentVolumeSpec bool, fldPath *field.Path, opts PersistentVolumeSpecValidationOptions) field.ErrorList {
|
||||
@ -1701,15 +1688,10 @@ func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName stri
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), ""))
|
||||
}
|
||||
|
||||
expandedSupportedAccessModes := sets.StringKeySet(supportedAccessModes)
|
||||
if opts.AllowReadWriteOncePod {
|
||||
expandedSupportedAccessModes.Insert(string(core.ReadWriteOncePod))
|
||||
}
|
||||
|
||||
foundReadWriteOncePod, foundNonReadWriteOncePod := false, false
|
||||
for _, mode := range pvSpec.AccessModes {
|
||||
if !expandedSupportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, expandedSupportedAccessModes.List()))
|
||||
if !supportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, supportedAccessModes.List()))
|
||||
}
|
||||
|
||||
if mode == core.ReadWriteOncePod {
|
||||
@ -2016,8 +1998,6 @@ func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *core.PersistentVolume) f
|
||||
}
|
||||
|
||||
type PersistentVolumeClaimSpecValidationOptions struct {
|
||||
// Allow spec to contain the "ReadWiteOncePod" access mode
|
||||
AllowReadWriteOncePod bool
|
||||
// Allow users to recover from previously failing expansion operation
|
||||
EnableRecoverFromExpansionFailure bool
|
||||
// Allow to validate the label value of the label selector
|
||||
@ -2028,7 +2008,6 @@ type PersistentVolumeClaimSpecValidationOptions struct {
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
|
||||
AllowInvalidLabelValueInSelector: false,
|
||||
}
|
||||
@ -2048,11 +2027,6 @@ func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolum
|
||||
opts.AllowInvalidLabelValueInSelector = true
|
||||
}
|
||||
|
||||
if helper.ContainsAccessMode(oldPvc.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
|
||||
if helper.ClaimContainsAllocatedResources(oldPvc) ||
|
||||
helper.ClaimContainsAllocatedResourceStatus(oldPvc) {
|
||||
opts.EnableRecoverFromExpansionFailure = true
|
||||
@ -2062,7 +2036,6 @@ func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolum
|
||||
|
||||
func ValidationOptionsForPersistentVolumeClaimTemplate(claimTemplate, oldClaimTemplate *core.PersistentVolumeClaimTemplate) PersistentVolumeClaimSpecValidationOptions {
|
||||
opts := PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
AllowInvalidLabelValueInSelector: false,
|
||||
}
|
||||
if oldClaimTemplate == nil {
|
||||
@ -2076,10 +2049,6 @@ func ValidationOptionsForPersistentVolumeClaimTemplate(claimTemplate, oldClaimTe
|
||||
// If the old object had an invalid label selector, continue to allow it in the new object
|
||||
opts.AllowInvalidLabelValueInSelector = true
|
||||
}
|
||||
if helper.ContainsAccessMode(oldClaimTemplate.Spec.AccessModes, core.ReadWriteOncePod) {
|
||||
// If the old object allowed "ReadWriteOncePod", continue to allow it in the new object
|
||||
opts.AllowReadWriteOncePod = true
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
@ -2172,15 +2141,10 @@ func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fld
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, labelSelectorValidationOpts, fldPath.Child("selector"))...)
|
||||
}
|
||||
|
||||
expandedSupportedAccessModes := sets.StringKeySet(supportedAccessModes)
|
||||
if opts.AllowReadWriteOncePod {
|
||||
expandedSupportedAccessModes.Insert(string(core.ReadWriteOncePod))
|
||||
}
|
||||
|
||||
foundReadWriteOncePod, foundNonReadWriteOncePod := false, false
|
||||
for _, mode := range spec.AccessModes {
|
||||
if !expandedSupportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, expandedSupportedAccessModes.List()))
|
||||
if !supportedAccessModes.Has(string(mode)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("accessModes"), mode, supportedAccessModes.List()))
|
||||
}
|
||||
|
||||
if mode == core.ReadWriteOncePod {
|
||||
|
@ -109,9 +109,8 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||
validMode := core.PersistentVolumeFilesystem
|
||||
invalidMode := core.PersistentVolumeMode("fakeVolumeMode")
|
||||
scenarios := map[string]struct {
|
||||
isExpectedFailure bool
|
||||
enableReadWriteOncePod bool
|
||||
volume *core.PersistentVolume
|
||||
isExpectedFailure bool
|
||||
volume *core.PersistentVolume
|
||||
}{
|
||||
"good-volume": {
|
||||
isExpectedFailure: false,
|
||||
@ -253,9 +252,8 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||
VolumeMode: &invalidMode,
|
||||
}),
|
||||
},
|
||||
"with-read-write-once-pod-feature-gate-enabled": {
|
||||
isExpectedFailure: false,
|
||||
enableReadWriteOncePod: true,
|
||||
"with-read-write-once-pod": {
|
||||
isExpectedFailure: false,
|
||||
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||
Capacity: core.ResourceList{
|
||||
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||
@ -269,25 +267,8 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||
},
|
||||
}),
|
||||
},
|
||||
"with-read-write-once-pod-feature-gate-disabled": {
|
||||
isExpectedFailure: true,
|
||||
enableReadWriteOncePod: false,
|
||||
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||
Capacity: core.ResourceList{
|
||||
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||
},
|
||||
AccessModes: []core.PersistentVolumeAccessMode{"ReadWriteOncePod"},
|
||||
PersistentVolumeSource: core.PersistentVolumeSource{
|
||||
HostPath: &core.HostPathVolumeSource{
|
||||
Path: "/foo",
|
||||
Type: newHostPathType(string(core.HostPathDirectory)),
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
"with-read-write-once-pod-and-others-feature-gate-enabled": {
|
||||
isExpectedFailure: true,
|
||||
enableReadWriteOncePod: true,
|
||||
"with-read-write-once-pod-and-others": {
|
||||
isExpectedFailure: true,
|
||||
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||
Capacity: core.ResourceList{
|
||||
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||
@ -501,8 +482,6 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, scenario.enableReadWriteOncePod)()
|
||||
|
||||
opts := ValidationOptionsForPersistentVolume(scenario.volume, nil)
|
||||
errs := ValidatePersistentVolume(scenario.volume, opts)
|
||||
if len(errs) == 0 && scenario.isExpectedFailure {
|
||||
@ -903,51 +882,17 @@ func TestValidatePersistentVolumeSourceUpdate(t *testing.T) {
|
||||
|
||||
func TestValidationOptionsForPersistentVolume(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
oldPv *core.PersistentVolume
|
||||
enableReadWriteOncePod bool
|
||||
expectValidationOpts PersistentVolumeSpecValidationOptions
|
||||
oldPv *core.PersistentVolume
|
||||
expectValidationOpts PersistentVolumeSpecValidationOptions
|
||||
}{
|
||||
"nil old pv": {
|
||||
oldPv: nil,
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop allowed because feature enabled": {
|
||||
oldPv: pvWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop not allowed because not used and feature disabled": {
|
||||
oldPv: pvWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: false,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature enabled": {
|
||||
oldPv: pvWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature disabled": {
|
||||
oldPv: pvWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
oldPv: nil,
|
||||
expectValidationOpts: PersistentVolumeSpecValidationOptions{},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tc.enableReadWriteOncePod)()
|
||||
|
||||
opts := ValidationOptionsForPersistentVolume(nil, tc.oldPv)
|
||||
if opts != tc.expectValidationOpts {
|
||||
t.Errorf("Expected opts: %+v, received: %+v", opts, tc.expectValidationOpts)
|
||||
@ -973,29 +918,6 @@ func getCSIVolumeWithSecret(pv *core.PersistentVolume, secret *core.SecretRefere
|
||||
|
||||
return pvCopy
|
||||
}
|
||||
func pvWithAccessModes(accessModes []core.PersistentVolumeAccessMode) *core.PersistentVolume {
|
||||
return &core.PersistentVolume{
|
||||
Spec: core.PersistentVolumeSpec{
|
||||
AccessModes: accessModes,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func pvcWithAccessModes(accessModes []core.PersistentVolumeAccessMode) *core.PersistentVolumeClaim {
|
||||
return &core.PersistentVolumeClaim{
|
||||
Spec: core.PersistentVolumeClaimSpec{
|
||||
AccessModes: accessModes,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func pvcTemplateWithAccessModes(accessModes []core.PersistentVolumeAccessMode) *core.PersistentVolumeClaimTemplate {
|
||||
return &core.PersistentVolumeClaimTemplate{
|
||||
Spec: core.PersistentVolumeClaimSpec{
|
||||
AccessModes: accessModes,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func pvcWithDataSource(dataSource *core.TypedLocalObjectReference) *core.PersistentVolumeClaim {
|
||||
return &core.PersistentVolumeClaim{
|
||||
@ -1594,9 +1516,8 @@ func testValidatePVC(t *testing.T, ephemeral bool) {
|
||||
ten := int64(10)
|
||||
|
||||
scenarios := map[string]struct {
|
||||
isExpectedFailure bool
|
||||
enableReadWriteOncePod bool
|
||||
claim *core.PersistentVolumeClaim
|
||||
isExpectedFailure bool
|
||||
claim *core.PersistentVolumeClaim
|
||||
}{
|
||||
"good-claim": {
|
||||
isExpectedFailure: false,
|
||||
@ -1734,9 +1655,8 @@ func testValidatePVC(t *testing.T, ephemeral bool) {
|
||||
return claim
|
||||
}(),
|
||||
},
|
||||
"with-read-write-once-pod-feature-gate-enabled": {
|
||||
isExpectedFailure: false,
|
||||
enableReadWriteOncePod: true,
|
||||
"with-read-write-once-pod": {
|
||||
isExpectedFailure: false,
|
||||
claim: testVolumeClaim(goodName, goodNS, core.PersistentVolumeClaimSpec{
|
||||
AccessModes: []core.PersistentVolumeAccessMode{"ReadWriteOncePod"},
|
||||
Resources: core.VolumeResourceRequirements{
|
||||
@ -1746,21 +1666,8 @@ func testValidatePVC(t *testing.T, ephemeral bool) {
|
||||
},
|
||||
}),
|
||||
},
|
||||
"with-read-write-once-pod-feature-gate-disabled": {
|
||||
isExpectedFailure: true,
|
||||
enableReadWriteOncePod: false,
|
||||
claim: testVolumeClaim(goodName, goodNS, core.PersistentVolumeClaimSpec{
|
||||
AccessModes: []core.PersistentVolumeAccessMode{"ReadWriteOncePod"},
|
||||
Resources: core.VolumeResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
"with-read-write-once-pod-and-others-feature-gate-enabled": {
|
||||
isExpectedFailure: true,
|
||||
enableReadWriteOncePod: true,
|
||||
"with-read-write-once-pod-and-others": {
|
||||
isExpectedFailure: true,
|
||||
claim: testVolumeClaim(goodName, goodNS, core.PersistentVolumeClaimSpec{
|
||||
AccessModes: []core.PersistentVolumeAccessMode{"ReadWriteOncePod", "ReadWriteMany"},
|
||||
Resources: core.VolumeResourceRequirements{
|
||||
@ -1991,8 +1898,6 @@ func testValidatePVC(t *testing.T, ephemeral bool) {
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, scenario.enableReadWriteOncePod)()
|
||||
|
||||
var errs field.ErrorList
|
||||
if ephemeral {
|
||||
volumes := []core.Volume{{
|
||||
@ -2754,47 +2659,12 @@ func TestValidationOptionsForPersistentVolumeClaim(t *testing.T) {
|
||||
invaildAPIGroup := "^invalid"
|
||||
|
||||
tests := map[string]struct {
|
||||
oldPvc *core.PersistentVolumeClaim
|
||||
enableReadWriteOncePod bool
|
||||
expectValidationOpts PersistentVolumeClaimSpecValidationOptions
|
||||
oldPvc *core.PersistentVolumeClaim
|
||||
expectValidationOpts PersistentVolumeClaimSpecValidationOptions
|
||||
}{
|
||||
"nil pv": {
|
||||
oldPvc: nil,
|
||||
enableReadWriteOncePod: true,
|
||||
oldPvc: nil,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
EnableRecoverFromExpansionFailure: false,
|
||||
},
|
||||
},
|
||||
"rwop allowed because feature enabled": {
|
||||
oldPvc: pvcWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
EnableRecoverFromExpansionFailure: false,
|
||||
},
|
||||
},
|
||||
"rwop not allowed because not used and feature disabled": {
|
||||
oldPvc: pvcWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: false,
|
||||
EnableRecoverFromExpansionFailure: false,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature enabled": {
|
||||
oldPvc: pvcWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
EnableRecoverFromExpansionFailure: false,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature disabled": {
|
||||
oldPvc: pvcWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
EnableRecoverFromExpansionFailure: false,
|
||||
},
|
||||
},
|
||||
@ -2814,8 +2684,6 @@ func TestValidationOptionsForPersistentVolumeClaim(t *testing.T) {
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tc.enableReadWriteOncePod)()
|
||||
|
||||
opts := ValidationOptionsForPersistentVolumeClaim(nil, tc.oldPvc)
|
||||
if opts != tc.expectValidationOpts {
|
||||
t.Errorf("Expected opts: %+v, received: %+v", tc.expectValidationOpts, opts)
|
||||
@ -2826,51 +2694,17 @@ func TestValidationOptionsForPersistentVolumeClaim(t *testing.T) {
|
||||
|
||||
func TestValidationOptionsForPersistentVolumeClaimTemplate(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
oldPvcTemplate *core.PersistentVolumeClaimTemplate
|
||||
enableReadWriteOncePod bool
|
||||
expectValidationOpts PersistentVolumeClaimSpecValidationOptions
|
||||
oldPvcTemplate *core.PersistentVolumeClaimTemplate
|
||||
expectValidationOpts PersistentVolumeClaimSpecValidationOptions
|
||||
}{
|
||||
"nil pv": {
|
||||
oldPvcTemplate: nil,
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop allowed because feature enabled": {
|
||||
oldPvcTemplate: pvcTemplateWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop not allowed because not used and feature disabled": {
|
||||
oldPvcTemplate: pvcTemplateWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOnce}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: false,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature enabled": {
|
||||
oldPvcTemplate: pvcTemplateWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: true,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
},
|
||||
"rwop allowed because used and feature disabled": {
|
||||
oldPvcTemplate: pvcTemplateWithAccessModes([]core.PersistentVolumeAccessMode{core.ReadWriteOncePod}),
|
||||
enableReadWriteOncePod: false,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{
|
||||
AllowReadWriteOncePod: true,
|
||||
},
|
||||
oldPvcTemplate: nil,
|
||||
expectValidationOpts: PersistentVolumeClaimSpecValidationOptions{},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tc.enableReadWriteOncePod)()
|
||||
|
||||
opts := ValidationOptionsForPersistentVolumeClaimTemplate(nil, tc.oldPvcTemplate)
|
||||
if opts != tc.expectValidationOpts {
|
||||
t.Errorf("Expected opts: %+v, received: %+v", opts, tc.expectValidationOpts)
|
||||
|
@ -670,6 +670,7 @@ const (
|
||||
// kep: https://kep.k8s.io/2485
|
||||
// alpha: v1.22
|
||||
// beta: v1.27
|
||||
// GA: v1.29
|
||||
//
|
||||
// Enables usage of the ReadWriteOncePod PersistentVolume access mode.
|
||||
ReadWriteOncePod featuregate.Feature = "ReadWriteOncePod"
|
||||
@ -1046,7 +1047,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
QOSReserved: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
ReadWriteOncePod: {Default: true, PreRelease: featuregate.Beta},
|
||||
ReadWriteOncePod: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
RecoverVolumeExpansionFailure: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
|
@ -877,7 +877,6 @@ func Test_MarkDeviceAsMounted_Positive_NewVolume(t *testing.T) {
|
||||
// Verifies volume/pod combo exist using PodExistsInVolume()
|
||||
func Test_AddPodToVolume_Positive_SELinux(t *testing.T) {
|
||||
// Arrange
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
volumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t)
|
||||
asw := NewActualStateOfWorld("mynode" /* nodeName */, volumePluginMgr)
|
||||
@ -956,7 +955,6 @@ func Test_AddPodToVolume_Positive_SELinux(t *testing.T) {
|
||||
// Verifies newly added volume exists in GetGloballyMountedVolumes()
|
||||
func Test_MarkDeviceAsMounted_Positive_SELinux(t *testing.T) {
|
||||
// Arrange
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
volumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t)
|
||||
asw := NewActualStateOfWorld("mynode" /* nodeName */, volumePluginMgr)
|
||||
|
@ -609,7 +609,6 @@ func Test_AddPodToVolume_WithEmptyDirSizeLimit(t *testing.T) {
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Positive_SELinuxNoRWOP(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
@ -690,7 +689,6 @@ func Test_AddPodToVolume_Positive_SELinuxNoRWOP(t *testing.T) {
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Positive_NoSELinuxPlugin(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
@ -772,7 +770,6 @@ func Test_AddPodToVolume_Positive_NoSELinuxPlugin(t *testing.T) {
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume()
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Positive_ExistingPodSameSELinuxRWOP(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
@ -873,7 +870,6 @@ func Test_AddPodToVolume_Positive_ExistingPodSameSELinuxRWOP(t *testing.T) {
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume()
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Negative_ExistingPodDifferentSELinuxRWOP(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
|
@ -1189,7 +1189,6 @@ func TestCheckVolumeFSResize(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckVolumeSELinux(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
fullOpts := &v1.SELinuxOptions{
|
||||
User: "system_u",
|
||||
|
@ -21,7 +21,6 @@ package feature
|
||||
// the internal k8s features pkg.
|
||||
type Features struct {
|
||||
EnableDynamicResourceAllocation bool
|
||||
EnableReadWriteOncePod bool
|
||||
EnableVolumeCapacityPriority bool
|
||||
EnableMinDomainsInPodTopologySpread bool
|
||||
EnableNodeInclusionPolicyInPodTopologySpread bool
|
||||
|
@ -47,7 +47,6 @@ import (
|
||||
func NewInTreeRegistry() runtime.Registry {
|
||||
fts := plfeature.Features{
|
||||
EnableDynamicResourceAllocation: feature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation),
|
||||
EnableReadWriteOncePod: feature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
|
||||
EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),
|
||||
EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),
|
||||
EnableNodeInclusionPolicyInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread),
|
||||
|
@ -33,9 +33,8 @@ import (
|
||||
|
||||
// VolumeRestrictions is a plugin that checks volume restrictions.
|
||||
type VolumeRestrictions struct {
|
||||
pvcLister corelisters.PersistentVolumeClaimLister
|
||||
sharedLister framework.SharedLister
|
||||
enableReadWriteOncePod bool
|
||||
pvcLister corelisters.PersistentVolumeClaimLister
|
||||
sharedLister framework.SharedLister
|
||||
}
|
||||
|
||||
var _ framework.PreFilterPlugin = &VolumeRestrictions{}
|
||||
@ -169,13 +168,6 @@ func (pl *VolumeRestrictions) PreFilter(ctx context.Context, cycleState *framewo
|
||||
}
|
||||
}
|
||||
|
||||
if !pl.enableReadWriteOncePod {
|
||||
if needsCheck {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, framework.NewStatus(framework.Skip)
|
||||
}
|
||||
|
||||
pvcs, err := pl.readWriteOncePodPVCsForPod(ctx, pod)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
@ -198,9 +190,6 @@ func (pl *VolumeRestrictions) PreFilter(ctx context.Context, cycleState *framewo
|
||||
|
||||
// AddPod from pre-computed data in cycleState.
|
||||
func (pl *VolumeRestrictions) AddPod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status {
|
||||
if !pl.enableReadWriteOncePod {
|
||||
return nil
|
||||
}
|
||||
state, err := getPreFilterState(cycleState)
|
||||
if err != nil {
|
||||
return framework.AsStatus(err)
|
||||
@ -211,9 +200,6 @@ func (pl *VolumeRestrictions) AddPod(ctx context.Context, cycleState *framework.
|
||||
|
||||
// RemovePod from pre-computed data in cycleState.
|
||||
func (pl *VolumeRestrictions) RemovePod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status {
|
||||
if !pl.enableReadWriteOncePod {
|
||||
return nil
|
||||
}
|
||||
state, err := getPreFilterState(cycleState)
|
||||
if err != nil {
|
||||
return framework.AsStatus(err)
|
||||
@ -321,9 +307,6 @@ func (pl *VolumeRestrictions) Filter(ctx context.Context, cycleState *framework.
|
||||
if !satisfyVolumeConflicts(pod, nodeInfo) {
|
||||
return framework.NewStatus(framework.Unschedulable, ErrReasonDiskConflict)
|
||||
}
|
||||
if !pl.enableReadWriteOncePod {
|
||||
return nil
|
||||
}
|
||||
state, err := getPreFilterState(cycleState)
|
||||
if err != nil {
|
||||
return framework.AsStatus(err)
|
||||
@ -354,8 +337,7 @@ func New(_ context.Context, _ runtime.Object, handle framework.Handle, fts featu
|
||||
sharedLister := handle.SnapshotSharedLister()
|
||||
|
||||
return &VolumeRestrictions{
|
||||
pvcLister: pvcLister,
|
||||
sharedLister: sharedLister,
|
||||
enableReadWriteOncePod: fts.EnableReadWriteOncePod,
|
||||
pvcLister: pvcLister,
|
||||
sharedLister: sharedLister,
|
||||
}, nil
|
||||
}
|
||||
|
@ -24,9 +24,6 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||
@ -355,8 +352,6 @@ func TestISCSIDiskConflicts(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAccessModeConflicts(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
|
||||
// Required for querying lister for PVCs in the same namespace.
|
||||
podWithOnePVC := st.MakePod().Name("pod-with-one-pvc").Namespace(metav1.NamespaceDefault).PVC("claim-with-rwop-1").Node("node-1").Obj()
|
||||
podWithTwoPVCs := st.MakePod().Name("pod-with-two-pvcs").Namespace(metav1.NamespaceDefault).PVC("claim-with-rwop-1").PVC("claim-with-rwop-2").Node("node-1").Obj()
|
||||
@ -401,81 +396,64 @@ func TestAccessModeConflicts(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
nodeInfo *framework.NodeInfo
|
||||
existingPods []*v1.Pod
|
||||
existingNodes []*v1.Node
|
||||
existingPVCs []*v1.PersistentVolumeClaim
|
||||
enableReadWriteOncePod bool
|
||||
preFilterWantStatus *framework.Status
|
||||
wantStatus *framework.Status
|
||||
name string
|
||||
pod *v1.Pod
|
||||
nodeInfo *framework.NodeInfo
|
||||
existingPods []*v1.Pod
|
||||
existingNodes []*v1.Node
|
||||
existingPVCs []*v1.PersistentVolumeClaim
|
||||
preFilterWantStatus *framework.Status
|
||||
wantStatus *framework.Status
|
||||
}{
|
||||
{
|
||||
name: "nothing",
|
||||
pod: &v1.Pod{},
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
existingPods: []*v1.Pod{},
|
||||
existingNodes: []*v1.Node{},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{},
|
||||
enableReadWriteOncePod: true,
|
||||
preFilterWantStatus: framework.NewStatus(framework.Skip),
|
||||
wantStatus: nil,
|
||||
name: "nothing",
|
||||
pod: &v1.Pod{},
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
existingPods: []*v1.Pod{},
|
||||
existingNodes: []*v1.Node{},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{},
|
||||
preFilterWantStatus: framework.NewStatus(framework.Skip),
|
||||
wantStatus: nil,
|
||||
},
|
||||
{
|
||||
name: "nothing, ReadWriteOncePod disabled",
|
||||
pod: &v1.Pod{},
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
existingPods: []*v1.Pod{},
|
||||
existingNodes: []*v1.Node{},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{},
|
||||
enableReadWriteOncePod: false,
|
||||
preFilterWantStatus: framework.NewStatus(framework.Skip),
|
||||
wantStatus: nil,
|
||||
name: "failed to get PVC",
|
||||
pod: podWithOnePVC,
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
existingPods: []*v1.Pod{},
|
||||
existingNodes: []*v1.Node{},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{},
|
||||
preFilterWantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, "persistentvolumeclaim \"claim-with-rwop-1\" not found"),
|
||||
wantStatus: nil,
|
||||
},
|
||||
{
|
||||
name: "failed to get PVC",
|
||||
pod: podWithOnePVC,
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
existingPods: []*v1.Pod{},
|
||||
existingNodes: []*v1.Node{},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{},
|
||||
enableReadWriteOncePod: true,
|
||||
preFilterWantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, "persistentvolumeclaim \"claim-with-rwop-1\" not found"),
|
||||
wantStatus: nil,
|
||||
name: "no access mode conflict",
|
||||
pod: podWithOnePVC,
|
||||
nodeInfo: framework.NewNodeInfo(podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteManyPVC},
|
||||
preFilterWantStatus: framework.NewStatus(framework.Skip),
|
||||
wantStatus: nil,
|
||||
},
|
||||
{
|
||||
name: "no access mode conflict",
|
||||
pod: podWithOnePVC,
|
||||
nodeInfo: framework.NewNodeInfo(podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteManyPVC},
|
||||
enableReadWriteOncePod: true,
|
||||
preFilterWantStatus: framework.NewStatus(framework.Skip),
|
||||
wantStatus: nil,
|
||||
name: "access mode conflict, unschedulable",
|
||||
pod: podWithOneConflict,
|
||||
nodeInfo: framework.NewNodeInfo(podWithOnePVC, podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithOnePVC, podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteManyPVC},
|
||||
preFilterWantStatus: nil,
|
||||
wantStatus: framework.NewStatus(framework.Unschedulable, ErrReasonReadWriteOncePodConflict),
|
||||
},
|
||||
{
|
||||
name: "access mode conflict, unschedulable",
|
||||
pod: podWithOneConflict,
|
||||
nodeInfo: framework.NewNodeInfo(podWithOnePVC, podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithOnePVC, podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteManyPVC},
|
||||
enableReadWriteOncePod: true,
|
||||
preFilterWantStatus: nil,
|
||||
wantStatus: framework.NewStatus(framework.Unschedulable, ErrReasonReadWriteOncePodConflict),
|
||||
},
|
||||
{
|
||||
name: "two conflicts, unschedulable",
|
||||
pod: podWithTwoConflicts,
|
||||
nodeInfo: framework.NewNodeInfo(podWithTwoPVCs, podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithTwoPVCs, podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteOncePodPVC2, readWriteManyPVC},
|
||||
enableReadWriteOncePod: true,
|
||||
preFilterWantStatus: nil,
|
||||
wantStatus: framework.NewStatus(framework.Unschedulable, ErrReasonReadWriteOncePodConflict),
|
||||
name: "two conflicts, unschedulable",
|
||||
pod: podWithTwoConflicts,
|
||||
nodeInfo: framework.NewNodeInfo(podWithTwoPVCs, podWithReadWriteManyPVC),
|
||||
existingPods: []*v1.Pod{podWithTwoPVCs, podWithReadWriteManyPVC},
|
||||
existingNodes: []*v1.Node{node},
|
||||
existingPVCs: []*v1.PersistentVolumeClaim{readWriteOncePodPVC1, readWriteOncePodPVC2, readWriteManyPVC},
|
||||
preFilterWantStatus: nil,
|
||||
wantStatus: framework.NewStatus(framework.Unschedulable, ErrReasonReadWriteOncePodConflict),
|
||||
},
|
||||
}
|
||||
|
||||
@ -483,7 +461,7 @@ func TestAccessModeConflicts(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
p := newPluginWithListers(ctx, t, test.existingPods, test.existingNodes, test.existingPVCs, test.enableReadWriteOncePod)
|
||||
p := newPluginWithListers(ctx, t, test.existingPods, test.existingNodes, test.existingPVCs)
|
||||
cycleState := framework.NewCycleState()
|
||||
_, preFilterGotStatus := p.(framework.PreFilterPlugin).PreFilter(ctx, cycleState, test.pod)
|
||||
if diff := cmp.Diff(test.preFilterWantStatus, preFilterGotStatus); diff != "" {
|
||||
@ -501,14 +479,12 @@ func TestAccessModeConflicts(t *testing.T) {
|
||||
}
|
||||
|
||||
func newPlugin(ctx context.Context, t *testing.T) framework.Plugin {
|
||||
return newPluginWithListers(ctx, t, nil, nil, nil, true)
|
||||
return newPluginWithListers(ctx, t, nil, nil, nil)
|
||||
}
|
||||
|
||||
func newPluginWithListers(ctx context.Context, t *testing.T, pods []*v1.Pod, nodes []*v1.Node, pvcs []*v1.PersistentVolumeClaim, enableReadWriteOncePod bool) framework.Plugin {
|
||||
func newPluginWithListers(ctx context.Context, t *testing.T, pods []*v1.Pod, nodes []*v1.Node, pvcs []*v1.PersistentVolumeClaim) framework.Plugin {
|
||||
pluginFactory := func(ctx context.Context, plArgs runtime.Object, fh framework.Handle) (framework.Plugin, error) {
|
||||
return New(ctx, plArgs, fh, feature.Features{
|
||||
EnableReadWriteOncePod: enableReadWriteOncePod,
|
||||
})
|
||||
return New(ctx, plArgs, fh, feature.Features{})
|
||||
}
|
||||
snapshot := cache.NewSnapshot(pods, nodes)
|
||||
|
||||
|
@ -370,7 +370,6 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tc.seLinuxMountEnabled)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, tc.seLinuxMountEnabled)()
|
||||
|
||||
mounter, err := plug.NewMounter(
|
||||
|
@ -580,8 +580,7 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
|
||||
}
|
||||
|
||||
// Enforce ReadWriteOncePod access mode if it is the only one present. This is also enforced during scheduling.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod) &&
|
||||
actualStateOfWorld.IsVolumeMountedElsewhere(volumeToMount.VolumeName, volumeToMount.PodName) &&
|
||||
if actualStateOfWorld.IsVolumeMountedElsewhere(volumeToMount.VolumeName, volumeToMount.PodName) &&
|
||||
// Because we do not know what access mode the pod intends to use if there are multiple.
|
||||
len(volumeToMount.VolumeSpec.PersistentVolume.Spec.AccessModes) == 1 &&
|
||||
v1helper.ContainsAccessMode(volumeToMount.VolumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) {
|
||||
@ -1071,8 +1070,7 @@ func (og *operationGenerator) GenerateMapVolumeFunc(
|
||||
migrated := getMigratedStatusBySpec(volumeToMount.VolumeSpec)
|
||||
|
||||
// Enforce ReadWriteOncePod access mode. This is also enforced during scheduling.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod) &&
|
||||
actualStateOfWorld.IsVolumeMountedElsewhere(volumeToMount.VolumeName, volumeToMount.PodName) &&
|
||||
if actualStateOfWorld.IsVolumeMountedElsewhere(volumeToMount.VolumeName, volumeToMount.PodName) &&
|
||||
// Because we do not know what access mode the pod intends to use if there are multiple.
|
||||
len(volumeToMount.VolumeSpec.PersistentVolume.Spec.AccessModes) == 1 &&
|
||||
v1helper.ContainsAccessMode(volumeToMount.VolumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) {
|
||||
|
@ -168,10 +168,6 @@ func SupportsSELinuxContextMount(volumeSpec *volume.Spec, volumePluginMgr *volum
|
||||
|
||||
// VolumeSupportsSELinuxMount returns true if given volume access mode can support mount with SELinux mount options.
|
||||
func VolumeSupportsSELinuxMount(volumeSpec *volume.Spec) bool {
|
||||
// Right now, SELinux mount is supported only for ReadWriteOncePod volumes.
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod) {
|
||||
return false
|
||||
}
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
return false
|
||||
}
|
||||
|
@ -616,7 +616,6 @@ func TestMakeAbsolutePath(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPodVolumeNames(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -1554,11 +1554,10 @@ var (
|
||||
|
||||
func TestUnschedulablePodBecomesSchedulable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
init func(kubernetes.Interface, string) error
|
||||
pod *testutils.PausePodConfig
|
||||
update func(kubernetes.Interface, string) error
|
||||
enableReadWriteOncePod bool
|
||||
name string
|
||||
init func(kubernetes.Interface, string) error
|
||||
pod *testutils.PausePodConfig
|
||||
update func(kubernetes.Interface, string) error
|
||||
}{
|
||||
{
|
||||
name: "node gets added",
|
||||
@ -1765,13 +1764,10 @@ func TestUnschedulablePodBecomesSchedulable(t *testing.T) {
|
||||
update: func(cs kubernetes.Interface, ns string) error {
|
||||
return deletePod(cs, "pod-to-be-deleted", ns)
|
||||
},
|
||||
enableReadWriteOncePod: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tt.enableReadWriteOncePod)()
|
||||
|
||||
testCtx := initTest(t, "scheduler-informer")
|
||||
|
||||
if tt.init != nil {
|
||||
|
@ -1648,8 +1648,6 @@ func TestPreferNominatedNode(t *testing.T) {
|
||||
// TestReadWriteOncePodPreemption tests preemption scenarios for pods with
|
||||
// ReadWriteOncePod PVCs.
|
||||
func TestReadWriteOncePodPreemption(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||
|
||||
cfg := configtesting.V1ToInternalWithDefaults(t, configv1.KubeSchedulerConfiguration{
|
||||
Profiles: []configv1.KubeSchedulerProfile{{
|
||||
SchedulerName: pointer.StringPtr(v1.DefaultSchedulerName),
|
||||
|
Loading…
Reference in New Issue
Block a user