@@ -60,6 +60,9 @@ const (
60
60
uninstallFinalizer = "helm.sdk.operatorframework.io/uninstall-release"
61
61
// Deprecated: use uninstallFinalizer. This will be removed in operator-sdk v2.0.0.
62
62
uninstallFinalizerLegacy = "uninstall-helm-release"
63
+
64
+ helmUpgradeForceAnnotation = "helm.sdk.operatorframework.io/upgrade-force"
65
+ helmUninstallWaitAnnotation = "helm.sdk.operatorframework.io/uninstall-wait"
63
66
)
64
67
65
68
// Reconcile reconciles the requested resource by installing, updating, or
@@ -122,25 +125,58 @@ func (r HelmOperatorReconciler) Reconcile(ctx context.Context, request reconcile
122
125
}
123
126
status .RemoveCondition (types .ConditionReleaseFailed )
124
127
128
+ wait := hasAnnotation (helmUninstallWaitAnnotation , o )
125
129
if errors .Is (err , driver .ErrReleaseNotFound ) {
126
- log .Info ("Release not found, removing finalizer " )
130
+ log .Info ("Release not found" )
127
131
} else {
128
132
log .Info ("Uninstalled release" )
129
133
if log .V (0 ).Enabled () && uninstalledRelease != nil {
130
134
fmt .Println (diff .Generate (uninstalledRelease .Manifest , "" ))
131
135
}
136
+ if ! wait {
137
+ status .SetCondition (types.HelmAppCondition {
138
+ Type : types .ConditionDeployed ,
139
+ Status : types .StatusFalse ,
140
+ Reason : types .ReasonUninstallSuccessful ,
141
+ })
142
+ status .DeployedRelease = nil
143
+ }
144
+ }
145
+ if wait {
132
146
status .SetCondition (types.HelmAppCondition {
133
- Type : types .ConditionDeployed ,
134
- Status : types .StatusFalse ,
135
- Reason : types .ReasonUninstallSuccessful ,
147
+ Type : types .ConditionDeployed ,
148
+ Status : types .StatusFalse ,
149
+ Reason : types .ReasonUninstallSuccessful ,
150
+ Message : "Waiting until all resources are deleted." ,
136
151
})
137
- status .DeployedRelease = nil
138
152
}
139
153
if err := r .updateResourceStatus (ctx , o , status ); err != nil {
140
154
log .Info ("Failed to update CR status" )
141
155
return reconcile.Result {}, err
142
156
}
143
157
158
+ if wait && status .DeployedRelease != nil && status .DeployedRelease .Manifest != "" {
159
+ log .Info ("Uninstall wait" )
160
+ isAllResourcesDeleted , err := manager .CleanupRelease (ctx , status .DeployedRelease .Manifest )
161
+ if err != nil {
162
+ log .Error (err , "Failed to cleanup release" )
163
+ status .SetCondition (types.HelmAppCondition {
164
+ Type : types .ConditionReleaseFailed ,
165
+ Status : types .StatusTrue ,
166
+ Reason : types .ReasonUninstallError ,
167
+ Message : err .Error (),
168
+ })
169
+ _ = r .updateResourceStatus (ctx , o , status )
170
+ return reconcile.Result {}, err
171
+ }
172
+ if ! isAllResourcesDeleted {
173
+ log .Info ("Waiting until all resources are deleted" )
174
+ return reconcile.Result {RequeueAfter : r .ReconcilePeriod }, nil
175
+ }
176
+ status .RemoveCondition (types .ConditionReleaseFailed )
177
+ }
178
+
179
+ log .Info ("Removing finalizer" )
144
180
controllerutil .RemoveFinalizer (o , uninstallFinalizer )
145
181
controllerutil .RemoveFinalizer (o , uninstallFinalizerLegacy )
146
182
if err := r .updateResource (ctx , o ); err != nil {
@@ -254,7 +290,7 @@ func (r HelmOperatorReconciler) Reconcile(ctx context.Context, request reconcile
254
290
r .EventRecorder .Eventf (o , "Warning" , "OverrideValuesInUse" ,
255
291
"Chart value %q overridden to %q by operator's watches.yaml" , k , v )
256
292
}
257
- force := hasHelmUpgradeForceAnnotation ( o )
293
+ force := hasAnnotation ( helmUpgradeForceAnnotation , o )
258
294
previousRelease , upgradedRelease , err := manager .UpgradeRelease (ctx , release .ForceUpgrade (force ))
259
295
if err != nil {
260
296
log .Error (err , "Release failed" )
@@ -357,16 +393,15 @@ func (r HelmOperatorReconciler) Reconcile(ctx context.Context, request reconcile
357
393
358
394
// returns the boolean representation of the annotation string
359
395
// will return false if annotation is not set
360
- func hasHelmUpgradeForceAnnotation (o * unstructured.Unstructured ) bool {
361
- const helmUpgradeForceAnnotation = "helm.sdk.operatorframework.io/upgrade-force"
362
- force := o .GetAnnotations ()[helmUpgradeForceAnnotation ]
363
- if force == "" {
396
+ func hasAnnotation (anno string , o * unstructured.Unstructured ) bool {
397
+ boolStr := o .GetAnnotations ()[anno ]
398
+ if boolStr == "" {
364
399
return false
365
400
}
366
401
value := false
367
- if i , err := strconv .ParseBool (force ); err != nil {
402
+ if i , err := strconv .ParseBool (boolStr ); err != nil {
368
403
log .Info ("Could not parse annotation as a boolean" ,
369
- "annotation" , helmUpgradeForceAnnotation , "value informed" , force )
404
+ "annotation" , anno , "value informed" , boolStr )
370
405
} else {
371
406
value = i
372
407
}
0 commit comments