mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
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:
3
vendor/k8s.io/apiserver/pkg/registry/generic/OWNERS
generated
vendored
3
vendor/k8s.io/apiserver/pkg/registry/generic/OWNERS
generated
vendored
@ -13,6 +13,7 @@ reviewers:
|
||||
- saad-ali
|
||||
- janetkuo
|
||||
- pwittrock
|
||||
- ncdc
|
||||
- dims
|
||||
- enj
|
||||
emeritus_reviewers:
|
||||
- ncdc
|
||||
|
122
vendor/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go
generated
vendored
Normal file
122
vendor/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go
generated
vendored
Normal 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
|
||||
}
|
4
vendor/k8s.io/apiserver/pkg/registry/generic/registry/dryrun.go
generated
vendored
4
vendor/k8s.io/apiserver/pkg/registry/generic/registry/dryrun.go
generated
vendored
@ -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) {
|
||||
|
27
vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go
generated
vendored
27
vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go
generated
vendored
@ -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
|
||||
}
|
||||
|
||||
|
3
vendor/k8s.io/apiserver/pkg/registry/rest/OWNERS
generated
vendored
3
vendor/k8s.io/apiserver/pkg/registry/rest/OWNERS
generated
vendored
@ -10,7 +10,8 @@ reviewers:
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- justinsb
|
||||
- ncdc
|
||||
- dims
|
||||
- ingvagabund
|
||||
- enj
|
||||
emeritus_reviewers:
|
||||
- ncdc
|
||||
|
16
vendor/k8s.io/apiserver/pkg/registry/rest/rest.go
generated
vendored
16
vendor/k8s.io/apiserver/pkg/registry/rest/rest.go
generated
vendored
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user