Move Snapshot to GA

This commit is contained in:
xing-yang 2020-09-26 16:23:05 +00:00
parent 17376e6aef
commit c0eaee3494
8 changed files with 58 additions and 132 deletions

View File

@ -8140,7 +8140,7 @@
}, },
"dataSource": { "dataSource": {
"$ref": "#/definitions/io.k8s.api.core.v1.TypedLocalObjectReference", "$ref": "#/definitions/io.k8s.api.core.v1.TypedLocalObjectReference",
"description": "This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC (PersistentVolumeClaim) * An existing custom resource/object that implements data population (Alpha) In order to use VolumeSnapshot object types, the appropriate feature gate must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the specified data source is not supported, the volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change." "description": "This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) * An existing custom resource that implements data population (Alpha) In order to use custom resource types that implement data population, the AnyVolumeDataSource feature gate must be enabled. If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source."
}, },
"resources": { "resources": {
"$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements",

View File

@ -61,9 +61,7 @@ func dataSourceIsEnabled(pvcSpec *core.PersistentVolumeClaimSpec) bool {
} }
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeSnapshotDataSource) && if pvcSpec.DataSource.Kind == volumeSnapshot && apiGroup == "snapshot.storage.k8s.io" {
pvcSpec.DataSource.Kind == volumeSnapshot &&
apiGroup == "snapshot.storage.k8s.io" {
return true return true
} }
} }

View File

