mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Add suggestion to storage interface Delete method
This commit is contained in:
parent
e1c617a88e
commit
c2d61896f4
@ -113,7 +113,7 @@ func (s *storageLeases) UpdateLease(ip string) error {
|
|||||||
|
|
||||||
// RemoveLease removes the lease on a master IP in storage
|
// RemoveLease removes the lease on a master IP in storage
|
||||||
func (s *storageLeases) RemoveLease(ip string) error {
|
func (s *storageLeases) RemoveLease(ip string) error {
|
||||||
return s.storage.Delete(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &corev1.Endpoints{}, nil, rest.ValidateAllObjectFunc)
|
return s.storage.Delete(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &corev1.Endpoints{}, nil, rest.ValidateAllObjectFunc, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLeases creates a new etcd-based Leases implementation.
|
// NewLeases creates a new etcd-based Leases implementation.
|
||||||
|
@ -159,7 +159,7 @@ type FailDeletionStorage struct {
|
|||||||
Called *bool
|
Called *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FailDeletionStorage) Delete(ctx context.Context, key string, out runtime.Object, precondition *apiserverstorage.Preconditions, _ apiserverstorage.ValidateObjectFunc) error {
|
func (f FailDeletionStorage) Delete(_ context.Context, key string, _ runtime.Object, _ *apiserverstorage.Preconditions, _ apiserverstorage.ValidateObjectFunc, _ runtime.Object) error {
|
||||||
*f.Called = true
|
*f.Called = true
|
||||||
return apiserverstorage.NewKeyNotFoundError(key, 0)
|
return apiserverstorage.NewKeyNotFoundError(key, 0)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ func (s *DryRunnableStorage) Create(ctx context.Context, key string, obj, out ru
|
|||||||
return s.Storage.Create(ctx, key, obj, out, ttl)
|
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) error {
|
func (s *DryRunnableStorage) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, deleteValidation storage.ValidateObjectFunc, dryRun bool, cachedExistingObject runtime.Object) error {
|
||||||
if dryRun {
|
if dryRun {
|
||||||
if err := s.Storage.Get(ctx, key, storage.GetOptions{}, out); err != nil {
|
if err := s.Storage.Get(ctx, key, storage.GetOptions{}, out); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -53,7 +53,7 @@ func (s *DryRunnableStorage) Delete(ctx context.Context, key string, out runtime
|
|||||||
}
|
}
|
||||||
return deleteValidation(ctx, out)
|
return deleteValidation(ctx, out)
|
||||||
}
|
}
|
||||||
return s.Storage.Delete(ctx, key, out, preconditions, deleteValidation)
|
return s.Storage.Delete(ctx, key, out, preconditions, deleteValidation, cachedExistingObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DryRunnableStorage) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) {
|
func (s *DryRunnableStorage) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) {
|
||||||
|
@ -234,7 +234,7 @@ func TestDryRunDeleteDoesntDelete(t *testing.T) {
|
|||||||
t.Fatalf("Failed to create new object: %v", err)
|
t.Fatalf("Failed to create new object: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true)
|
err = s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to dry-run delete the object: %v", err)
|
t.Fatalf("Failed to dry-run delete the object: %v", err)
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ func TestDryRunDeleteMissingObjectFails(t *testing.T) {
|
|||||||
defer destroy()
|
defer destroy()
|
||||||
|
|
||||||
out := UnstructuredOrDie(`{}`)
|
out := UnstructuredOrDie(`{}`)
|
||||||
err := s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true)
|
err := s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true, nil)
|
||||||
if e, ok := err.(*storage.StorageError); !ok || e.Code != storage.ErrCodeKeyNotFound {
|
if e, ok := err.(*storage.StorageError); !ok || e.Code != storage.ErrCodeKeyNotFound {
|
||||||
t.Errorf("Expected key to be not found, error: %v", err)
|
t.Errorf("Expected key to be not found, error: %v", err)
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ func TestDryRunDeleteReturnsObject(t *testing.T) {
|
|||||||
|
|
||||||
out = UnstructuredOrDie(`{}`)
|
out = UnstructuredOrDie(`{}`)
|
||||||
expected := UnstructuredOrDie(`{"kind": "Pod", "metadata": {"resourceVersion": "2"}}`)
|
expected := UnstructuredOrDie(`{"kind": "Pod", "metadata": {"resourceVersion": "2"}}`)
|
||||||
err = s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true)
|
err = s.Delete(context.Background(), "key", out, nil, rest.ValidateAllObjectFunc, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to delete with valid precondition: %v", err)
|
t.Fatalf("Failed to delete with valid precondition: %v", err)
|
||||||
}
|
}
|
||||||
@ -293,12 +293,12 @@ func TestDryRunDeletePreconditions(t *testing.T) {
|
|||||||
|
|
||||||
wrongID := types.UID("wrong-uid")
|
wrongID := types.UID("wrong-uid")
|
||||||
myID := types.UID("my-uid")
|
myID := types.UID("my-uid")
|
||||||
err = s.Delete(context.Background(), "key", out, &storage.Preconditions{UID: &wrongID}, rest.ValidateAllObjectFunc, true)
|
err = s.Delete(context.Background(), "key", out, &storage.Preconditions{UID: &wrongID}, rest.ValidateAllObjectFunc, true, nil)
|
||||||
if e, ok := err.(*storage.StorageError); !ok || e.Code != storage.ErrCodeInvalidObj {
|
if e, ok := err.(*storage.StorageError); !ok || e.Code != storage.ErrCodeInvalidObj {
|
||||||
t.Errorf("Expected invalid object, error: %v", err)
|
t.Errorf("Expected invalid object, error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Delete(context.Background(), "key", out, &storage.Preconditions{UID: &myID}, rest.ValidateAllObjectFunc, true)
|
err = s.Delete(context.Background(), "key", out, &storage.Preconditions{UID: &myID}, rest.ValidateAllObjectFunc, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to delete with valid precondition: %v", err)
|
t.Fatalf("Failed to delete with valid precondition: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -428,7 +428,7 @@ func (e *Store) deleteWithoutFinalizers(ctx context.Context, name, key string, o
|
|||||||
out := e.NewFunc()
|
out := e.NewFunc()
|
||||||
klog.V(6).Infof("going to delete %s from registry, triggered by update", name)
|
klog.V(6).Infof("going to delete %s from registry, triggered by update", name)
|
||||||
// Using the rest.ValidateAllObjectFunc because the request is an UPDATE request and has already passed the admission for the UPDATE verb.
|
// 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); err != nil {
|
if err := e.Storage.Delete(ctx, key, out, preconditions, rest.ValidateAllObjectFunc, dryRun, nil); err != nil {
|
||||||
// Deletion is racy, i.e., there could be multiple update
|
// Deletion is racy, i.e., there could be multiple update
|
||||||
// requests to remove all finalizers from the object, so we
|
// requests to remove all finalizers from the object, so we
|
||||||
// ignore the NotFound error.
|
// ignore the NotFound error.
|
||||||
@ -963,7 +963,7 @@ func (e *Store) Delete(ctx context.Context, name string, deleteValidation rest.V
|
|||||||
// delete immediately, or no graceful deletion supported
|
// delete immediately, or no graceful deletion supported
|
||||||
klog.V(6).Infof("going to delete %s from registry: ", name)
|
klog.V(6).Infof("going to delete %s from registry: ", name)
|
||||||
out = e.NewFunc()
|
out = e.NewFunc()
|
||||||
if err := e.Storage.Delete(ctx, key, out, &preconditions, storage.ValidateObjectFunc(deleteValidation), dryrun.IsDryRun(options.DryRun)); err != nil {
|
if err := e.Storage.Delete(ctx, key, out, &preconditions, storage.ValidateObjectFunc(deleteValidation), dryrun.IsDryRun(options.DryRun), nil); err != nil {
|
||||||
// Please refer to the place where we set ignoreNotFound for the reason
|
// Please refer to the place where we set ignoreNotFound for the reason
|
||||||
// why we ignore the NotFound error .
|
// why we ignore the NotFound error .
|
||||||
if storage.IsNotFound(err) && ignoreNotFound && lastExisting != nil {
|
if storage.IsNotFound(err) && ignoreNotFound && lastExisting != nil {
|
||||||
|
@ -431,8 +431,10 @@ func (c *Cacher) Create(ctx context.Context, key string, obj, out runtime.Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete implements storage.Interface.
|
// Delete implements storage.Interface.
|
||||||
func (c *Cacher) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, validateDeletion storage.ValidateObjectFunc) error {
|
func (c *Cacher) Delete(
|
||||||
return c.storage.Delete(ctx, key, out, preconditions, validateDeletion)
|
ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions,
|
||||||
|
validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error {
|
||||||
|
return c.storage.Delete(ctx, key, out, preconditions, validateDeletion, cachedExistingObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch implements storage.Interface.
|
// Watch implements storage.Interface.
|
||||||
|
@ -299,7 +299,7 @@ func (d *dummyStorage) Versioner() storage.Versioner { return nil }
|
|||||||
func (d *dummyStorage) Create(_ context.Context, _ string, _, _ runtime.Object, _ uint64) error {
|
func (d *dummyStorage) Create(_ context.Context, _ string, _, _ runtime.Object, _ uint64) error {
|
||||||
return fmt.Errorf("unimplemented")
|
return fmt.Errorf("unimplemented")
|
||||||
}
|
}
|
||||||
func (d *dummyStorage) Delete(_ context.Context, _ string, _ runtime.Object, _ *storage.Preconditions, _ storage.ValidateObjectFunc) error {
|
func (d *dummyStorage) Delete(_ context.Context, _ string, _ runtime.Object, _ *storage.Preconditions, _ storage.ValidateObjectFunc, _ runtime.Object) error {
|
||||||
return fmt.Errorf("unimplemented")
|
return fmt.Errorf("unimplemented")
|
||||||
}
|
}
|
||||||
func (d *dummyStorage) Watch(_ context.Context, _ string, _ storage.ListOptions) (watch.Interface, error) {
|
func (d *dummyStorage) Watch(_ context.Context, _ string, _ storage.ListOptions) (watch.Interface, error) {
|
||||||
|
@ -185,16 +185,20 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete implements storage.Interface.Delete.
|
// Delete implements storage.Interface.Delete.
|
||||||
func (s *store) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, validateDeletion storage.ValidateObjectFunc) error {
|
func (s *store) Delete(
|
||||||
|
ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions,
|
||||||
|
validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error {
|
||||||
v, err := conversion.EnforcePtr(out)
|
v, err := conversion.EnforcePtr(out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to convert output object to pointer: %v", err)
|
return fmt.Errorf("unable to convert output object to pointer: %v", err)
|
||||||
}
|
}
|
||||||
key = path.Join(s.pathPrefix, key)
|
key = path.Join(s.pathPrefix, key)
|
||||||
return s.conditionalDelete(ctx, key, out, v, preconditions, validateDeletion)
|
return s.conditionalDelete(ctx, key, out, v, preconditions, validateDeletion, cachedExistingObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.Object, v reflect.Value, preconditions *storage.Preconditions, validateDeletion storage.ValidateObjectFunc) error {
|
func (s *store) conditionalDelete(
|
||||||
|
ctx context.Context, key string, out runtime.Object, v reflect.Value, preconditions *storage.Preconditions,
|
||||||
|
validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
getResp, err := s.client.KV.Get(ctx, key)
|
getResp, err := s.client.KV.Get(ctx, key)
|
||||||
metrics.RecordEtcdRequestLatency("get", getTypeName(out), startTime)
|
metrics.RecordEtcdRequestLatency("get", getTypeName(out), startTime)
|
||||||
|
@ -323,7 +323,7 @@ func TestUnconditionalDelete(t *testing.T) {
|
|||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
out := &example.Pod{} // reset
|
out := &example.Pod{} // reset
|
||||||
err := store.Delete(ctx, tt.key, out, nil, storage.ValidateAllObjectFunc)
|
err := store.Delete(ctx, tt.key, out, nil, storage.ValidateAllObjectFunc, nil)
|
||||||
if tt.expectNotFoundErr {
|
if tt.expectNotFoundErr {
|
||||||
if err == nil || !storage.IsNotFound(err) {
|
if err == nil || !storage.IsNotFound(err) {
|
||||||
t.Errorf("#%d: expecting not found error, but get: %s", i, err)
|
t.Errorf("#%d: expecting not found error, but get: %s", i, err)
|
||||||
@ -357,7 +357,7 @@ func TestConditionalDelete(t *testing.T) {
|
|||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
out := &example.Pod{}
|
out := &example.Pod{}
|
||||||
err := store.Delete(ctx, key, out, tt.precondition, storage.ValidateAllObjectFunc)
|
err := store.Delete(ctx, key, out, tt.precondition, storage.ValidateAllObjectFunc, nil)
|
||||||
if tt.expectInvalidObjErr {
|
if tt.expectInvalidObjErr {
|
||||||
if err == nil || !storage.IsInvalidObj(err) {
|
if err == nil || !storage.IsInvalidObj(err) {
|
||||||
t.Errorf("#%d: expecting invalid UID error, but get: %s", i, err)
|
t.Errorf("#%d: expecting invalid UID error, but get: %s", i, err)
|
||||||
@ -887,7 +887,7 @@ func TestTransformationFailure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete fails with internal error.
|
// Delete fails with internal error.
|
||||||
if err := store.Delete(ctx, preset[1].key, &example.Pod{}, nil, storage.ValidateAllObjectFunc); !storage.IsInternalError(err) {
|
if err := store.Delete(ctx, preset[1].key, &example.Pod{}, nil, storage.ValidateAllObjectFunc, nil); !storage.IsInternalError(err) {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if err := store.Get(ctx, preset[1].key, storage.GetOptions{}, &example.Pod{}); !storage.IsInternalError(err) {
|
if err := store.Get(ctx, preset[1].key, storage.GetOptions{}, &example.Pod{}); !storage.IsInternalError(err) {
|
||||||
@ -1833,7 +1833,7 @@ func testPropogateStoreWithKey(ctx context.Context, t *testing.T, store *store,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic("unable to convert output object to pointer")
|
panic("unable to convert output object to pointer")
|
||||||
}
|
}
|
||||||
err = store.conditionalDelete(ctx, key, &example.Pod{}, v, nil, storage.ValidateAllObjectFunc)
|
err = store.conditionalDelete(ctx, key, &example.Pod{}, v, nil, storage.ValidateAllObjectFunc, nil)
|
||||||
if err != nil && !storage.IsNotFound(err) {
|
if err != nil && !storage.IsNotFound(err) {
|
||||||
t.Fatalf("Cleanup failed: %v", err)
|
t.Fatalf("Cleanup failed: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func TestDeleteTriggerWatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Watch failed: %v", err)
|
t.Fatalf("Watch failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := store.Delete(ctx, key, &example.Pod{}, nil, storage.ValidateAllObjectFunc); err != nil {
|
if err := store.Delete(ctx, key, &example.Pod{}, nil, storage.ValidateAllObjectFunc, nil); err != nil {
|
||||||
t.Fatalf("Delete failed: %v", err)
|
t.Fatalf("Delete failed: %v", err)
|
||||||
}
|
}
|
||||||
testCheckEventType(t, watch.Deleted, w)
|
testCheckEventType(t, watch.Deleted, w)
|
||||||
@ -295,7 +295,7 @@ func TestWatchDeleteEventObjectHaveLatestRV(t *testing.T) {
|
|||||||
}
|
}
|
||||||
etcdW := cluster.RandClient().Watch(ctx, "/", clientv3.WithPrefix())
|
etcdW := cluster.RandClient().Watch(ctx, "/", clientv3.WithPrefix())
|
||||||
|
|
||||||
if err := store.Delete(ctx, key, &example.Pod{}, &storage.Preconditions{}, storage.ValidateAllObjectFunc); err != nil {
|
if err := store.Delete(ctx, key, &example.Pod{}, &storage.Preconditions{}, storage.ValidateAllObjectFunc, nil); err != nil {
|
||||||
t.Fatalf("Delete failed: %v", err)
|
t.Fatalf("Delete failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,12 @@ type Interface interface {
|
|||||||
|
|
||||||
// Delete removes the specified key and returns the value that existed at that spot.
|
// Delete removes the specified key and returns the value that existed at that spot.
|
||||||
// If key didn't exist, it will return NotFound storage error.
|
// If key didn't exist, it will return NotFound storage error.
|
||||||
Delete(ctx context.Context, key string, out runtime.Object, preconditions *Preconditions, validateDeletion ValidateObjectFunc) error
|
// If 'cachedExistingObject' is non-nil, it can be used as a suggestion about the
|
||||||
|
// current version of the object to avoid read operation from storage to get it.
|
||||||
|
// However, the implementations have to retry in case suggestion is stale.
|
||||||
|
Delete(
|
||||||
|
ctx context.Context, key string, out runtime.Object, preconditions *Preconditions,
|
||||||
|
validateDeletion ValidateObjectFunc, cachedExistingObject runtime.Object) error
|
||||||
|
|
||||||
// Watch begins watching the specified key. Events are decoded into API objects,
|
// Watch begins watching the specified key. Events are decoded into API objects,
|
||||||
// and any items selected by 'p' are sent down to returned watch.Interface.
|
// and any items selected by 'p' are sent down to returned watch.Interface.
|
||||||
|
@ -282,7 +282,7 @@ func TestList(t *testing.T) {
|
|||||||
updatePod(t, etcdStorage, podFooNS2, nil)
|
updatePod(t, etcdStorage, podFooNS2, nil)
|
||||||
|
|
||||||
deleted := example.Pod{}
|
deleted := example.Pod{}
|
||||||
if err := etcdStorage.Delete(context.TODO(), "pods/ns/bar", &deleted, nil, storage.ValidateAllObjectFunc); err != nil {
|
if err := etcdStorage.Delete(context.TODO(), "pods/ns/bar", &deleted, nil, storage.ValidateAllObjectFunc, nil); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +575,7 @@ func TestFiltering(t *testing.T) {
|
|||||||
_ = updatePod(t, etcdStorage, podFooPrime, fooUnfiltered)
|
_ = updatePod(t, etcdStorage, podFooPrime, fooUnfiltered)
|
||||||
|
|
||||||
deleted := example.Pod{}
|
deleted := example.Pod{}
|
||||||
if err := etcdStorage.Delete(context.TODO(), "pods/ns/foo", &deleted, nil, storage.ValidateAllObjectFunc); err != nil {
|
if err := etcdStorage.Delete(context.TODO(), "pods/ns/foo", &deleted, nil, storage.ValidateAllObjectFunc, nil); err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user