From 1361f6204547d424cea7acf4733d482122f4c3eb Mon Sep 17 00:00:00 2001 From: Jean-Marc ANDRE Date: Sat, 18 Feb 2023 22:46:15 +0100 Subject: [PATCH] A sidecar ENV keeps the paths to backup. That will do for now but the BackupSession controller in the sidecar should do the job of computing the paths to backup every time it reconciles. In case the paths have changed --- api/v1alpha1/backupconfiguration_types.go | 7 -- api/v1alpha1/common.go | 2 + api/v1alpha1/zz_generated.deepcopy.go | 27 ------- controllers/backupconfiguration_controller.go | 8 +- .../backupconfiguration_controller_helpers.go | 76 ++++++++++++------- 5 files changed, 50 insertions(+), 70 deletions(-) diff --git a/api/v1alpha1/backupconfiguration_types.go b/api/v1alpha1/backupconfiguration_types.go index aff1486..582d5bd 100644 --- a/api/v1alpha1/backupconfiguration_types.go +++ b/api/v1alpha1/backupconfiguration_types.go @@ -61,11 +61,6 @@ type Target struct { Retry int `json:"retry"` } -type TargetSidecarPath struct { - TargetName string `json:"targetName"` - SidecarPaths []string `json:"sidecarPaths"` -} - type Keep struct { Last int32 `json:"last"` Daily int32 `json:"daily"` @@ -91,8 +86,6 @@ type BackupConfigurationStatus struct { Suspended bool `json:"suspended"` ActiveCronJob bool `json:"activeCronJob"` ActiveSidecar bool `json:"activeSidecar"` - // +optional - Targets []TargetSidecarPath `json:"targets,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/common.go b/api/v1alpha1/common.go index 9c21ad6..3491639 100644 --- a/api/v1alpha1/common.go +++ b/api/v1alpha1/common.go @@ -10,4 +10,6 @@ const ( // Used by the backupsession controller POD_NAME string = "POD_NAME" POD_NAMESPACE string = "POD_NAMESPACE" + // Backup Paths list + BACKUP_PATHS = "BACKUP_PATHS" ) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 1cef863..3cd2fac 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -145,13 +145,6 @@ func (in *BackupConfigurationStatus) DeepCopyInto(out *BackupConfigurationStatus in, out := &in.LastBackupTime, &out.LastBackupTime *out = (*in).DeepCopy() } - if in.Targets != nil { - in, out := &in.Targets, &out.Targets - *out = make([]TargetSidecarPath, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationStatus. @@ -617,26 +610,6 @@ func (in *TargetContainer) DeepCopy() *TargetContainer { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TargetSidecarPath) DeepCopyInto(out *TargetSidecarPath) { - *out = *in - if in.SidecarPaths != nil { - in, out := &in.SidecarPaths, &out.SidecarPaths - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetSidecarPath. -func (in *TargetSidecarPath) DeepCopy() *TargetSidecarPath { - if in == nil { - return nil - } - out := new(TargetSidecarPath) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetStatus) DeepCopyInto(out *TargetStatus) { *out = *in diff --git a/controllers/backupconfiguration_controller.go b/controllers/backupconfiguration_controller.go index 792d94c..459d05d 100644 --- a/controllers/backupconfiguration_controller.go +++ b/controllers/backupconfiguration_controller.go @@ -97,15 +97,9 @@ func (r *BackupConfigurationReconciler) Reconcile(ctx context.Context, req ctrl. switch target.BackupType { case formolv1alpha1.OnlineKind: // TODO: add a sidecar to the pod with the target.Containers[].Paths mounted - if sidecarPaths, err := r.addOnlineSidecar(backupConf, target); err != nil { + if err := r.addOnlineSidecar(backupConf, target); err != nil { r.Log.Error(err, "unable to add online sidecar") return ctrl.Result{}, err - } else if len(sidecarPaths) > 0 { - backupConf.Status.Targets = append(backupConf.Status.Targets, - formolv1alpha1.TargetSidecarPath{ - TargetName: target.TargetName, - SidecarPaths: sidecarPaths, - }) } backupConf.Status.ActiveSidecar = true case formolv1alpha1.JobKind: diff --git a/controllers/backupconfiguration_controller_helpers.go b/controllers/backupconfiguration_controller_helpers.go index 26c0f9e..7de1a43 100644 --- a/controllers/backupconfiguration_controller_helpers.go +++ b/controllers/backupconfiguration_controller_helpers.go @@ -24,9 +24,11 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "os" "path/filepath" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1" ) @@ -178,13 +180,18 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1. return nil } -func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (sidecarPaths []string, err error) { - addTags := func(sideCar *corev1.Container, podSpec *corev1.PodSpec, target formolv1alpha1.Target) ([]string, bool) { - var sidecarPaths []string +func hasSidecar(podSpec *corev1.PodSpec) bool { + for _, container := range podSpec.Containers { + if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME { + return true + } + } + return false +} + +func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (err error) { + addTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) (sidecarPaths []string, vms []corev1.VolumeMount) { for i, container := range podSpec.Containers { - if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME { - return sidecarPaths, false - } for _, targetContainer := range target.Containers { if targetContainer.Name == container.Name { // Found a target container. Tag it. @@ -209,13 +216,13 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph sidecarPath = filepath.Join(vm.MountPath, rel) } } - sideCar.VolumeMounts = append(sideCar.VolumeMounts, vm) + vms = append(vms, vm) sidecarPaths = append(sidecarPaths, sidecarPath) } } } } - return sidecarPaths, true + return } repo := formolv1alpha1.Repo{} @@ -224,11 +231,11 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph Name: backupConf.Spec.Repository, }, &repo); err != nil { r.Log.Error(err, "unable to get Repo") - return + return err } r.Log.V(1).Info("Got Repository", "repo", repo) env := repo.GetResticEnv(backupConf) - sideCar := corev1.Container{ + sidecar := corev1.Container{ Name: formolv1alpha1.SIDECARCONTAINER_NAME, Image: backupConf.Spec.Image, Args: []string{"backupsession", "server"}, @@ -247,33 +254,44 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph }), VolumeMounts: []corev1.VolumeMount{}, } + var targetObject client.Object + var targetPodSpec *corev1.PodSpec switch target.TargetKind { case formolv1alpha1.Deployment: - deployment := &appsv1.Deployment{} + deployment := appsv1.Deployment{} if err = r.Get(r.Context, client.ObjectKey{ Namespace: backupConf.Namespace, Name: target.TargetName, - }, deployment); err != nil { + }, &deployment); err != nil { r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName) return } - if paths, add := addTags(&sideCar, &deployment.Spec.Template.Spec, target); add == true { - sidecarPaths = paths - if err = r.createRBACSidecar(corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: deployment.Namespace, - Name: deployment.Spec.Template.Spec.ServiceAccountName, - }, - }); err != nil { - r.Log.Error(err, "unable to create RBAC for the sidecar container") - return - } - deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sideCar) - r.Log.V(1).Info("Updating deployment", "deployment", deployment, "containers", deployment.Spec.Template.Spec.Containers) - if err = r.Update(r.Context, deployment); err != nil { - r.Log.Error(err, "cannot update deployment", "Deployment", deployment) - return - } + targetObject = &deployment + targetPodSpec = &deployment.Spec.Template.Spec + } + if !hasSidecar(targetPodSpec) { + if err = r.createRBACSidecar(corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: backupConf.Namespace, + Name: targetPodSpec.ServiceAccountName, + }, + }); err != nil { + r.Log.Error(err, "unable to create RBAC for the sidecar container") + return + } + sidecarPaths, vms := addTags(targetPodSpec, target) + sidecar.VolumeMounts = vms + sidecar.Env = append(sidecar.Env, corev1.EnvVar{ + Name: formolv1alpha1.BACKUP_PATHS, + Value: strings.Join(sidecarPaths, string(os.PathListSeparator)), + }) + + // The sidecar definition is complete. Add it to the targetObject + targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar) + r.Log.V(1).Info("Adding sidecar", "targetObject", targetObject, "sidecar", sidecar) + if err = r.Update(r.Context, targetObject); err != nil { + r.Log.Error(err, "unable to add sidecar", "targetObject", targetObject) + return } }