@@ -16,14 +16,17 @@ package controller
16
16
17
17
import (
18
18
"context"
19
+ "errors"
19
20
"fmt"
20
21
"time"
21
22
22
23
rpb "helm.sh/helm/v3/pkg/release"
24
+ "helm.sh/helm/v3/pkg/storage/driver"
23
25
apierrors "k8s.io/apimachinery/pkg/api/errors"
24
26
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25
27
"k8s.io/apimachinery/pkg/runtime"
26
28
"k8s.io/apimachinery/pkg/runtime/schema"
29
+ "k8s.io/apimachinery/pkg/util/wait"
27
30
"k8s.io/client-go/tools/record"
28
31
"sigs.k8s.io/controller-runtime/pkg/client"
29
32
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -126,7 +129,7 @@ func (r HelmOperatorReconciler) Reconcile(request reconcile.Request) (reconcile.
126
129
}
127
130
128
131
uninstalledRelease , err := manager .UninstallRelease (context .TODO ())
129
- if err != nil && err != release . ErrNotFound {
132
+ if err != nil && ! errors . Is ( err , driver . ErrReleaseNotFound ) {
130
133
log .Error (err , "Failed to uninstall release" )
131
134
status .SetCondition (types.HelmAppCondition {
132
135
Type : types .ConditionReleaseFailed ,
@@ -139,7 +142,7 @@ func (r HelmOperatorReconciler) Reconcile(request reconcile.Request) (reconcile.
139
142
}
140
143
status .RemoveCondition (types .ConditionReleaseFailed )
141
144
142
- if err == release . ErrNotFound {
145
+ if errors . Is ( err , driver . ErrReleaseNotFound ) {
143
146
log .Info ("Release not found, removing finalizer" )
144
147
} else {
145
148
log .Info ("Uninstalled release" )
@@ -154,6 +157,7 @@ func (r HelmOperatorReconciler) Reconcile(request reconcile.Request) (reconcile.
154
157
status .DeployedRelease = nil
155
158
}
156
159
if err := r .updateResourceStatus (o , status ); err != nil {
160
+ log .Info ("Failed to update CR status" )
157
161
return reconcile.Result {}, err
158
162
}
159
163
@@ -164,10 +168,21 @@ func (r HelmOperatorReconciler) Reconcile(request reconcile.Request) (reconcile.
164
168
}
165
169
}
166
170
o .SetFinalizers (finalizers )
167
- err = r .updateResource (o )
171
+ if err := r .updateResource (o ); err != nil {
172
+ log .Info ("Failed to remove CR uninstall finalizer" )
173
+ return reconcile.Result {}, err
174
+ }
168
175
169
- // Need to requeue because finalizer update does not change metadata.generation
170
- return reconcile.Result {Requeue : true }, err
176
+ // Since the client is hitting a cache, waiting for the
177
+ // deletion here will guarantee that the next reconciliation
178
+ // will see that the CR has been deleted and that there's
179
+ // nothing left to do.
180
+ if err := r .waitForDeletion (o ); err != nil {
181
+ log .Info ("Failed waiting for CR deletion" )
182
+ return reconcile.Result {}, err
183
+ }
184
+
185
+ return reconcile.Result {}, nil
171
186
}
172
187
173
188
if ! manager .IsInstalled () {
@@ -313,6 +328,26 @@ func (r HelmOperatorReconciler) updateResourceStatus(o *unstructured.Unstructure
313
328
return r .Client .Status ().Update (context .TODO (), o )
314
329
}
315
330
331
+ func (r HelmOperatorReconciler ) waitForDeletion (o runtime.Object ) error {
332
+ key , err := client .ObjectKeyFromObject (o )
333
+ if err != nil {
334
+ return err
335
+ }
336
+
337
+ ctx , cancel := context .WithTimeout (context .Background (), time .Second * 5 )
338
+ defer cancel ()
339
+ return wait .PollImmediateUntil (time .Millisecond * 10 , func () (bool , error ) {
340
+ err := r .Client .Get (ctx , key , o )
341
+ if apierrors .IsNotFound (err ) {
342
+ return true , nil
343
+ }
344
+ if err != nil {
345
+ return false , err
346
+ }
347
+ return false , nil
348
+ }, ctx .Done ())
349
+ }
350
+
316
351
func contains (l []string , s string ) bool {
317
352
for _ , elem := range l {
318
353
if elem == s {
0 commit comments