5
5
"fmt"
6
6
"time"
7
7
8
+ "k8s.io/client-go/tools/record"
9
+
8
10
log "github.com/sirupsen/logrus"
9
11
"k8s.io/api/apps/v1"
10
12
corev1 "k8s.io/api/core/v1"
@@ -21,6 +23,7 @@ import (
21
23
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions"
22
24
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/annotator"
23
25
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
26
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event"
24
27
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
25
28
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
26
29
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
@@ -44,6 +47,7 @@ type Operator struct {
44
47
clusterRoleLister crbacv1.ClusterRoleLister
45
48
clusterRoleBindingLister crbacv1.ClusterRoleBindingLister
46
49
annotator * annotator.Annotator
50
+ recorder record.EventRecorder
47
51
cleanupFunc func ()
48
52
}
49
53
@@ -60,12 +64,17 @@ func NewOperator(crClient versioned.Interface, opClient operatorclient.ClientInt
60
64
return nil , err
61
65
}
62
66
namespaceAnnotator := annotator .NewAnnotator (queueOperator .OpClient , annotations )
67
+ eventRecorder , err := event .NewRecorder (opClient .KubernetesInterface ().CoreV1 ().Events (metav1 .NamespaceAll ))
68
+ if err != nil {
69
+ return nil , err
70
+ }
63
71
64
72
op := & Operator {
65
73
Operator : queueOperator ,
66
74
client : crClient ,
67
75
resolver : resolver ,
68
76
annotator : namespaceAnnotator ,
77
+ recorder : eventRecorder ,
69
78
cleanupFunc : func () {
70
79
namespaceAnnotator .CleanNamespaceAnnotations (namespaces )
71
80
},
@@ -281,8 +290,7 @@ func (a *Operator) syncClusterServiceVersion(obj interface{}) (syncError error)
281
290
return
282
291
}
283
292
284
- // transitionCSVState moves the CSV status state machine along based on the current value and the current cluster
285
- // state.
293
+ // transitionCSVState moves the CSV status state machine along based on the current value and the current cluster state.
286
294
func (a * Operator ) transitionCSVState (in v1alpha1.ClusterServiceVersion ) (out * v1alpha1.ClusterServiceVersion , syncError error ) {
287
295
logger := log .WithFields (log.Fields {
288
296
"csv" : in .GetName (),
@@ -301,31 +309,31 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
301
309
switch out .Status .Phase {
302
310
case v1alpha1 .CSVPhaseNone :
303
311
logger .Infof ("scheduling ClusterServiceVersion for requirement verification" )
304
- out .SetPhase (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonRequirementsUnknown , "requirements not yet checked" )
312
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonRequirementsUnknown , "requirements not yet checked" , a . recorder )
305
313
case v1alpha1 .CSVPhasePending :
306
314
met , statuses , err := a .requirementAndPermissionStatus (out )
307
315
if err != nil {
308
316
logger .Info ("invalid install strategy" )
309
- out .SetPhase (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInvalidStrategy , fmt .Sprintf ("install strategy invalid: %s" , err .Error ()))
317
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonInvalidStrategy , fmt .Sprintf ("install strategy invalid: %s" , err .Error ()), a . recorder )
310
318
return
311
319
}
312
320
out .SetRequirementStatus (statuses )
313
321
314
322
if ! met {
315
323
logger .Info ("requirements were not met" )
316
- out .SetPhase (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonRequirementsNotMet , "one or more requirements couldn't be found" )
324
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhasePending , v1alpha1 .CSVReasonRequirementsNotMet , "one or more requirements couldn't be found" , a . recorder )
317
325
syncError = ErrRequirementsNotMet
318
326
return
319
327
}
320
328
321
329
// check for CRD ownership conflicts
322
330
if syncError = a .crdOwnerConflicts (out , a .csvsInNamespace (out .GetNamespace ())); syncError != nil {
323
- out .SetPhase (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonOwnerConflict , fmt .Sprintf ("owner conflict: %s" , syncError ))
331
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonOwnerConflict , fmt .Sprintf ("owner conflict: %s" , syncError ), a . recorder )
324
332
return
325
333
}
326
334
327
335
logger .Info ("scheduling ClusterServiceVersion for install" )
328
- out .SetPhase (v1alpha1 .CSVPhaseInstallReady , v1alpha1 .CSVReasonRequirementsMet , "all requirements found, attempting install" )
336
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseInstallReady , v1alpha1 .CSVReasonRequirementsMet , "all requirements found, attempting install" , a . recorder )
329
337
case v1alpha1 .CSVPhaseInstallReady :
330
338
331
339
installer , strategy , _ := a .parseStrategiesAndUpdateStatus (out )
@@ -337,16 +345,16 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
337
345
// Install owned APIServices and update strategy with serving cert data
338
346
strategy , syncError = a .installOwnedAPIServiceRequirements (out , strategy )
339
347
if syncError != nil {
340
- out .SetPhase (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentFailed , fmt .Sprintf ("install API services failed: %s" , syncError ))
348
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentFailed , fmt .Sprintf ("install API services failed: %s" , syncError ), a . recorder )
341
349
return
342
350
}
343
351
344
352
if syncError = installer .Install (strategy ); syncError != nil {
345
- out .SetPhase (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentFailed , fmt .Sprintf ("install strategy failed: %s" , syncError ))
353
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseFailed , v1alpha1 .CSVReasonComponentFailed , fmt .Sprintf ("install strategy failed: %s" , syncError ), a . recorder )
346
354
return
347
355
}
348
356
349
- out .SetPhase (v1alpha1 .CSVPhaseInstalling , v1alpha1 .CSVReasonInstallSuccessful , "waiting for install components to report healthy" )
357
+ out .SetPhaseWithEvent (v1alpha1 .CSVPhaseInstalling , v1alpha1 .CSVReasonInstallSuccessful , "waiting for install components to report healthy" , a . recorder )
350
358
a .requeueCSV (out .GetName (), out .GetNamespace ())
351
359
return
352
360
case v1alpha1 .CSVPhaseInstalling :
@@ -382,7 +390,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
382
390
// if we can find a newer version that's successfully installed, we're safe to mark all intermediates
383
391
for _ , csv := range a .findIntermediatesForDeletion (out ) {
384
392
// we only mark them in this step, in case some get deleted but others fail and break the replacement chain
385
- csv .SetPhase (v1alpha1 .CSVPhaseDeleting , v1alpha1 .CSVReasonReplaced , "has been replaced by a newer ClusterServiceVersion that has successfully installed." )
393
+ csv .SetPhaseWithEvent (v1alpha1 .CSVPhaseDeleting , v1alpha1 .CSVReasonReplaced , "has been replaced by a newer ClusterServiceVersion that has successfully installed." , a . recorder )
386
394
// ignore errors and success here; this step is just an optimization to speed up GC
387
395
a .client .OperatorsV1alpha1 ().ClusterServiceVersions (csv .GetNamespace ()).UpdateStatus (csv )
388
396
a .requeueCSV (csv .GetName (), csv .GetNamespace ())
0 commit comments