@@ -8,13 +8,16 @@ import (
8
8
metainternal "k8s.io/apimachinery/pkg/apis/meta/internalversion"
9
9
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10
10
"k8s.io/apimachinery/pkg/runtime"
11
+ "k8s.io/apimachinery/pkg/util/wait"
11
12
"k8s.io/apimachinery/pkg/watch"
12
13
apirequest "k8s.io/apiserver/pkg/endpoints/request"
13
14
"k8s.io/apiserver/pkg/registry/rest"
14
15
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
15
16
"k8s.io/kubernetes/pkg/printers"
16
17
printerstorage "k8s.io/kubernetes/pkg/printers/storage"
17
18
19
+ "k8s.io/klog/v2"
20
+
18
21
"github.com/openshift/api/project"
19
22
"github.com/openshift/apiserver-library-go/pkg/authorization/scope"
20
23
"github.com/openshift/openshift-apiserver/pkg/api/apihelpers"
@@ -208,32 +211,53 @@ func (s *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje
208
211
209
212
var _ = rest .GracefulDeleter (& REST {})
210
213
214
+ // maxRetriesOnConflict is the maximum retry count for Delete calls which
215
+ // result in resource conflicts.
216
+ const maxRetriesOnConflict = 10
217
+
211
218
// Delete deletes a Project specified by its name
212
219
func (s * REST ) Delete (ctx context.Context , name string , objectFunc rest.ValidateObjectFunc , options * metav1.DeleteOptions ) (runtime.Object , bool , error ) {
220
+ klog .V (2 ).Infof ("Project delete name=%s: start" , name )
213
221
var opts metav1.DeleteOptions
214
222
if options != nil {
215
223
opts = * options
216
224
}
217
- if objectFunc != nil {
218
- obj , err := s .Get (ctx , name , & metav1.GetOptions {})
219
- if err != nil {
220
- return nil , false , err
221
- }
222
- projectObj , ok := obj .(* projectapi.Project )
223
- if ! ok || projectObj == nil {
224
- return nil , false , fmt .Errorf ("not a project: %#v" , obj )
225
- }
226
-
227
- // Make sure the object hasn't changed between Get and Delete - pass UID and RV to delete options
228
- if opts .Preconditions == nil {
229
- opts .Preconditions = & metav1.Preconditions {}
230
- }
231
- opts .Preconditions .UID = & projectObj .UID
232
- opts .Preconditions .ResourceVersion = & projectObj .ResourceVersion
233
-
234
- if err := objectFunc (ctx , obj ); err != nil {
235
- return nil , false , err
225
+ attempt := 0
226
+ err := wait .ExponentialBackoffWithContext (ctx , wait.Backoff {Steps : maxRetriesOnConflict }, func (ctx context.Context ) (bool , error ) {
227
+ attempt = attempt + 1
228
+ klog .V (2 ).Infof ("Project delete name=%s: attempt %d" , name , attempt )
229
+ if objectFunc != nil {
230
+ klog .V (2 ).Infof ("Project delete name=%s: validation func=%#v" , name , objectFunc )
231
+ obj , err := s .Get (ctx , name , & metav1.GetOptions {})
232
+ if err != nil {
233
+ klog .V (2 ).Infof ("Project delete name=%s: unable to get project: %#v" , name , err )
234
+ return false , fmt .Errorf ("unable to get project: %w" , err )
235
+ }
236
+ projectObj , ok := obj .(* projectapi.Project )
237
+ if ! ok || projectObj == nil {
238
+ klog .V (2 ).Infof ("Project delete name=%s: not a project: %#v" , name , err )
239
+ return false , fmt .Errorf ("not a project: %#v" , obj )
240
+ }
241
+
242
+ // Make sure the object hasn't changed between Get and Delete - pass UID and RV to delete options
243
+ if opts .Preconditions == nil {
244
+ opts .Preconditions = & metav1.Preconditions {}
245
+ }
246
+ opts .Preconditions .UID = & projectObj .UID
247
+ opts .Preconditions .ResourceVersion = & projectObj .ResourceVersion
248
+
249
+ if err := objectFunc (ctx , obj ); err != nil {
250
+ klog .V (2 ).Infof ("Project delete name=%s: validation func failed: %#v" , name , err )
251
+ return false , fmt .Errorf ("validation func failed: %w" , err )
252
+ }
253
+ klog .V (2 ).Infof ("Project delete name=%s: objectFunc validation complete" , name )
236
254
}
255
+ err := s .client .Delete (ctx , name , opts )
256
+ klog .V (2 ).Infof ("Project delete name=%s: complete err=%v" , name , err )
257
+ return err == nil , err
258
+ })
259
+ if err != nil {
260
+ return nil , false , err
237
261
}
238
- return & metav1.Status {Status : metav1 .StatusSuccess }, false , s . client . Delete ( ctx , name , opts )
262
+ return & metav1.Status {Status : metav1 .StatusSuccess }, false , nil
239
263
}
0 commit comments