Skip to content

Commit

Permalink
Merge pull request #67432 from lichuqiang/topo_provision_beta
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue (batch tested with PRs 67745, 67432, 67569, 67825, 67943). If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md.

Move volume dynamic provisioning scheduling to beta

**What this PR does / why we need it**:

*  Combine feature gate VolumeScheduling and DynamicProvisioningScheduling into one
* Add allowedTopologies description in kubectl

**Special notes for your reviewer**:
Wait until related e2e and downside plugins are ready.

/hold

**Release note**:

```release-note
Move volume dynamic provisioning scheduling to beta (ACTION REQUIRED: The DynamicProvisioningScheduling alpha feature gate has been removed. The VolumeScheduling beta feature gate is still required for this feature)
```
  • Loading branch information
Kubernetes Submit Queue authored Aug 29, 2018
2 parents 720781e + eefd337 commit 37b2929
Show file tree
Hide file tree
Showing 30 changed files with 307 additions and 294 deletions.
8 changes: 4 additions & 4 deletions api/openapi-spec/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions api/swagger-spec/storage.k8s.io_v1.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions api/swagger-spec/storage.k8s.io_v1beta1.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/api-reference/storage.k8s.io/v1/definitions.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/api-reference/storage.k8s.io/v1beta1/definitions.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/apis/core/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3153,7 +3153,7 @@ func ValidateTopologySelectorTerm(term core.TopologySelectorTerm, fldPath *field
exprMap := make(map[string]sets.String)
exprPath := fldPath.Child("matchLabelExpressions")

if utilfeature.DefaultFeatureGate.Enabled(features.DynamicProvisioningScheduling) {
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
// Allow empty MatchLabelExpressions, in case this field becomes optional in the future.

for i, req := range term.MatchLabelExpressions {
Expand All @@ -3168,7 +3168,7 @@ func ValidateTopologySelectorTerm(term core.TopologySelectorTerm, fldPath *field
exprMap[req.Key] = valueSet
}
} else if len(term.MatchLabelExpressions) != 0 {
allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate DynamicProvisioningScheduling"))
allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate VolumeScheduling"))
}

return exprMap, allErrs
Expand Down
6 changes: 2 additions & 4 deletions pkg/apis/storage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,14 @@ type StorageClass struct {

// VolumeBindingMode indicates how PersistentVolumeClaims should be
// provisioned and bound. When unset, VolumeBindingImmediate is used.
// This field is alpha-level and is only honored by servers that enable
// the VolumeScheduling feature.
// This field is only honored by servers that enable the VolumeScheduling feature.
// +optional
VolumeBindingMode *VolumeBindingMode

// Restrict the node topologies where volumes can be dynamically provisioned.
// Each volume plugin defines its own supported topology specifications.
// An empty TopologySelectorTerm list means there is no topology restriction.
// This field is alpha-level and is only honored by servers that enable
// the DynamicProvisioningScheduling feature.
// This field is only honored by servers that enable the VolumeScheduling feature.
// +optional
AllowedTopologies []api.TopologySelectorTerm
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/apis/storage/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import (
func DropDisabledAlphaFields(class *storage.StorageClass) {
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
class.VolumeBindingMode = nil
}
if !utilfeature.DefaultFeatureGate.Enabled(features.DynamicProvisioningScheduling) {
class.AllowedTopologies = nil
}
}
12 changes: 6 additions & 6 deletions pkg/apis/storage/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func TestDropAlphaFields(t *testing.T) {
}

// Test that field gets dropped when feature gate is not set
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false,DynamicProvisioningScheduling=false"); err != nil {
t.Fatalf("Failed to set feature gate for VolumeScheduling or DynamicProvisioningScheduling: %v", err)
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false"); err != nil {
t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err)
}
class := &storage.StorageClass{
VolumeBindingMode: &bindingMode,
Expand All @@ -59,8 +59,8 @@ func TestDropAlphaFields(t *testing.T) {
VolumeBindingMode: &bindingMode,
AllowedTopologies: allowedTopologies,
}
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true,DynamicProvisioningScheduling=true"); err != nil {
t.Fatalf("Failed to set feature gate for VolumeScheduling or DynamicProvisioningScheduling: %v", err)
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true"); err != nil {
t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err)
}
DropDisabledAlphaFields(class)
if class.VolumeBindingMode != &bindingMode {
Expand All @@ -70,7 +70,7 @@ func TestDropAlphaFields(t *testing.T) {
t.Errorf("AllowedTopologies field got unexpectantly modified: %+v", class.AllowedTopologies)
}

if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false,DynamicProvisioningScheduling=false"); err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling or DynamicProvisioningScheduling: %v", err)
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false"); err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err)
}
}
4 changes: 2 additions & 2 deletions pkg/apis/storage/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ func validateAllowedTopologies(topologies []api.TopologySelectorTerm, fldPath *f
return allErrs
}

