mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 13:55:41 +00:00
graduate PersistentVolumeLastPhaseTransitionTime to GA in 1.31
This commit is contained in:
parent
a31030543c
commit
5ea0c7be1e
2
api/openapi-spec/swagger.json
generated
2
api/openapi-spec/swagger.json
generated
@ -9023,7 +9023,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"lastPhaseTransitionTime": {
|
"lastPhaseTransitionTime": {
|
||||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time",
|
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time",
|
||||||
"description": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions. This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default)."
|
"description": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions."
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"description": "message is a human-readable message indicating details about why the volume is in this state.",
|
"description": "message is a human-readable message indicating details about why the volume is in this state.",
|
||||||
|
@ -4817,7 +4817,7 @@
|
|||||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time"
|
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions. This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default)."
|
"description": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions."
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"description": "message is a human-readable message indicating details about why the volume is in this state.",
|
"description": "message is a human-readable message indicating details about why the volume is in this state.",
|
||||||
|
@ -41,14 +41,6 @@ func DropDisabledSpecFields(pvSpec *api.PersistentVolumeSpec, oldPVSpec *api.Per
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DropDisabledStatusFields removes disabled fields from the pv status.
|
|
||||||
// This should be called from PrepareForUpdate for all resources containing a pv status.
|
|
||||||
func DropDisabledStatusFields(oldStatus, newStatus *api.PersistentVolumeStatus) {
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PersistentVolumeLastPhaseTransitionTime) && oldStatus.LastPhaseTransitionTime.IsZero() {
|
|
||||||
newStatus.LastPhaseTransitionTime = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetWarningsForPersistentVolume(pv *api.PersistentVolume) []string {
|
func GetWarningsForPersistentVolume(pv *api.PersistentVolume) []string {
|
||||||
if pv == nil {
|
if pv == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -392,8 +392,6 @@ type PersistentVolumeStatus struct {
|
|||||||
Reason string
|
Reason string
|
||||||
// LastPhaseTransitionTime is the time the phase transitioned from one to another
|
// LastPhaseTransitionTime is the time the phase transitioned from one to another
|
||||||
// and automatically resets to current time everytime a volume phase transitions.
|
// and automatically resets to current time everytime a volume phase transitions.
|
||||||
// This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).
|
|
||||||
// +featureGate=PersistentVolumeLastPhaseTransitionTime
|
|
||||||
// +optional
|
// +optional
|
||||||
LastPhaseTransitionTime *metav1.Time
|
LastPhaseTransitionTime *metav1.Time
|
||||||
}
|
}
|
||||||
|
@ -534,6 +534,7 @@ const (
|
|||||||
// kep: https://kep.k8s.io/3762
|
// kep: https://kep.k8s.io/3762
|
||||||
// alpha: v1.28
|
// alpha: v1.28
|
||||||
// beta: v1.29
|
// beta: v1.29
|
||||||
|
// GA: v1.31
|
||||||
//
|
//
|
||||||
// Adds a new field to persistent volumes which holds a timestamp of when the volume last transitioned its phase.
|
// Adds a new field to persistent volumes which holds a timestamp of when the volume last transitioned its phase.
|
||||||
PersistentVolumeLastPhaseTransitionTime featuregate.Feature = "PersistentVolumeLastPhaseTransitionTime"
|
PersistentVolumeLastPhaseTransitionTime featuregate.Feature = "PersistentVolumeLastPhaseTransitionTime"
|
||||||
@ -1089,7 +1090,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
PDBUnhealthyPodEvictionPolicy: {Default: true, PreRelease: featuregate.Beta},
|
PDBUnhealthyPodEvictionPolicy: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
|
||||||
PersistentVolumeLastPhaseTransitionTime: {Default: true, PreRelease: featuregate.Beta},
|
PersistentVolumeLastPhaseTransitionTime: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.33
|
||||||
|
|
||||||
PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha},
|
PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
|
2
pkg/generated/openapi/zz_generated.openapi.go
generated
2
pkg/generated/openapi/zz_generated.openapi.go
generated
@ -26072,7 +26072,7 @@ func schema_k8sio_api_core_v1_PersistentVolumeStatus(ref common.ReferenceCallbac
|
|||||||
},
|
},
|
||||||
"lastPhaseTransitionTime": {
|
"lastPhaseTransitionTime": {
|
||||||
SchemaProps: spec.SchemaProps{
|
SchemaProps: spec.SchemaProps{
|
||||||
Description: "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions. This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).",
|
Description: "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions.",
|
||||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -33,10 +33,7 @@ import (
|
|||||||
genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
|
genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
|
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/core/persistentvolume"
|
"k8s.io/kubernetes/pkg/registry/core/persistentvolume"
|
||||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||||
)
|
)
|
||||||
@ -174,7 +171,6 @@ func TestWatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateStatus(t *testing.T) {
|
func TestUpdateStatus(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentVolumeLastPhaseTransitionTime, true)
|
|
||||||
storage, statusStorage, server := newStorage(t)
|
storage, statusStorage, server := newStorage(t)
|
||||||
defer server.Terminate(t)
|
defer server.Terminate(t)
|
||||||
defer storage.Store.DestroyFunc()
|
defer storage.Store.DestroyFunc()
|
||||||
|
@ -21,9 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -70,11 +67,9 @@ func (persistentvolumeStrategy) PrepareForCreate(ctx context.Context, obj runtim
|
|||||||
pv := obj.(*api.PersistentVolume)
|
pv := obj.(*api.PersistentVolume)
|
||||||
pv.Status = api.PersistentVolumeStatus{}
|
pv.Status = api.PersistentVolumeStatus{}
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.PersistentVolumeLastPhaseTransitionTime) {
|
pv.Status.Phase = api.VolumePending
|
||||||
pv.Status.Phase = api.VolumePending
|
now := NowFunc()
|
||||||
now := NowFunc()
|
pv.Status.LastPhaseTransitionTime = &now
|
||||||
pv.Status.LastPhaseTransitionTime = &now
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (persistentvolumeStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
func (persistentvolumeStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||||
@ -148,20 +143,17 @@ func (persistentvolumeStatusStrategy) PrepareForUpdate(ctx context.Context, obj,
|
|||||||
oldPv := old.(*api.PersistentVolume)
|
oldPv := old.(*api.PersistentVolume)
|
||||||
newPv.Spec = oldPv.Spec
|
newPv.Spec = oldPv.Spec
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.PersistentVolumeLastPhaseTransitionTime) {
|
switch {
|
||||||
switch {
|
case oldPv.Status.Phase == newPv.Status.Phase && newPv.Status.LastPhaseTransitionTime == nil:
|
||||||
case oldPv.Status.Phase == newPv.Status.Phase && newPv.Status.LastPhaseTransitionTime == nil:
|
// phase didn't change, preserve the existing transition time if set
|
||||||
// phase didn't change, preserve the existing transition time if set
|
newPv.Status.LastPhaseTransitionTime = oldPv.Status.LastPhaseTransitionTime
|
||||||
newPv.Status.LastPhaseTransitionTime = oldPv.Status.LastPhaseTransitionTime
|
|
||||||
|
|
||||||
case oldPv.Status.Phase != newPv.Status.Phase && (newPv.Status.LastPhaseTransitionTime == nil || newPv.Status.LastPhaseTransitionTime.Equal(oldPv.Status.LastPhaseTransitionTime)):
|
case oldPv.Status.Phase != newPv.Status.Phase && (newPv.Status.LastPhaseTransitionTime == nil || newPv.Status.LastPhaseTransitionTime.Equal(oldPv.Status.LastPhaseTransitionTime)):
|
||||||
// phase changed and client didn't set or didn't change the transition time
|
// phase changed and client didn't set or didn't change the transition time
|
||||||
now := NowFunc()
|
now := NowFunc()
|
||||||
newPv.Status.LastPhaseTransitionTime = &now
|
newPv.Status.LastPhaseTransitionTime = &now
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pvutil.DropDisabledStatusFields(&oldPv.Status, &newPv.Status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (persistentvolumeStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (persistentvolumeStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
|
@ -21,11 +21,8 @@ import (
|
|||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -53,14 +50,12 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fg bool
|
|
||||||
oldObj *api.PersistentVolume
|
oldObj *api.PersistentVolume
|
||||||
newObj *api.PersistentVolume
|
newObj *api.PersistentVolume
|
||||||
expectedObj *api.PersistentVolume
|
expectedObj *api.PersistentVolume
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "feature enabled: timestamp is updated when phase changes",
|
name: "timestamp is updated when phase changes",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -88,8 +83,7 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "feature enabled: timestamp is updated when phase changes and old pv has a timestamp",
|
name: "timestamp is updated when phase changes and old pv has a timestamp",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -118,8 +112,7 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "feature enabled: user timestamp change is respected on no phase change",
|
name: "user timestamp change is respected on no phase change",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -148,8 +141,7 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "feature enabled: user timestamp is respected on phase change",
|
name: "user timestamp is respected on phase change",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -179,8 +171,7 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "feature enabled: user timestamp change is respected on no phase change when old pv has a timestamp",
|
name: "user timestamp change is respected on no phase change when old pv has a timestamp",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -210,8 +201,7 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "feature enabled: timestamp is updated when phase changes and both new and old timestamp matches",
|
name: "timestamp is updated when phase changes and both new and old timestamp matches",
|
||||||
fg: true,
|
|
||||||
oldObj: &api.PersistentVolume{
|
oldObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -240,131 +230,10 @@ func TestStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "feature disabled: timestamp is not updated",
|
|
||||||
fg: false,
|
|
||||||
oldObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumePending,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
newObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "feature disabled: user timestamp is overwritten on phase change to nil",
|
|
||||||
fg: false,
|
|
||||||
oldObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumePending,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
newObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumePending,
|
|
||||||
LastPhaseTransitionTime: &later,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumePending,
|
|
||||||
LastPhaseTransitionTime: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "feature disabled: user timestamp change is respected on phase change",
|
|
||||||
fg: false,
|
|
||||||
oldObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumePending,
|
|
||||||
LastPhaseTransitionTime: &origin,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
newObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
LastPhaseTransitionTime: &later,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
LastPhaseTransitionTime: &later,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "feature disabled: user timestamp change is respected on no phase change",
|
|
||||||
fg: false,
|
|
||||||
oldObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
LastPhaseTransitionTime: &origin,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
newObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
LastPhaseTransitionTime: &later,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
Status: api.PersistentVolumeStatus{
|
|
||||||
Phase: api.VolumeBound,
|
|
||||||
LastPhaseTransitionTime: &later,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentVolumeLastPhaseTransitionTime, tc.fg)
|
|
||||||
|
|
||||||
obj := tc.newObj.DeepCopy()
|
obj := tc.newObj.DeepCopy()
|
||||||
StatusStrategy.PrepareForUpdate(context.TODO(), obj, tc.oldObj.DeepCopy())
|
StatusStrategy.PrepareForUpdate(context.TODO(), obj, tc.oldObj.DeepCopy())
|
||||||
@ -383,13 +252,11 @@ func TestStatusCreate(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fg bool
|
|
||||||
newObj *api.PersistentVolume
|
newObj *api.PersistentVolume
|
||||||
expectedObj *api.PersistentVolume
|
expectedObj *api.PersistentVolume
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "feature enabled: pv is in pending phase and has a timestamp",
|
name: "pv is in pending phase and has a timestamp",
|
||||||
fg: true,
|
|
||||||
newObj: &api.PersistentVolume{
|
newObj: &api.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
@ -405,26 +272,11 @@ func TestStatusCreate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "feature disabled: pv does not have phase and timestamp",
|
|
||||||
fg: false,
|
|
||||||
newObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedObj: &api.PersistentVolume{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentVolumeLastPhaseTransitionTime, tc.fg)
|
|
||||||
obj := tc.newObj.DeepCopy()
|
obj := tc.newObj.DeepCopy()
|
||||||
StatusStrategy.PrepareForCreate(context.TODO(), obj)
|
StatusStrategy.PrepareForCreate(context.TODO(), obj)
|
||||||
if !reflect.DeepEqual(obj, tc.expectedObj) {
|
if !reflect.DeepEqual(obj, tc.expectedObj) {
|
||||||
|
@ -3406,8 +3406,6 @@ message PersistentVolumeStatus {
|
|||||||
|
|
||||||
// lastPhaseTransitionTime is the time the phase transitioned from one to another
|
// lastPhaseTransitionTime is the time the phase transitioned from one to another
|
||||||
// and automatically resets to current time everytime a volume phase transitions.
|
// and automatically resets to current time everytime a volume phase transitions.
|
||||||
// This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).
|
|
||||||
// +featureGate=PersistentVolumeLastPhaseTransitionTime
|
|
||||||
// +optional
|
// +optional
|
||||||
optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastPhaseTransitionTime = 4;
|
optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastPhaseTransitionTime = 4;
|
||||||
}
|
}
|
||||||
|
@ -425,8 +425,6 @@ type PersistentVolumeStatus struct {
|
|||||||
Reason string `json:"reason,omitempty" protobuf:"bytes,3,opt,name=reason"`
|
Reason string `json:"reason,omitempty" protobuf:"bytes,3,opt,name=reason"`
|
||||||
// lastPhaseTransitionTime is the time the phase transitioned from one to another
|
// lastPhaseTransitionTime is the time the phase transitioned from one to another
|
||||||
// and automatically resets to current time everytime a volume phase transitions.
|
// and automatically resets to current time everytime a volume phase transitions.
|
||||||
// This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).
|
|
||||||
// +featureGate=PersistentVolumeLastPhaseTransitionTime
|
|
||||||
// +optional
|
// +optional
|
||||||
LastPhaseTransitionTime *metav1.Time `json:"lastPhaseTransitionTime,omitempty" protobuf:"bytes,4,opt,name=lastPhaseTransitionTime"`
|
LastPhaseTransitionTime *metav1.Time `json:"lastPhaseTransitionTime,omitempty" protobuf:"bytes,4,opt,name=lastPhaseTransitionTime"`
|
||||||
}
|
}
|
||||||
|
@ -1500,7 +1500,7 @@ var map_PersistentVolumeStatus = map[string]string{
|
|||||||
"phase": "phase indicates if a volume is available, bound to a claim, or released by a claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#phase",
|
"phase": "phase indicates if a volume is available, bound to a claim, or released by a claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#phase",
|
||||||
"message": "message is a human-readable message indicating details about why the volume is in this state.",
|
"message": "message is a human-readable message indicating details about why the volume is in this state.",
|
||||||
"reason": "reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI.",
|
"reason": "reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI.",
|
||||||
"lastPhaseTransitionTime": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions. This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).",
|
"lastPhaseTransitionTime": "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions.",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PersistentVolumeStatus) SwaggerDoc() map[string]string {
|
func (PersistentVolumeStatus) SwaggerDoc() map[string]string {
|
||||||
|
@ -243,9 +243,6 @@ var (
|
|||||||
// Marks a single test that tests pod-to-pod connectivity between every pair of nodes.
|
// Marks a single test that tests pod-to-pod connectivity between every pair of nodes.
|
||||||
NoSNAT = framework.WithFeature(framework.ValidFeatures.Add("NoSNAT"))
|
NoSNAT = framework.WithFeature(framework.ValidFeatures.Add("NoSNAT"))
|
||||||
|
|
||||||
// TODO: document the feature (owning SIG, when to use this feature for a test)
|
|
||||||
PersistentVolumeLastPhaseTransitionTime = framework.WithFeature(framework.ValidFeatures.Add("PersistentVolumeLastPhaseTransitionTime"))
|
|
||||||
|
|
||||||
// Owner: sig-network
|
// Owner: sig-network
|
||||||
// Marks a single test that tests cluster DNS performance with many services.
|
// Marks a single test that tests cluster DNS performance with many services.
|
||||||
PerformanceDNS = framework.WithFeature(framework.ValidFeatures.Add("PerformanceDNS"))
|
PerformanceDNS = framework.WithFeature(framework.ValidFeatures.Add("PerformanceDNS"))
|
||||||
|
@ -34,7 +34,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/util/retry"
|
"k8s.io/client-go/util/retry"
|
||||||
"k8s.io/kubernetes/test/e2e/feature"
|
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
|
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
|
||||||
@ -213,7 +212,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create new PV without claim, verify it's in Available state and LastPhaseTransitionTime is set.
|
// Create new PV without claim, verify it's in Available state and LastPhaseTransitionTime is set.
|
||||||
f.It("create a PV: test phase transition timestamp is set and phase is Available", feature.PersistentVolumeLastPhaseTransitionTime, func(ctx context.Context) {
|
f.It("create a PV: test phase transition timestamp is set and phase is Available", func(ctx context.Context) {
|
||||||
pvObj := e2epv.MakePersistentVolume(pvConfig)
|
pvObj := e2epv.MakePersistentVolume(pvConfig)
|
||||||
pv, err = e2epv.CreatePV(ctx, c, f.Timeouts, pvObj)
|
pv, err = e2epv.CreatePV(ctx, c, f.Timeouts, pvObj)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
@ -232,7 +231,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
|
|||||||
|
|
||||||
// Create PV and pre-bound PVC that matches the PV, verify that when PV and PVC bind
|
// Create PV and pre-bound PVC that matches the PV, verify that when PV and PVC bind
|
||||||
// the LastPhaseTransitionTime filed of the PV is updated.
|
// the LastPhaseTransitionTime filed of the PV is updated.
|
||||||
f.It("create a PV and a pre-bound PVC: test phase transition timestamp is set", feature.PersistentVolumeLastPhaseTransitionTime, func(ctx context.Context) {
|
f.It("create a PV and a pre-bound PVC: test phase transition timestamp is set", func(ctx context.Context) {
|
||||||
pv, pvc, err = e2epv.CreatePVPVC(ctx, c, f.Timeouts, pvConfig, pvcConfig, ns, true)
|
pv, pvc, err = e2epv.CreatePVPVC(ctx, c, f.Timeouts, pvConfig, pvcConfig, ns, true)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
@ -252,7 +251,7 @@ var _ = utils.SIGDescribe("PersistentVolumes", func() {
|
|||||||
// Create PV and pre-bound PVC that matches the PV, verify that when PV and PVC bind
|
// Create PV and pre-bound PVC that matches the PV, verify that when PV and PVC bind
|
||||||
// the LastPhaseTransitionTime field of the PV is set, then delete the PVC to change PV phase to
|
// the LastPhaseTransitionTime field of the PV is set, then delete the PVC to change PV phase to
|
||||||
// released and validate PV LastPhaseTransitionTime correctly updated timestamp.
|
// released and validate PV LastPhaseTransitionTime correctly updated timestamp.
|
||||||
f.It("create a PV and a pre-bound PVC: test phase transition timestamp multiple updates", feature.PersistentVolumeLastPhaseTransitionTime, func(ctx context.Context) {
|
f.It("create a PV and a pre-bound PVC: test phase transition timestamp multiple updates", func(ctx context.Context) {
|
||||||
pv, pvc, err = e2epv.CreatePVPVC(ctx, c, f.Timeouts, pvConfig, pvcConfig, ns, true)
|
pv, pvc, err = e2epv.CreatePVPVC(ctx, c, f.Timeouts, pvConfig, pvcConfig, ns, true)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user