@ -51,22 +51,18 @@ func TestDropDisabledSnapshotDataSource(t *testing.T) {
pvcInfo := []struct { pvcInfo := []struct {
description string description string
hasDataSource bool
pvc func() *core.PersistentVolumeClaim pvc func() *core.PersistentVolumeClaim
}{ }{
{ {
description: "pvc without DataSource", description: "pvc without DataSource",
hasDataSource: false,
pvc: pvcWithoutDataSource, pvc: pvcWithoutDataSource,
}, },
{ {
description: "pvc with DataSource", description: "pvc with DataSource",
hasDataSource: true,
pvc: pvcWithDataSource, pvc: pvcWithDataSource,
}, },
{ {
description: "is nil", description: "is nil",
hasDataSource: false,
pvc: func() *core.PersistentVolumeClaim { return nil }, pvc: func() *core.PersistentVolumeClaim { return nil },
}, },
} }
@ -74,18 +70,15 @@ func TestDropDisabledSnapshotDataSource(t *testing.T) {
// Ensure that any data sources aren't enabled for this test // Ensure that any data sources aren't enabled for this test
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, false)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, false)()
for _, enabled := range []bool{true, false} {
for _, oldpvcInfo := range pvcInfo { for _, oldpvcInfo := range pvcInfo {
for _, newpvcInfo := range pvcInfo { for _, newpvcInfo := range pvcInfo {
oldPvcHasDataSource, oldpvc := oldpvcInfo.hasDataSource, oldpvcInfo.pvc() oldpvc := oldpvcInfo.pvc()
newPvcHasDataSource, newpvc := newpvcInfo.hasDataSource, newpvcInfo.pvc() newpvc := newpvcInfo.pvc()
if newpvc == nil { if newpvc == nil {
continue continue
} }
t.Run(fmt.Sprintf("feature enabled=%v, old pvc %v, new pvc %v", enabled, oldpvcInfo.description, newpvcInfo.description), func(t *testing.T) { t.Run(fmt.Sprintf("old pvc %v, new pvc %v", oldpvcInfo.description, newpvcInfo.description), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSnapshotDataSource, enabled)()
var oldpvcSpec *core.PersistentVolumeClaimSpec var oldpvcSpec *core.PersistentVolumeClaimSpec
if oldpvc != nil { if oldpvc != nil {
oldpvcSpec = &oldpvc.Spec oldpvcSpec = &oldpvc.Spec
@ -97,32 +90,14 @@ func TestDropDisabledSnapshotDataSource(t *testing.T) {
t.Errorf("old pvc changed: %v", diff.ObjectReflectDiff(oldpvc, oldpvcInfo.pvc())) t.Errorf("old pvc changed: %v", diff.ObjectReflectDiff(oldpvc, oldpvcInfo.pvc()))
} }
switch { // new pvc should not be changed
case enabled || oldPvcHasDataSource:
// new pvc should not be changed if the feature is enabled, or if the old pvc had DataSource
if !reflect.DeepEqual(newpvc, newpvcInfo.pvc()) { if !reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc changed: %v", diff.ObjectReflectDiff(newpvc, newpvcInfo.pvc())) t.Errorf("new pvc changed: %v", diff.ObjectReflectDiff(newpvc, newpvcInfo.pvc()))
} }
case newPvcHasDataSource:
// new pvc should be changed
if reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc was not changed")
}
// new pvc should not have DataSource
if !reflect.DeepEqual(newpvc, pvcWithoutDataSource()) {
t.Errorf("new pvc had DataSource: %v", diff.ObjectReflectDiff(newpvc, pvcWithoutDataSource()))
}
default:
// new pvc should not need to be changed
if !reflect.DeepEqual(newpvc, newpvcInfo.pvc()) {
t.Errorf("new pvc changed: %v", diff.ObjectReflectDiff(newpvc, newpvcInfo.pvc()))
}
}
}) })
} }
} }
} }
}
// TestPVCDataSourceSpecFilter checks to ensure the DropDisabledFields function behaves correctly for PVCDataSource featuregate // TestPVCDataSourceSpecFilter checks to ensure the DropDisabledFields function behaves correctly for PVCDataSource featuregate
func TestPVCDataSourceSpecFilter(t *testing.T) { func TestPVCDataSourceSpecFilter(t *testing.T) {
@ -204,23 +179,22 @@ func TestAnyDataSourceFilter(t *testing.T) {
var tests = map[string]struct { var tests = map[string]struct {
spec core.PersistentVolumeClaimSpec spec core.PersistentVolumeClaimSpec
snapshotEnabled bool
anyEnabled bool anyEnabled bool
want *core.TypedLocalObjectReference want *core.TypedLocalObjectReference
}{ }{
"both disabled with empty ds": { "any disabled with empty ds": {
spec: core.PersistentVolumeClaimSpec{}, spec: core.PersistentVolumeClaimSpec{},
want: nil, want: nil,
}, },
"both disabled with volume ds": { "any disabled with volume ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: volumeDataSource}, spec: core.PersistentVolumeClaimSpec{DataSource: volumeDataSource},
want: volumeDataSource, want: volumeDataSource,
}, },
"both disabled with snapshot ds": { "any disabled with snapshot ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: snapshotDataSource}, spec: core.PersistentVolumeClaimSpec{DataSource: snapshotDataSource},
want: nil, want: snapshotDataSource,
}, },
"both disabled with generic ds": { "any disabled with generic ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: genericDataSource}, spec: core.PersistentVolumeClaimSpec{DataSource: genericDataSource},
want: nil, want: nil,
}, },
@ -244,50 +218,15 @@ func TestAnyDataSourceFilter(t *testing.T) {
anyEnabled: true, anyEnabled: true,
want: genericDataSource, want: genericDataSource,
}, },
"snapshot enabled with snapshot ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: snapshotDataSource},
snapshotEnabled: true,
want: snapshotDataSource,
},
"snapshot enabled with generic ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: genericDataSource},
snapshotEnabled: true,
want: nil,
},
"both enabled with empty ds": {
spec: core.PersistentVolumeClaimSpec{},
snapshotEnabled: true,
anyEnabled: true,
want: nil,
},
"both enabled with volume ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: volumeDataSource},
snapshotEnabled: true,
anyEnabled: true,
want: volumeDataSource,
},
"both enabled with snapshot ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: snapshotDataSource},
snapshotEnabled: true,
anyEnabled: true,
want: snapshotDataSource,
},
"both enabled with generic ds": {
spec: core.PersistentVolumeClaimSpec{DataSource: genericDataSource},
snapshotEnabled: true,
anyEnabled: true,
want: genericDataSource,
},
} }
for testName, test := range tests { for testName, test := range tests {
t.Run(testName, func(t *testing.T) { t.Run(testName, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSnapshotDataSource, test.snapshotEnabled)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, test.anyEnabled)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, test.anyEnabled)()
DropDisabledFields(&test.spec, nil) DropDisabledFields(&test.spec, nil)
if test.spec.DataSource != test.want { if test.spec.DataSource != test.want {
t.Errorf("expected condition was not met, test: %s, snapshotEnabled: %v, anyEnabled: %v, spec: %v, expected: %v", t.Errorf("expected condition was not met, test: %s, anyEnabled: %v, spec: %v, expected: %v",
testName, test.snapshotEnabled, test.anyEnabled, test.spec, test.want) testName, test.anyEnabled, test.spec, test.want)
} }
}) })
} }

View File

@ -445,17 +445,13 @@ type PersistentVolumeClaimSpec struct {
// +optional // +optional
VolumeMode *PersistentVolumeMode VolumeMode *PersistentVolumeMode
// This field can be used to specify either: // This field can be used to specify either:
// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) // * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
// * An existing PVC (PersistentVolumeClaim) // * An existing PVC (PersistentVolumeClaim)
// * An existing custom resource/object that implements data population (Alpha) // * An existing custom resource that implements data population (Alpha)
// In order to use VolumeSnapshot object types, the appropriate feature gate // In order to use custom resource types that implement data population,
// must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) // the AnyVolumeDataSource feature gate must be enabled.
// If the provisioner or an external controller can support the specified data source, // If the provisioner or an external controller can support the specified data source,
// it will create a new volume based on the contents of the specified data source. // it will create a new volume based on the contents of the specified data source.
// If the specified data source is not supported, the volume will
// not be created and the failure will be reported as an event.
// In the future, we plan to support more data source types and the behavior
// of the provisioner may change.
// +optional // +optional
DataSource *TypedLocalObjectReference DataSource *TypedLocalObjectReference
} }

