@@ -40,7 +40,8 @@ import (
4040 "sigs.k8s.io/controller-runtime/pkg/client"
4141 "sigs.k8s.io/controller-runtime/pkg/controller"
4242
43- "github.com/fluxcd/pkg/recorder"
43+ "github.com/fluxcd/pkg/runtime/events"
44+ "github.com/fluxcd/pkg/runtime/metrics"
4445 "github.com/fluxcd/pkg/runtime/predicates"
4546 "github.com/fluxcd/pkg/untar"
4647
@@ -56,7 +57,8 @@ type HelmChartReconciler struct {
5657 Storage * Storage
5758 Getters getter.Providers
5859 EventRecorder kuberecorder.EventRecorder
59- ExternalEventRecorder * recorder.EventRecorder
60+ ExternalEventRecorder * events.Recorder
61+ MetricsRecorder * metrics.Recorder
6062}
6163
6264// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=helmcharts,verbs=get;list;watch;create;update;patch;delete
@@ -91,10 +93,12 @@ func (r *HelmChartReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
9193 if containsString (chart .ObjectMeta .Finalizers , sourcev1 .SourceFinalizer ) {
9294 // Our finalizer is still present, so lets handle garbage collection
9395 if err := r .gc (chart , true ); err != nil {
94- r .event (chart , recorder .EventSeverityError , fmt .Sprintf ("garbage collection for deleted resource failed: %s" , err .Error ()))
96+ r .event (chart , events .EventSeverityError , fmt .Sprintf ("garbage collection for deleted resource failed: %s" , err .Error ()))
9597 // Return the error so we retry the failed garbage collection
9698 return ctrl.Result {}, err
9799 }
100+ // Record deleted status
101+ r .recordReadiness (chart , true )
98102 // Remove our finalizer from the list and update it
99103 chart .ObjectMeta .Finalizers = removeString (chart .ObjectMeta .Finalizers , sourcev1 .SourceFinalizer )
100104 if err := r .Update (ctx , & chart ); err != nil {
@@ -105,6 +109,15 @@ func (r *HelmChartReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
105109 }
106110 }
107111
112+ // record reconciliation duration
113+ if r .MetricsRecorder != nil {
114+ objRef , err := reference .GetReference (r .Scheme , & chart )
115+ if err != nil {
116+ return ctrl.Result {}, err
117+ }
118+ defer r .MetricsRecorder .RecordDuration (* objRef , start )
119+ }
120+
108121 // Conditionally set progressing condition in status
109122 resetChart , changed := r .resetStatus (chart )
110123 if changed {
@@ -113,6 +126,7 @@ func (r *HelmChartReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
113126 log .Error (err , "unable to update status" )
114127 return ctrl.Result {Requeue : true }, err
115128 }
129+ r .recordReadiness (chart , false )
116130 }
117131
118132 // Purge all but current artifact from storage
@@ -138,6 +152,7 @@ func (r *HelmChartReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
138152 if err := r .Status ().Update (ctx , & chart ); err != nil {
139153 log .Error (err , "unable to update status" )
140154 }
155+ r .recordReadiness (chart , false )
141156 return ctrl.Result {Requeue : true }, err
142157 }
143158
@@ -163,14 +178,16 @@ func (r *HelmChartReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
163178
164179 // If reconciliation failed, record the failure and requeue immediately
165180 if reconcileErr != nil {
166- r .event (reconciledChart , recorder .EventSeverityError , reconcileErr .Error ())
181+ r .event (reconciledChart , events .EventSeverityError , reconcileErr .Error ())
182+ r .recordReadiness (reconciledChart , false )
167183 return ctrl.Result {Requeue : true }, reconcileErr
168184 }
169185
170186 // Emit an event if we did not have an artifact before, or the revision has changed
171187 if chart .Status .Artifact == nil || reconciledChart .Status .Artifact .Revision != chart .Status .Artifact .Revision {
172- r .event (reconciledChart , recorder .EventSeverityInfo , sourcev1 .HelmChartReadyMessage (reconciledChart ))
188+ r .event (reconciledChart , events .EventSeverityInfo , sourcev1 .HelmChartReadyMessage (reconciledChart ))
173189 }
190+ r .recordReadiness (reconciledChart , false )
174191
175192 log .Info (fmt .Sprintf ("Reconciliation finished in %s, next run in %s" ,
176193 time .Now ().Sub (start ).String (),
@@ -527,3 +544,26 @@ func (r *HelmChartReconciler) event(chart sourcev1.HelmChart, severity, msg stri
527544 }
528545 }
529546}
547+
548+ func (r * HelmChartReconciler ) recordReadiness (chart sourcev1.HelmChart , deleted bool ) {
549+ if r .MetricsRecorder == nil {
550+ return
551+ }
552+
553+ objRef , err := reference .GetReference (r .Scheme , & chart )
554+ if err != nil {
555+ r .Log .WithValues (
556+ strings .ToLower (chart .Kind ),
557+ fmt .Sprintf ("%s/%s" , chart .GetNamespace (), chart .GetName ()),
558+ ).Error (err , "unable to record readiness metric" )
559+ return
560+ }
561+ if rc := meta .GetCondition (chart .Status .Conditions , meta .ReadyCondition ); rc != nil {
562+ r .MetricsRecorder .RecordCondition (* objRef , * rc , deleted )
563+ } else {
564+ r .MetricsRecorder .RecordCondition (* objRef , meta.Condition {
565+ Type : meta .ReadyCondition ,
566+ Status : corev1 .ConditionUnknown ,
567+ }, deleted )
568+ }
569+ }
0 commit comments