rebase: update K8s packages to v0.32.1

Update K8s packages in go.mod to v0.32.1

Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
Praveen M
2025-01-16 09:41:46 +05:30
committed by mergify[bot]
parent 5aef21ea4e
commit 7eb99fc6c9
2442 changed files with 273386 additions and 47788 deletions

View File

@ -13,6 +13,7 @@ reviewers:
- saad-ali
- janetkuo
- pwittrock
- ncdc
- dims
- enj
emeritus_reviewers:
- ncdc

View File

@ -0,0 +1,122 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package registry
import (
"context"
"errors"
"strings"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/apiserver/pkg/storage"
storeerr "k8s.io/apiserver/pkg/storage/errors"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"
)
// the corrupt object deleter has the same interface as rest.GracefulDeleter
var _ rest.GracefulDeleter = &corruptObjectDeleter{}
// NewCorruptObjectDeleter returns a deleter that can perform unsafe deletion
// of corrupt objects, it makes an attempt to perform a normal deletion flow
// first, and if the normal deletion flow fails with a corrupt object error
// then it performs the unsafe delete of the object.
//
// NOTE: it skips precondition checks, finalizer constraints, and any
// post deletion hook defined in 'AfterDelete' of the registry.
//
// WARNING: This may break the cluster if the resource being deleted has dependencies.
func NewCorruptObjectDeleter(store *Store) rest.GracefulDeleter {
return &corruptObjectDeleter{store: store}
}
// corruptObjectDeleter implements unsafe object deletion flow
type corruptObjectDeleter struct {
store *Store
}
// Delete performs an unsafe deletion of the given resource from the storage.
//
// NOTE: This function should NEVER be used for any normal deletion
// flow, it is exclusively used when the user enables
// 'IgnoreStoreReadErrorWithClusterBreakingPotential' in the delete options.
func (d *corruptObjectDeleter) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, opts *metav1.DeleteOptions) (runtime.Object, bool, error) {
if opts == nil || !ptr.Deref[bool](opts.IgnoreStoreReadErrorWithClusterBreakingPotential, false) {
// this is a developer error, we should never be here, since the unsafe
// deleter is wired in the rest layer only when the option is enabled
return nil, false, apierrors.NewInternalError(errors.New("initialization error, expected normal deletion flow to be used"))
}
key, err := d.store.KeyFunc(ctx, name)
if err != nil {
return nil, false, err
}
obj := d.store.NewFunc()
qualifiedResource := d.store.qualifiedResourceFromContext(ctx)
// use the storage implementation directly, bypass the dryRun layer
storageBackend := d.store.Storage.Storage
// we leave ResourceVersion as empty in the GetOptions so the
// object is retrieved from the underlying storage directly
err = storageBackend.Get(ctx, key, storage.GetOptions{}, obj)
if err == nil || !storage.IsCorruptObject(err) {
// TODO: The Invalid error should have a field for Resource.
// After that field is added, we should fill the Resource and
// leave the Kind field empty. See the discussion in #18526.
qualifiedKind := schema.GroupKind{Group: qualifiedResource.Group, Kind: qualifiedResource.Resource}
fieldErrList := field.ErrorList{
field.Invalid(field.NewPath("ignoreStoreReadErrorWithClusterBreakingPotential"), true, "is exclusively used to delete corrupt object(s), try again by removing this option"),
}
return nil, false, apierrors.NewInvalid(qualifiedKind, name, fieldErrList)
}
// try normal deletion anyway, it is expected to fail
obj, deleted, err := d.store.Delete(ctx, name, deleteValidation, opts)
if err == nil {
return obj, deleted, err
}
// TODO: unfortunately we can't do storage.IsCorruptObject(err),
// conversion to API error drops the inner error chain
if !strings.Contains(err.Error(), "corrupt object") {
return obj, deleted, err
}
// TODO: at this instant, some actor may have a) managed to recreate this
// object by doing a delete+create, or b) the underlying error has resolved
// since the last time we checked, and the object is readable now.
klog.FromContext(ctx).V(1).Info("Going to perform unsafe object deletion", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name))
out := d.store.NewFunc()
storageOpts := storage.DeleteOptions{IgnoreStoreReadError: true}
// dropping preconditions, and keeping the admission
if err := storageBackend.Delete(ctx, key, out, nil, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil {
if storage.IsNotFound(err) {
// the DELETE succeeded, but we don't have the object since it's
// not retrievable from the storage, so we send a nil object
return nil, false, nil
}
return nil, false, storeerr.InterpretDeleteError(err, qualifiedResource, name)
}
// the DELETE succeeded, but we don't have the object sine it's
// not retrievable from the storage, so we send a nil objct
return nil, true, nil
}

View File