if !utilfeature.DefaultFeatureGate.Enabled(features.DynamicProvisioningScheduling) {
allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate DynamicProvisioningScheduling"))
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
allErrs = append(allErrs, field.Forbidden(fldPath, "field is disabled by feature-gate VolumeScheduling"))
}

rawTopologies := make([]map[string]sets.String, len(topologies))
Expand Down
42 changes: 18 additions & 24 deletions pkg/apis/storage/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,73 +827,67 @@ func TestValidateAllowedTopologies(t *testing.T) {

cases := map[string]bindingTest{
"no topology": {
class: makeClass(nil, nil),
class: makeClass(&waitingMode, nil),
shouldSucceed: true,
},
"valid topology": {
class: makeClass(nil, validTopology),
class: makeClass(&waitingMode, validTopology),
shouldSucceed: true,
},
"topology invalid key": {
class: makeClass(nil, topologyInvalidKey),
class: makeClass(&waitingMode, topologyInvalidKey),
shouldSucceed: false,
},
"topology lack of values": {
class: makeClass(nil, topologyLackOfValues),
class: makeClass(&waitingMode, topologyLackOfValues),
shouldSucceed: false,
},
"duplicate TopologySelectorRequirement values": {
class: makeClass(nil, topologyDupValues),
class: makeClass(&waitingMode, topologyDupValues),
shouldSucceed: false,
},
"multiple TopologySelectorRequirement values": {
class: makeClass(nil, topologyMultiValues),
class: makeClass(&waitingMode, topologyMultiValues),
shouldSucceed: true,
},
"empty MatchLabelExpressions": {
class: makeClass(nil, topologyEmptyMatchLabelExpressions),
class: makeClass(&waitingMode, topologyEmptyMatchLabelExpressions),
shouldSucceed: false,
},
"duplicate MatchLabelExpression keys": {
class: makeClass(nil, topologyDupKeys),
class: makeClass(&waitingMode, topologyDupKeys),
shouldSucceed: false,
},
"duplicate MatchLabelExpression keys but across separate terms": {
class: makeClass(nil, topologyMultiTerm),
class: makeClass(&waitingMode, topologyMultiTerm),
shouldSucceed: true,
},
"duplicate AllowedTopologies terms - identical": {
class: makeClass(nil, topologyDupTermsIdentical),
class: makeClass(&waitingMode, topologyDupTermsIdentical),
shouldSucceed: false,
},
"two AllowedTopologies terms, with a pair of the same MatchLabelExpressions and a pair of different ones": {
class: makeClass(nil, topologyExprsOneSameOneDiff),
class: makeClass(&waitingMode, topologyExprsOneSameOneDiff),
shouldSucceed: true,
},
"two AllowedTopologies terms, with a pair of the same Values and a pair of different ones": {
class: makeClass(nil, topologyValuesOneSameOneDiff),
class: makeClass(&waitingMode, topologyValuesOneSameOneDiff),
shouldSucceed: true,
},
"duplicate AllowedTopologies terms - different MatchLabelExpressions order": {
class: makeClass(nil, topologyDupTermsDiffExprOrder),
class: makeClass(&waitingMode, topologyDupTermsDiffExprOrder),
shouldSucceed: false,
},
"duplicate AllowedTopologies terms - different TopologySelectorRequirement values order": {
class: makeClass(nil, topologyDupTermsDiffValueOrder),
class: makeClass(&waitingMode, topologyDupTermsDiffValueOrder),
shouldSucceed: false,
},
}

// Disable VolumeScheduling so nil VolumeBindingMode doesn't fail to validate.
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
if err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err)
}

// TODO: remove when feature gate not required
err = utilfeature.DefaultFeatureGate.Set("DynamicProvisioningScheduling=true")
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
if err != nil {
t.Fatalf("Failed to enable feature gate for DynamicProvisioningScheduling: %v", err)
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}

for testName, testCase := range cases {
Expand All @@ -906,9 +900,9 @@ func TestValidateAllowedTopologies(t *testing.T) {
}
}

err = utilfeature.DefaultFeatureGate.Set("DynamicProvisioningScheduling=false")
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
if err != nil {
t.Fatalf("Failed to disable feature gate for DynamicProvisioningScheduling: %v", err)
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err)
}

for testName, testCase := range cases {
Expand Down
Loading

0 comments on commit 37b2929

Please sign in to comment.