View File

@ -338,6 +338,7 @@ const (
// owner: @xing-yang // owner: @xing-yang
// alpha: v1.12 // alpha: v1.12
// beta: v1.17 // beta: v1.17
// GA: v1.20
// //
// Enable volume snapshot data source support. // Enable volume snapshot data source support.
VolumeSnapshotDataSource featuregate.Feature = "VolumeSnapshotDataSource" VolumeSnapshotDataSource featuregate.Feature = "VolumeSnapshotDataSource"
@ -718,7 +719,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
RuntimeClass: {Default: true, PreRelease: featuregate.Beta}, RuntimeClass: {Default: true, PreRelease: featuregate.Beta},
NodeLease: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, NodeLease: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
SCTPSupport: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22 SCTPSupport: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
VolumeSnapshotDataSource: {Default: true, PreRelease: featuregate.Beta}, VolumeSnapshotDataSource: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.21
ProcMountType: {Default: false, PreRelease: featuregate.Alpha}, ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
TTLAfterFinished: {Default: false, PreRelease: featuregate.Alpha}, TTLAfterFinished: {Default: false, PreRelease: featuregate.Alpha},
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta}, KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},

View File

@ -2681,17 +2681,13 @@ message PersistentVolumeClaimSpec {
optional string volumeMode = 6; optional string volumeMode = 6;
// This field can be used to specify either: // This field can be used to specify either:
// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) // * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
// * An existing PVC (PersistentVolumeClaim) // * An existing PVC (PersistentVolumeClaim)
// * An existing custom resource/object that implements data population (Alpha) // * An existing custom resource that implements data population (Alpha)
// In order to use VolumeSnapshot object types, the appropriate feature gate // In order to use custom resource types that implement data population,
// must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) // the AnyVolumeDataSource feature gate must be enabled.
// If the provisioner or an external controller can support the specified data source, // If the provisioner or an external controller can support the specified data source,
// it will create a new volume based on the contents of the specified data source. // it will create a new volume based on the contents of the specified data source.
// If the specified data source is not supported, the volume will
// not be created and the failure will be reported as an event.
// In the future, we plan to support more data source types and the behavior
// of the provisioner may change.
// +optional // +optional
optional TypedLocalObjectReference dataSource = 7; optional TypedLocalObjectReference dataSource = 7;
} }

View File

@ -489,17 +489,13 @@ type PersistentVolumeClaimSpec struct {
// +optional // +optional
VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,6,opt,name=volumeMode,casttype=PersistentVolumeMode"` VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,6,opt,name=volumeMode,casttype=PersistentVolumeMode"`
// This field can be used to specify either: // This field can be used to specify either:
// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) // * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
// * An existing PVC (PersistentVolumeClaim) // * An existing PVC (PersistentVolumeClaim)
// * An existing custom resource/object that implements data population (Alpha) // * An existing custom resource that implements data population (Alpha)
// In order to use VolumeSnapshot object types, the appropriate feature gate // In order to use custom resource types that implement data population,
// must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) // the AnyVolumeDataSource feature gate must be enabled.
// If the provisioner or an external controller can support the specified data source, // If the provisioner or an external controller can support the specified data source,
// it will create a new volume based on the contents of the specified data source. // it will create a new volume based on the contents of the specified data source.
// If the specified data source is not supported, the volume will
// not be created and the failure will be reported as an event.
// In the future, we plan to support more data source types and the behavior
// of the provisioner may change.
// +optional // +optional
DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" protobuf:"bytes,7,opt,name=dataSource"` DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" protobuf:"bytes,7,opt,name=dataSource"`
} }

View File

@ -1310,7 +1310,7 @@ var map_PersistentVolumeClaimSpec = map[string]string{
"volumeName": "VolumeName is the binding reference to the PersistentVolume backing this claim.", "volumeName": "VolumeName is the binding reference to the PersistentVolume backing this claim.",
"storageClassName": "Name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", "storageClassName": "Name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1",
"volumeMode": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.", "volumeMode": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.",
"dataSource": "This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC (PersistentVolumeClaim) * An existing custom resource/object that implements data population (Alpha) In order to use VolumeSnapshot object types, the appropriate feature gate must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the specified data source is not supported, the volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change.", "dataSource": "This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) * An existing custom resource that implements data population (Alpha) In order to use custom resource types that implement data population, the AnyVolumeDataSource feature gate must be enabled. If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source.",
} }
func (PersistentVolumeClaimSpec) SwaggerDoc() map[string]string { func (PersistentVolumeClaimSpec) SwaggerDoc() map[string]string {