@@ -127,14 +127,14 @@ func (r *ExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alpha1.Ext
127
127
if ! features .OperatorControllerFeatureGate .Enabled (features .EnableExtensionAPI ) {
128
128
l .Info ("extension feature is gated" , "name" , ext .GetName (), "namespace" , ext .GetNamespace ())
129
129
130
- // Set the TypeInstalled condition to Unknown to indicate that the resolution
130
+ // Set the TypeInstalled condition to Failed to indicate that the resolution
131
131
// hasn't been attempted yet, due to the spec being invalid.
132
132
ext .Status .InstalledBundle = nil
133
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , "extension feature is disabled" , ext .GetGeneration ())
134
- // Set the TypeResolved condition to Unknown to indicate that the resolution
133
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , "extension feature is disabled" , ext .GetGeneration ())
134
+ // Set the TypeResolved condition to Failed to indicate that the resolution
135
135
// hasn't been attempted yet, due to the spec being invalid.
136
136
ext .Status .ResolvedBundle = nil
137
- setResolvedStatusConditionUnknown (& ext .Status .Conditions , "extension feature is disabled" , ext .GetGeneration ())
137
+ setResolvedStatusConditionFailed (& ext .Status .Conditions , "extension feature is disabled" , ext .GetGeneration ())
138
138
139
139
setDeprecationStatusesUnknown (& ext .Status .Conditions , "extension feature is disabled" , ext .GetGeneration ())
140
140
return ctrl.Result {}, nil
@@ -150,8 +150,10 @@ func (r *ExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alpha1.Ext
150
150
// TODO: Improve the resolution logic.
151
151
bundle , err := r .resolve (ctx , * ext )
152
152
if err != nil {
153
- ext .Status .InstalledBundle = nil
154
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , "installation has not been attempted as resolution failed" , ext .GetGeneration ())
153
+ if c := apimeta .FindStatusCondition (ext .Status .Conditions , ocv1alpha1 .TypeInstalled ); c == nil {
154
+ ext .Status .InstalledBundle = nil
155
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , "installation has not been attempted as resolution failed" , ext .GetGeneration ())
156
+ }
155
157
ext .Status .ResolvedBundle = nil
156
158
setResolvedStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
157
159
setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as resolution failed" , ext .GetGeneration ())
@@ -164,33 +166,46 @@ func (r *ExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alpha1.Ext
164
166
165
167
mediaType , err := bundle .MediaType ()
166
168
if err != nil {
167
- setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
168
- setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
169
+ if c := apimeta .FindStatusCondition (ext .Status .Conditions , ocv1alpha1 .TypeInstalled ); c == nil {
170
+ ext .Status .InstalledBundle = nil
171
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("failed to read bundle mediaType: %v" , err ), ext .GetGeneration ())
172
+ setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
173
+ }
174
+ setProgressingStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("failed to read bundle mediaType: %v" , err ), ext .GetGeneration ())
169
175
return ctrl.Result {}, err
170
176
}
171
177
172
178
// TODO: this needs to include the registryV1 bundle option. As of this PR, this only supports direct
173
179
// installation of a set of manifests.
174
180
if mediaType != catalogmetadata .MediaTypePlain {
175
- // Set the TypeInstalled condition to Unknown to indicate that the resolution
176
- // hasn't been attempted yet, due to the spec being invalid.
177
- ext .Status .InstalledBundle = nil
178
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , fmt .Sprintf ("bundle type %s not supported currently" , mediaType ), ext .GetGeneration ())
179
- setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
181
+ if c := apimeta .FindStatusCondition (ext .Status .Conditions , ocv1alpha1 .TypeInstalled ); c == nil {
182
+ // Set the TypeInstalled condition to Failed to indicate that the resolution
183
+ // hasn't been attempted yet, due to the spec being invalid.
184
+ ext .Status .InstalledBundle = nil
185
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("bundle type %s not supported currently" , mediaType ), ext .GetGeneration ())
186
+ setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
187
+ }
188
+ setProgressingStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("bundle type %s not supported currently" , mediaType ), ext .GetGeneration ())
180
189
return ctrl.Result {}, nil
181
190
}
182
191
183
192
app , err := r .GenerateExpectedApp (* ext , bundle )
184
193
if err != nil {
185
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
186
- setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
194
+ if c := apimeta .FindStatusCondition (ext .Status .Conditions , ocv1alpha1 .TypeInstalled ); c == nil {
195
+ ext .Status .InstalledBundle = nil
196
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
197
+ setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
198
+ }
199
+ setProgressingStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
187
200
return ctrl.Result {}, err
188
201
}
189
202
190
203
if err := r .ensureApp (ctx , app ); err != nil {
191
204
// originally Reason: ocv1alpha1.ReasonInstallationFailed
192
205
ext .Status .InstalledBundle = nil
193
206
setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
207
+ setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
208
+ setProgressingStatusConditionProgressing (& ext .Status .Conditions , "installation failed" , ext .GetGeneration ())
194
209
return ctrl.Result {}, err
195
210
}
196
211
@@ -199,14 +214,19 @@ func (r *ExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alpha1.Ext
199
214
if err := runtime .DefaultUnstructuredConverter .FromUnstructured (app .UnstructuredContent (), existingTypedApp ); err != nil {
200
215
// originally Reason: ocv1alpha1.ReasonInstallationStatusUnknown
201
216
ext .Status .InstalledBundle = nil
202
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
217
+ setInstalledStatusConditionFailed (& ext .Status .Conditions , err .Error (), ext .GetGeneration ())
203
218
setDeprecationStatusesUnknown (& ext .Status .Conditions , "deprecation checks have not been attempted as installation has failed" , ext .GetGeneration ())
219
+ setProgressingStatusConditionProgressing (& ext .Status .Conditions , "installation failed" , ext .GetGeneration ())
204
220
return ctrl.Result {}, err
205
221
}
206
222
207
- mapAppStatusToInstalledCondition (existingTypedApp , ext , bundle )
223
+ ext .Status .InstalledBundle = bundleMetadataFor (bundle )
224
+ setInstalledStatusConditionSuccess (& ext .Status .Conditions , fmt .Sprintf ("successfully installed %v" , ext .Status .InstalledBundle ), ext .GetGeneration ())
208
225
SetDeprecationStatusInExtension (ext , bundle )
209
226
227
+ // TODO: add conditions to determine extension health
228
+ mapAppStatusToCondition (existingTypedApp , ext )
229
+
210
230
return ctrl.Result {}, nil
211
231
}
212
232
@@ -228,28 +248,37 @@ func (r *ExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
228
248
Complete (r )
229
249
}
230
250
231
- // TODO: follow up with mapping of all the available App statuses: https://github.com/carvel-dev/kapp-controller/blob/855063edee53315811a13ee8d5df1431ba258ede/pkg/apis/kappctrl/v1alpha1/status.go#L28-L35
232
- // mapAppStatusToInstalledCondition currently maps only the installed condition.
233
- func mapAppStatusToInstalledCondition (existingApp * kappctrlv1alpha1.App , ext * ocv1alpha1.Extension , bundle * catalogmetadata.Bundle ) {
234
- appReady := findStatusCondition (existingApp .Status .GenericStatus .Conditions , kappctrlv1alpha1 .ReconcileSucceeded )
235
- if appReady == nil {
236
- ext .Status .InstalledBundle = nil
237
- setInstalledStatusConditionUnknown (& ext .Status .Conditions , "install status unknown" , ext .Generation )
251
+ // mapAppStatusToCondition maps the reconciling/deleting App conditions to the installed/deleting conditions on the Extension.
252
+ func mapAppStatusToCondition (existingApp * kappctrlv1alpha1.App , ext * ocv1alpha1.Extension ) {
253
+ // Note: App.Status.Inspect errors are never surfaced to App conditions, so are currently ignored when determining App status.
254
+ if ext == nil || existingApp == nil {
238
255
return
239
256
}
240
-
241
- if appReady .Status != corev1 .ConditionTrue {
242
- ext .Status .InstalledBundle = nil
243
- setInstalledStatusConditionFailed (
244
- & ext .Status .Conditions ,
245
- appReady .Message ,
246
- ext .GetGeneration (),
247
- )
248
- return
257
+ message := existingApp .Status .FriendlyDescription
258
+ if len (message ) == 0 || strings .Contains (message , "Error (see .status.usefulErrorMessage for details)" ) {
259
+ message = existingApp .Status .UsefulErrorMessage
249
260
}
250
261
251
- ext .Status .InstalledBundle = bundleMetadataFor (bundle )
252
- setInstalledStatusConditionSuccess (& ext .Status .Conditions , appReady .Message , ext .Generation )
262
+ appStatusMapFn := map [kappctrlv1alpha1.ConditionType ]func (* []metav1.Condition , string , int64 ){
263
+ kappctrlv1alpha1 .Deleting : setProgressingStatusConditionProgressing ,
264
+ kappctrlv1alpha1 .Reconciling : setProgressingStatusConditionProgressing ,
265
+ kappctrlv1alpha1 .DeleteFailed : setProgressingStatusConditionFailed ,
266
+ kappctrlv1alpha1 .ReconcileFailed : setProgressingStatusConditionFailed ,
267
+ kappctrlv1alpha1 .ReconcileSucceeded : setProgressingStatusConditionSuccess ,
268
+ }
269
+ for cond := range appStatusMapFn {
270
+ if c := findStatusCondition (existingApp .Status .GenericStatus .Conditions , cond ); c != nil && c .Status == corev1 .ConditionTrue {
271
+ if len (message ) == 0 {
272
+ message = c .Message
273
+ }
274
+ appStatusMapFn [cond ](& ext .Status .Conditions , fmt .Sprintf ("App %s: %s" , c .Type , message ), ext .Generation )
275
+ return
276
+ }
277
+ }
278
+ if len (message ) == 0 {
279
+ message = "waiting for app"
280
+ }
281
+ setProgressingStatusConditionProgressing (& ext .Status .Conditions , message , ext .Generation )
253
282
}
254
283
255
284
// setDeprecationStatus will set the appropriate deprecation statuses for a Extension
0 commit comments