Skip to content

Commit

Permalink
Upgrade controller-runtime to v0.7.0
Browse files Browse the repository at this point in the history
This commit upgrades the `controller-runtime` dependency to `v0.7.0`,
including all changes required to make all wiring work again.

- Upgrade `runtime` to v0.6.0 to include `controller-runtime` changes.
- Logger has been removed from the reconciler, and is now retrieved
  from the `context.Context` passed to the `Reconcile` method and
  downwards functions.
- Logger configuration flags are now bound to the flag set using
  `BindFlags` from `runtime/logger`, ensuring the same contract across
  GitOps Toolkit controllers, and the `--log-json` flag has been
  deprecated in favour of the `--log-encoding=json` default.
- The `ChangePredicate` from `runtime` has changed to a
  `ReconcilateAtChangedPredicate`, and is now chained with the
  `GenerationChangedPredicate` from `controller-runtime` using
  `predicate.Or`.
- Signatures that made use of `runtime.Object` have changed to
  `client.Object`, removing the requirement to e.g. call
  `runtime.Object#Object`.
- The `leader-election-role` was changed, as leader election now works
  via the `coordination/v1` API.

Signed-off-by: Hidde Beydals <[email protected]>
  • Loading branch information
hiddeco committed Jan 12, 2021
1 parent 6ae133b commit f481b57
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 121 deletions.
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ require (
github.com/fluxcd/pkg/apis/meta v0.5.0
k8s.io/api v0.19.3
k8s.io/apimachinery v0.19.4
sigs.k8s.io/controller-runtime v0.6.3
sigs.k8s.io/controller-runtime v0.7.0
)
245 changes: 183 additions & 62 deletions api/go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion config/manager/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ spec:
args:
- --watch-all-namespaces
- --log-level=info
- --log-json
- --log-encoding=json
- --enable-leader-election
readinessProbe:
httpGet:
Expand Down
12 changes: 12 additions & 0 deletions config/rbac/leader_election_role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ rules:
- events
verbs:
- create
- apiGroups:
- "coordination.k8s.io"
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
54 changes: 19 additions & 35 deletions controllers/imageupdateautomation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

