From 664bcc278ddc565d43c1a973ab9dd2e091dc3b0a Mon Sep 17 00:00:00 2001 From: David Cassany Date: Mon, 2 Oct 2023 22:02:43 +0200 Subject: [PATCH] Patch already existing versions on channel sync Signed-off-by: David Cassany --- api/v1beta1/common_consts.go | 3 ++ .../managedosversionchannel_controller.go | 45 +++++++++++++++++-- ...managedosversionchannel_controller_test.go | 11 ++++- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/api/v1beta1/common_consts.go b/api/v1beta1/common_consts.go index c48c73709..a56e2f719 100644 --- a/api/v1beta1/common_consts.go +++ b/api/v1beta1/common_consts.go @@ -20,6 +20,9 @@ const ( // ElementalManagedLabel label used to put on resources managed by the elemental operator. ElementalManagedLabel = "elemental.cattle.io/managed" + // ElementalManagedLabel label used to put on resources managed by the elemental operator. + ElementalManagedOSVersionChannelLabel = "elemental.cattle.io/channel" + // SASecretSuffix is the suffix used to name registration service account's token secret SASecretSuffix = "-token" diff --git a/controllers/managedosversionchannel_controller.go b/controllers/managedosversionchannel_controller.go index 1c70c8f98..edfe846ea 100644 --- a/controllers/managedosversionchannel_controller.go +++ b/controllers/managedosversionchannel_controller.go @@ -283,8 +283,12 @@ func (r *ManagedOSVersionChannelReconciler) createManagedOSVersions(ctx context. return err } - var errs []error + curVersions := r.getAllOwnedManagedOSVersions(ctx, client.ObjectKey{ + Name: ch.Name, + Namespace: ch.Namespace, + }) + var errs []error for _, v := range vers { vcpy := v.DeepCopy() vcpy.ObjectMeta.Namespace = ch.Namespace @@ -297,12 +301,25 @@ func (r *ManagedOSVersionChannelReconciler) createManagedOSVersions(ctx context. Controller: pointer.Bool(true), }, } + vcpy.ObjectMeta.Labels = map[string]string{ + elementalv1.ElementalManagedOSVersionChannelLabel: ch.Name, + } if ch.Spec.UpgradeContainer != nil { vcpy.Spec.UpgradeContainer = ch.Spec.UpgradeContainer } - if err := r.Create(ctx, vcpy); err != nil { + if cv, ok := curVersions[v.Name]; ok { + patchBase := client.MergeFrom(cv.DeepCopy()) + cv.Spec = vcpy.Spec + err = r.Patch(ctx, cv, patchBase) + if err != nil { + logger.Error(err, "failed to patch a managedosversion", "name", cv.Name) + errs = append(errs, err) + } else { + logger.Info("patched managedOSVersion", "name", cv.Name) + } + } else if err = r.Create(ctx, vcpy); err != nil { if apierrors.IsAlreadyExists(err) { logger.Info("already existing managedOSVersion", "name", vcpy.Name) } else { @@ -317,10 +334,32 @@ func (r *ManagedOSVersionChannelReconciler) createManagedOSVersions(ctx context. return errorutils.NewAggregate(errs) } +// getAllOwnedManagedOSVersions returns a map of all ManagedOSVersions labeled with the given channel, resource name is used as the map key +func (r *ManagedOSVersionChannelReconciler) getAllOwnedManagedOSVersions(ctx context.Context, chKey client.ObjectKey) map[string]*elementalv1.ManagedOSVersion { + logger := ctrl.LoggerFrom(ctx) + versions := &elementalv1.ManagedOSVersionList{} + result := map[string]*elementalv1.ManagedOSVersion{} + + err := r.List(ctx, versions, client.InNamespace(chKey.Namespace), client.MatchingLabels(map[string]string{ + elementalv1.ElementalManagedOSVersionChannelLabel: chKey.Name, + })) + if err != nil { + // only log error and return an empty map + logger.Error(err, "failed listing existing versions from channel") + return result + } + + for _, ver := range versions.Items { + result[ver.Name] = &ver + } + + return result +} + // createSyncerPod creates the pod according to the managed OS version channel configuration func (r *ManagedOSVersionChannelReconciler) createSyncerPod(ctx context.Context, ch *elementalv1.ManagedOSVersionChannel, sync syncer.Syncer) error { logger := ctrl.LoggerFrom(ctx) - logger.Info("Launching syncer pod", "pod", ch.Name) + logger.Info("Launching syncer", "pod", ch.Name) serviceAccount := false pod := &corev1.Pod{ diff --git a/controllers/managedosversionchannel_controller_test.go b/controllers/managedosversionchannel_controller_test.go index cb681ce7f..091d99d58 100644 --- a/controllers/managedosversionchannel_controller_test.go +++ b/controllers/managedosversionchannel_controller_test.go @@ -56,10 +56,10 @@ const updatedJSON = `[ "name": "v0.1.0" }, "spec": { - "version": "v0.1.0", + "version": "v0.1.0-patched", "type": "container", "metadata": { - "upgradeImage": "foo/bar:v0.1.0" + "upgradeImage": "foo/bar:v0.1.0-patched" } } }, @@ -575,5 +575,12 @@ var _ = Describe("managed os version channel controller integration tests", func }, managedOSVersion) return err == nil }, 4*time.Second, 1*time.Second).Should(BeTrue()) + + // After channel update already existing versions were patched + Expect(cl.Get(ctx, client.ObjectKey{ + Name: "v0.1.0", + Namespace: ch.Namespace, + }, managedOSVersion)).To(Succeed()) + Expect(managedOSVersion.Spec.Version).To(Equal("v0.1.0-patched")) }) })