@ -46,7 +46,7 @@ func (s *DryRunnableStorage) Create(ctx context.Context, key string, obj, out ru
return s.Storage.Create(ctx, key, obj, out, ttl)
}
func (s *DryRunnableStorage) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, deleteValidation storage.ValidateObjectFunc, dryRun bool, cachedExistingObject runtime.Object) error {
func (s *DryRunnableStorage) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, deleteValidation storage.ValidateObjectFunc, dryRun bool, cachedExistingObject runtime.Object, opts storage.DeleteOptions) error {
if dryRun {
if err := s.Storage.Get(ctx, key, storage.GetOptions{}, out); err != nil {
return err
@ -56,7 +56,7 @@ func (s *DryRunnableStorage) Delete(ctx context.Context, key string, out runtime
}
return deleteValidation(ctx, out)
}
return s.Storage.Delete(ctx, key, out, preconditions, deleteValidation, cachedExistingObject)
return s.Storage.Delete(ctx, key, out, preconditions, deleteValidation, cachedExistingObject, opts)
}
func (s *DryRunnableStorage) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) {

View File

@ -234,6 +234,18 @@ type Store struct {
// If set, DestroyFunc has to be implemented in thread-safe way and
// be prepared for being called more than once.
DestroyFunc func()
// corruptObjDeleter implements unsafe deletion flow to enable deletion
// of corrupt object(s), it makes an attempt to perform a normal
// deletion flow first, and if the normal deletion flow fails with a
// corrupt object error then it proceeds with the unsafe deletion
// of the object from the storage.
// NOTE: it skips precondition checks, finalizer constraints, and any
// after delete hook defined in 'AfterDelete' of the registry.
// WARNING: This may break the cluster if the resource has
// dependencies. Use when the cluster is broken, and there is no
// other viable option to repair the cluster.
corruptObjDeleter rest.GracefulDeleter
}
// Note: the rest.StandardStorage interface aggregates the common REST verbs
@ -244,6 +256,8 @@ var _ GenericStore = &Store{}
var _ rest.SingularNameProvider = &Store{}
var _ rest.CorruptObjectDeleterProvider = &Store{}
const (
OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again"
resourceCountPollPeriodJitter = 1.2
@ -344,6 +358,11 @@ func (e *Store) GetDeleteStrategy() rest.RESTDeleteStrategy {
return e.DeleteStrategy
}
// GetCorruptObjDeleter returns the unsafe corrupt object deleter
func (e *Store) GetCorruptObjDeleter() rest.GracefulDeleter {
return e.corruptObjDeleter
}
// List returns a list of items matching labels and field according to the
// store's PredicateFunc.
func (e *Store) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
@ -572,7 +591,7 @@ func (e *Store) deleteWithoutFinalizers(ctx context.Context, name, key string, o
out := e.NewFunc()
klog.V(6).InfoS("Going to delete object from registry, triggered by update", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name))
// Using the rest.ValidateAllObjectFunc because the request is an UPDATE request and has already passed the admission for the UPDATE verb.
if err := e.Storage.Delete(ctx, key, out, preconditions, rest.ValidateAllObjectFunc, dryrun.IsDryRun(options.DryRun), nil); err != nil {
if err := e.Storage.Delete(ctx, key, out, preconditions, rest.ValidateAllObjectFunc, dryrun.IsDryRun(options.DryRun), nil, storage.DeleteOptions{}); err != nil {
// Deletion is racy, i.e., there could be multiple update
// requests to remove all finalizers from the object, so we
// ignore the NotFound error.
@ -1182,7 +1201,7 @@ func (e *Store) Delete(ctx context.Context, name string, deleteValidation rest.V
// delete immediately, or no graceful deletion supported
klog.V(6).InfoS("Going to delete object from registry", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name))
out = e.NewFunc()
if err := e.Storage.Delete(ctx, key, out, &preconditions, storage.ValidateObjectFunc(deleteValidation), dryrun.IsDryRun(options.DryRun), nil); err != nil {
if err := e.Storage.Delete(ctx, key, out, &preconditions, storage.ValidateObjectFunc(deleteValidation), dryrun.IsDryRun(options.DryRun), nil, storage.DeleteOptions{}); err != nil {
// Please refer to the place where we set ignoreNotFound for the reason
// why we ignore the NotFound error .
if storage.IsNotFound(err) && ignoreNotFound && lastExisting != nil {
@ -1631,6 +1650,10 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error {
e.ReadinessCheckFunc = e.Storage.Storage.ReadinessCheck
}
if utilfeature.DefaultFeatureGate.Enabled(features.AllowUnsafeMalformedObjectDeletion) {
e.corruptObjDeleter = NewCorruptObjectDeleter(e)
}
return nil
}

View File

@ -10,7 +10,8 @@ reviewers:
- mikedanese
- liggitt
- justinsb
- ncdc
- dims
- ingvagabund
- enj
emeritus_reviewers:
- ncdc

View File

@ -22,12 +22,13 @@ import (
"net/http"
"net/url"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
)
//TODO:
@ -387,6 +388,12 @@ type ResetFieldsStrategy interface {
GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set
}
// ResetFieldsFilterStrategy is an optional interface that a storage object can
// implement if it wishes to provide a fields filter reset by its strategies.
type ResetFieldsFilterStrategy interface {
GetResetFieldsFilter() map[fieldpath.APIVersion]fieldpath.Filter
}
// CreateUpdateResetFieldsStrategy is a union of RESTCreateUpdateStrategy
// and ResetFieldsStrategy.
type CreateUpdateResetFieldsStrategy interface {
@ -400,3 +407,10 @@ type UpdateResetFieldsStrategy interface {
RESTUpdateStrategy
ResetFieldsStrategy
}
// CorruptObjectDeleterProvider is an interface the storage implements
// to support unsafe deletion of corrupt object(s). It returns a
// GracefulDeleter that is used to perform unsafe deletion of corrupt object(s).
type CorruptObjectDeleterProvider interface {
GetCorruptObjDeleter() GracefulDeleter
}