Compare artifact <> HelmRelease in enqueuer

The reason for this is the `EnqueueRequestsFromMapFunc` calling the
enqueuer for _both_ the old and the new object, and we only want to act
on the ones that contain a revision different from the one that we have
recorded in the status object of the `HelmRelease`.

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
Hidde Beydals 2020-10-28 18:04:18 +01:00
parent 7ab3ed3a55
commit fa598261e7
2 changed files with 33 additions and 17 deletions

View File

@ -96,8 +96,8 @@ func (r *HelmReleaseReconciler) SetupWithManager(mgr ctrl.Manager, opts HelmRele
For(&v2.HelmRelease{}, builder.WithPredicates(predicates.ChangePredicate{})).
Watches(
&source.Kind{Type: &sourcev1.HelmChart{}},
&handler.EnqueueRequestsFromMapFunc{ToRequests: handler.ToRequestsFunc(r.helmReleasesForHelmChart)},
builder.WithPredicates(HelmChartRevisionChangePredicate{}),
&handler.EnqueueRequestsFromMapFunc{ToRequests: handler.ToRequestsFunc(r.requestsForHelmChartChange)},
builder.WithPredicates(SourceRevisionChangePredicate{}),
).
WithOptions(controller.Options{MaxConcurrentReconciles: opts.MaxConcurrentReconciles}).
Complete(r)
@ -704,7 +704,16 @@ func (r *HelmReleaseReconciler) handleHelmActionResult(hr *v2.HelmRelease, revis
}
}
func (r *HelmReleaseReconciler) helmReleasesForHelmChart(obj handler.MapObject) []reconcile.Request {
func (r *HelmReleaseReconciler) requestsForHelmChartChange(obj handler.MapObject) []reconcile.Request {
hc, ok := obj.Object.(*sourcev1.HelmChart)
if !ok {
panic(fmt.Sprintf("Expected a HelmChart, got %T", hc))
}
// If we do not have an artifact, we have no requests to make
if hc.GetArtifact() == nil {
return nil
}
ctx := context.Background()
var list v2.HelmReleaseList
if err := r.List(ctx, &list, client.MatchingFields{
@ -713,12 +722,19 @@ func (r *HelmReleaseReconciler) helmReleasesForHelmChart(obj handler.MapObject)
r.Log.Error(err, "failed to list HelmReleases for HelmChart")
return nil
}
reqs := make([]reconcile.Request, len(list.Items), len(list.Items))
for i := range list.Items {
reqs[i].NamespacedName.Name = list.Items[i].Name
reqs[i].NamespacedName.Namespace = list.Items[i].Namespace
r.Log.Info("requesting reconciliation", v2.HelmReleaseKind, reqs[i].NamespacedName)
var reqs []reconcile.Request
for _, i := range list.Items {
// If the revision of the artifact equals to the last attempted revision,
// we should not make a request for this HelmRelease
if hc.GetArtifact().Revision == i.Status.LastAttemptedRevision {
continue
}
req := reconcile.Request{NamespacedName: types.NamespacedName{Namespace: i.GetNamespace(), Name: i.GetName()}}
reqs = append(reqs, req)
r.Log.Info("requesting reconciliation due to GitRepository revision change",
strings.ToLower(v2.HelmReleaseKind), &req,
"revision", hc.GetArtifact().Revision)
}
return reqs
}

View File

@ -23,41 +23,41 @@ import (
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
type HelmChartRevisionChangePredicate struct {
type SourceRevisionChangePredicate struct {
predicate.Funcs
}
func (HelmChartRevisionChangePredicate) Update(e event.UpdateEvent) bool {
func (SourceRevisionChangePredicate) Update(e event.UpdateEvent) bool {
if e.MetaOld == nil || e.MetaNew == nil {
return false
}
oldChart, ok := e.ObjectOld.(*sourcev1.HelmChart)
oldSource, ok := e.ObjectOld.(sourcev1.Source)
if !ok {
return false
}
newChart, ok := e.ObjectNew.(*sourcev1.HelmChart)
newSource, ok := e.ObjectNew.(sourcev1.Source)
if !ok {
return false
}
if oldChart.GetArtifact() == nil && newChart.GetArtifact() != nil {
if oldSource.GetArtifact() == nil && newSource.GetArtifact() != nil {
return true
}
if oldChart.GetArtifact() != nil && newChart.GetArtifact() != nil &&
oldChart.GetArtifact().Revision != newChart.GetArtifact().Revision {
if oldSource.GetArtifact() != nil && newSource.GetArtifact() != nil &&
oldSource.GetArtifact().Revision != newSource.GetArtifact().Revision {
return true
}
return false
}
func (HelmChartRevisionChangePredicate) Create(e event.CreateEvent) bool {
func (SourceRevisionChangePredicate) Create(e event.CreateEvent) bool {
return false
}
func (HelmChartRevisionChangePredicate) Delete(e event.DeleteEvent) bool {
func (SourceRevisionChangePredicate) Delete(e event.DeleteEvent) bool {
return false
}