@@ -8,13 +8,16 @@ import (
88 metainternal "k8s.io/apimachinery/pkg/apis/meta/internalversion"
99 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010 "k8s.io/apimachinery/pkg/runtime"
11+ "k8s.io/apimachinery/pkg/util/wait"
1112 "k8s.io/apimachinery/pkg/watch"
1213 apirequest "k8s.io/apiserver/pkg/endpoints/request"
1314 "k8s.io/apiserver/pkg/registry/rest"
1415 corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
1516 "k8s.io/kubernetes/pkg/printers"
1617 printerstorage "k8s.io/kubernetes/pkg/printers/storage"
1718
19+ "k8s.io/klog/v2"
20+
1821 "github.com/openshift/api/project"
1922 "github.com/openshift/apiserver-library-go/pkg/authorization/scope"
2023 "github.com/openshift/openshift-apiserver/pkg/api/apihelpers"
@@ -208,32 +211,53 @@ func (s *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje
208211
209212var _ = rest .GracefulDeleter (& REST {})
210213
214+ // maxRetriesOnConflict is the maximum retry count for Delete calls which
215+ // result in resource conflicts.
216+ const maxRetriesOnConflict = 10
217+
211218// Delete deletes a Project specified by its name
212219func (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 )
213221 var opts metav1.DeleteOptions
214222 if options != nil {
215223 opts = * options
216224 }
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 )
236254 }
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
237261 }
238- return & metav1.Status {Status : metav1 .StatusSuccess }, false , s . client . Delete ( ctx , name , opts )
262+ return & metav1.Status {Status : metav1 .StatusSuccess }, false , nil
239263}
0 commit comments