mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
update CRD strategy for status updates
1. Clear the status of the CRD and set the Generation before creation. 2. While updating the CRD: - ignore changes on status. - increase Generation if spec changes. 3. Don't update objectmeta when status is updated. - however, update finalizers. Without this, deletion will timeout.
This commit is contained in:
parent
baa6b2ff20
commit
5c354615e0
@ -24,13 +24,13 @@ import (
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
|
||||
)
|
||||
|
||||
// rest implements a RESTStorage for API services against etcd
|
||||
// REST implements a RESTStorage for API services against etcd
|
||||
type REST struct {
|
||||
*genericregistry.Store
|
||||
}
|
||||
|
||||
// NewREST returns a RESTStorage object that will work against API services.
|
||||
func NewREST(resource schema.GroupResource, listKind schema.GroupVersionKind, copier runtime.ObjectCopier, strategy CustomResourceDefinitionStorageStrategy, optsGetter generic.RESTOptionsGetter) *REST {
|
||||
func NewREST(resource schema.GroupResource, listKind schema.GroupVersionKind, copier runtime.ObjectCopier, strategy customResourceDefinitionStorageStrategy, optsGetter generic.RESTOptionsGetter) *REST {
|
||||
store := &genericregistry.Store{
|
||||
Copier: copier,
|
||||
NewFunc: func() runtime.Object { return &unstructured.Unstructured{} },
|
||||
|
@ -32,7 +32,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
)
|
||||
|
||||
type CustomResourceDefinitionStorageStrategy struct {
|
||||
type customResourceDefinitionStorageStrategy struct {
|
||||
runtime.ObjectTyper
|
||||
names.NameGenerator
|
||||
|
||||
@ -40,8 +40,8 @@ type CustomResourceDefinitionStorageStrategy struct {
|
||||
validator customResourceValidator
|
||||
}
|
||||
|
||||
func NewStrategy(typer runtime.ObjectTyper, namespaceScoped bool, kind schema.GroupVersionKind) CustomResourceDefinitionStorageStrategy {
|
||||
return CustomResourceDefinitionStorageStrategy{
|
||||
func NewStrategy(typer runtime.ObjectTyper, namespaceScoped bool, kind schema.GroupVersionKind) customResourceDefinitionStorageStrategy {
|
||||
return customResourceDefinitionStorageStrategy{
|
||||
ObjectTyper: typer,
|
||||
NameGenerator: names.SimpleNameGenerator,
|
||||
namespaceScoped: namespaceScoped,
|
||||
@ -52,36 +52,36 @@ func NewStrategy(typer runtime.ObjectTyper, namespaceScoped bool, kind schema.Gr
|
||||
}
|
||||
}
|
||||
|
||||
func (a CustomResourceDefinitionStorageStrategy) NamespaceScoped() bool {
|
||||
func (a customResourceDefinitionStorageStrategy) NamespaceScoped() bool {
|
||||
return a.namespaceScoped
|
||||
}
|
||||
|
||||
func (CustomResourceDefinitionStorageStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
func (customResourceDefinitionStorageStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
}
|
||||
|
||||
func (CustomResourceDefinitionStorageStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
func (customResourceDefinitionStorageStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
}
|
||||
|
||||
func (a CustomResourceDefinitionStorageStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
func (a customResourceDefinitionStorageStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
return a.validator.Validate(ctx, obj)
|
||||
}
|
||||
|
||||
func (CustomResourceDefinitionStorageStrategy) AllowCreateOnUpdate() bool {
|
||||
func (customResourceDefinitionStorageStrategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (CustomResourceDefinitionStorageStrategy) AllowUnconditionalUpdate() bool {
|
||||
func (customResourceDefinitionStorageStrategy) AllowUnconditionalUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (CustomResourceDefinitionStorageStrategy) Canonicalize(obj runtime.Object) {
|
||||
func (customResourceDefinitionStorageStrategy) Canonicalize(obj runtime.Object) {
|
||||
}
|
||||
|
||||
func (a CustomResourceDefinitionStorageStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
func (a customResourceDefinitionStorageStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
|
||||
return a.validator.ValidateUpdate(ctx, obj, old)
|
||||
}
|
||||
|
||||
func (a CustomResourceDefinitionStorageStrategy) GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
func (a customResourceDefinitionStorageStrategy) GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
@ -102,7 +102,7 @@ func objectMetaFieldsSet(objectMeta metav1.Object, namespaceScoped bool) fields.
|
||||
}
|
||||
}
|
||||
|
||||
func (a CustomResourceDefinitionStorageStrategy) MatchCustomResourceDefinitionStorage(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
func (a customResourceDefinitionStorageStrategy) MatchCustomResourceDefinitionStorage(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
return storage.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
|
@ -14,6 +14,7 @@ go_library(
|
||||
deps = [
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
|
@ -19,6 +19,7 @@ package customresourcedefinition
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -46,9 +47,27 @@ func (strategy) NamespaceScoped() bool {
|
||||
}
|
||||
|
||||
func (strategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
|
||||
crd := obj.(*apiextensions.CustomResourceDefinition)
|
||||
crd.Status = apiextensions.CustomResourceDefinitionStatus{}
|
||||
crd.Generation = 1
|
||||
}
|
||||
|
||||
func (strategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) {
|
||||
newCRD := obj.(*apiextensions.CustomResourceDefinition)
|
||||
oldCRD := old.(*apiextensions.CustomResourceDefinition)
|
||||
newCRD.Status = oldCRD.Status
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object. We push
|
||||
// the burden of managing the status onto the clients because we can't (in general)
|
||||
// know here what version of spec the writer of the status has seen. It may seem like
|
||||
// we can at first -- since obj contains spec -- but in the future we will probably make
|
||||
// status its own object, and even if we don't, writes may be the result of a
|
||||
// read-update-write loop, so the contents of spec may not actually be the spec that
|
||||
// the controller has *seen*.
|
||||
if !apiequality.Semantic.DeepEqual(oldCRD.Spec, newCRD.Spec) {
|
||||
newCRD.Generation = oldCRD.Generation + 1
|
||||
}
|
||||
}
|
||||
|
||||
func (strategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList {
|
||||
@ -87,9 +106,14 @@ func (statusStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old r
|
||||
newObj := obj.(*apiextensions.CustomResourceDefinition)
|
||||
oldObj := old.(*apiextensions.CustomResourceDefinition)
|
||||
newObj.Spec = oldObj.Spec
|
||||
|
||||
// Status updates are for only for updating status, not objectmeta.
|
||||
// TODO: Update after ResetObjectMetaForStatus is added to meta/v1.
|
||||
newObj.Labels = oldObj.Labels
|
||||
newObj.Annotations = oldObj.Annotations
|
||||
newObj.OwnerReferences = oldObj.OwnerReferences
|
||||
newObj.Generation = oldObj.Generation
|
||||
newObj.SelfLink = oldObj.SelfLink
|
||||
}
|
||||
|
||||
func (statusStrategy) AllowCreateOnUpdate() bool {
|
||||
|
Loading…
Reference in New Issue
Block a user