Expand Down Expand Up @@ -69,7 +70,6 @@ const imagePolicyKey = ".spec.update.imagePolicy"
// ImageUpdateAutomationReconciler reconciles a ImageUpdateAutomation object
type ImageUpdateAutomationReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
EventRecorder kuberecorder.EventRecorder
ExternalEventRecorder *events.Recorder
Expand All @@ -80,9 +80,8 @@ type ImageUpdateAutomationReconciler struct {
// +kubebuilder:rbac:groups=image.toolkit.fluxcd.io,resources=imageupdateautomations/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories,verbs=get;list;watch

func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
ctx := context.Background()
log := r.Log.WithValues("imageupdateautomation", req.NamespacedName)
func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := logr.FromContext(ctx)
now := time.Now()

var auto imagev1.ImageUpdateAutomation
Expand All @@ -98,7 +97,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu
// Record readiness metric when exiting; if there's any points at
// which the readiness is updated _without also exiting_, they
// should also record the readiness.
defer r.recordReadinessMetric(&auto)
defer r.recordReadinessMetric(ctx, &auto)
// Record reconciliation duration when exiting
if r.MetricsRecorder != nil {
objRef, err := reference.GetReference(r.Scheme, &auto)
Expand All @@ -119,7 +118,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu

// failWithError is a helper for bailing on the reconciliation.
failWithError := func(err error) (ctrl.Result, error) {
r.event(auto, events.EventSeverityError, err.Error())
r.event(ctx, auto, events.EventSeverityError, err.Error())
imagev1.SetImageUpdateAutomationReadiness(&auto, metav1.ConditionFalse, meta.ReconciliationFailedReason, err.Error())
if err := r.Status().Update(ctx, &auto); err != nil {
log.Error(err, "failed to reconcile")
Expand Down Expand Up @@ -184,7 +183,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu
default:
log.Info("no update strategy given in the spec")
// no sense rescheduling until this resource changes
r.event(auto, events.EventSeverityInfo, "no update strategy in spec, failing trivially")
r.event(ctx, auto, events.EventSeverityInfo, "no update strategy in spec, failing trivially")
imagev1.SetImageUpdateAutomationReadiness(&auto, metav1.ConditionFalse, imagev1.NoStrategyReason, "no update strategy is given for object")
err := r.Status().Update(ctx, &auto)
return ctrl.Result{}, err
Expand All @@ -196,7 +195,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu

if rev, err := commitAllAndPush(ctx, repo, access, &auto.Spec.Commit); err != nil {
if err == errNoChanges {
r.event(auto, events.EventSeverityInfo, "no updates made")
r.event(ctx, auto, events.EventSeverityInfo, "no updates made")
log.V(debug).Info("no changes made in working directory; no commit")
statusMessage = "no updates made"
if lastCommit, lastTime := auto.Status.LastPushCommit, auto.Status.LastPushTime; lastCommit != "" {
Expand All @@ -206,7 +205,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu
return failWithError(err)
}
} else {
r.event(auto, events.EventSeverityInfo, "committed and pushed change "+rev)
r.event(ctx, auto, events.EventSeverityInfo, "committed and pushed change "+rev)
log.Info("pushed commit to origin", "revision", rev)
auto.Status.LastPushCommit = rev
auto.Status.LastPushTime = &metav1.Time{Time: now}
Expand All @@ -232,7 +231,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu
func (r *ImageUpdateAutomationReconciler) SetupWithManager(mgr ctrl.Manager) error {
ctx := context.Background()
// Index the git repository object that each I-U-A refers to
if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj runtime.Object) []string {
if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj client.Object) []string {
updater := obj.(*imagev1.ImageUpdateAutomation)
ref := updater.Spec.Checkout.GitRepositoryRef
return []string{ref.Name}
Expand All @@ -242,11 +241,8 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(mgr ctrl.Manager) err

return ctrl.NewControllerManagedBy(mgr).
For(&imagev1.ImageUpdateAutomation{}).
WithEventFilter(predicates.ChangePredicate{}).
Watches(&source.Kind{Type: &sourcev1.GitRepository{}},
&handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.automationsForGitRepo),
}).
WithEventFilter(predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcilateAtChangedPredicate{})).
Watches(&source.Kind{Type: &sourcev1.GitRepository{}}, handler.EnqueueRequestsFromMapFunc(r.automationsForGitRepo)).
Complete(r)
}

Expand All @@ -271,14 +267,11 @@ func durationSinceLastRun(auto *imagev1.ImageUpdateAutomation, now time.Time) ti

// automationsForGitRepo fetches all the automations that refer to a
// particular source.GitRepository object.
func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(obj handler.MapObject) []reconcile.Request {
func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(obj client.Object) []reconcile.Request {
ctx := context.Background()
var autoList imagev1.ImageUpdateAutomationList
if err := r.List(ctx, &autoList, client.InNamespace(obj.Meta.GetNamespace()), client.MatchingFields{repoRefKey: obj.Meta.GetName()}); err != nil {
r.Log.Error(err, "failed to list ImageUpdateAutomations for GitRepository", "name", types.NamespacedName{
Name: obj.Meta.GetName(),
Namespace: obj.Meta.GetNamespace(),
})
if err := r.List(ctx, &autoList, client.InNamespace(obj.GetNamespace()),
client.MatchingFields{repoRefKey: obj.GetName()}); err != nil {
return nil
}
reqs := make([]reconcile.Request, len(autoList.Items), len(autoList.Items))
Expand Down Expand Up @@ -382,41 +375,32 @@ func commitAllAndPush(ctx context.Context, repo *gogit.Repository, access repoAc

// --- events, metrics

func (r *ImageUpdateAutomationReconciler) event(auto imagev1.ImageUpdateAutomation, severity, msg string) {
func (r *ImageUpdateAutomationReconciler) event(ctx context.Context, auto imagev1.ImageUpdateAutomation, severity, msg string) {
if r.EventRecorder != nil {
r.EventRecorder.Event(&auto, "Normal", severity, msg)
}
if r.ExternalEventRecorder != nil {
objRef, err := reference.GetReference(r.Scheme, &auto)
if err != nil {
r.Log.WithValues(
"request",
fmt.Sprintf("%s/%s", auto.GetNamespace(), auto.GetName()),
).Error(err, "unable to send event")
logr.FromContext(ctx).Error(err, "unable to send event")
return
}

if err := r.ExternalEventRecorder.Eventf(*objRef, nil, severity, severity, msg); err != nil {
r.Log.WithValues(
"request",
fmt.Sprintf("%s/%s", auto.GetNamespace(), auto.GetName()),
).Error(err, "unable to send event")
logr.FromContext(ctx).Error(err, "unable to send event")
return
}
}
}

func (r *ImageUpdateAutomationReconciler) recordReadinessMetric(auto *imagev1.ImageUpdateAutomation) {
func (r *ImageUpdateAutomationReconciler) recordReadinessMetric(ctx context.Context, auto *imagev1.ImageUpdateAutomation) {
if r.MetricsRecorder == nil {
return
}

objRef, err := reference.GetReference(r.Scheme, auto)
if err != nil {
r.Log.WithValues(
strings.ToLower(auto.Kind),
fmt.Sprintf("%s/%s", auto.GetNamespace(), auto.GetName()),
).Error(err, "unable to record readiness metric")
logr.FromContext(ctx).Error(err, "unable to record readiness metric")
return
}
if rc := apimeta.FindStatusCondition(auto.Status.Conditions, meta.ReadyCondition); rc != nil {
Expand Down
5 changes: 3 additions & 2 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ func TestAPIs(t *testing.T) {
}

var _ = BeforeSuite(func(done Done) {
logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
logf.SetLogger(
zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)),
)

By("bootstrapping test environment")
testEnv = &envtest.Environment{
Expand Down Expand Up @@ -84,7 +86,6 @@ var _ = BeforeSuite(func(done Done) {

imageAutoReconciler = &ImageUpdateAutomationReconciler{
Client: k8sManager.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("ImageUpdateAutomation"),
Scheme: scheme.Scheme,
}
Expect(imageAutoReconciler.SetupWithManager(k8sManager)).To(Succeed())
Expand Down
2 changes: 1 addition & 1 deletion controllers/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
}, timeout, time.Second).Should(BeTrue())
// run the reconciliation explicitly, and make sure it
// doesn't do anything
result, err := imageAutoReconciler.Reconcile(ctrl.Request{
result, err := imageAutoReconciler.Reconcile(context.TODO(), ctrl.Request{
NamespacedName: updateKey,
})
Expect(err).To(BeNil())
Expand Down
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ require (
github.com/fluxcd/image-reflector-controller/api v0.1.0
github.com/fluxcd/pkg/apis/meta v0.5.0
github.com/fluxcd/pkg/gittestserver v0.0.2
github.com/fluxcd/pkg/runtime v0.4.0
github.com/fluxcd/pkg/runtime v0.6.0
github.com/fluxcd/source-controller v0.3.0
// If you bump this, change TOOLKIT_VERSION in the Makefile to match
github.com/fluxcd/source-controller/api v0.5.0
github.com/fluxcd/source-controller/api v0.6.0
github.com/go-git/go-billy/v5 v5.0.0
github.com/go-git/go-git/v5 v5.1.0
github.com/go-logr/logr v0.2.1
github.com/go-logr/logr v0.3.0
github.com/go-openapi/spec v0.19.5
github.com/google/go-containerregistry v0.1.1
github.com/onsi/ginkgo v1.12.1
github.com/onsi/gomega v1.10.1
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/otiai10/copy v1.2.0
github.com/spf13/pflag v1.0.5
k8s.io/api v0.19.4
k8s.io/apimachinery v0.19.4
k8s.io/client-go v0.19.4
sigs.k8s.io/controller-runtime v0.6.4
sigs.k8s.io/controller-runtime v0.7.0
sigs.k8s.io/kustomize/kyaml v0.4.1
)
Loading

0 comments on commit f481b57

Please sign in to comment.