diff --git a/api/v1alpha1/backupconfiguration_types.go b/api/v1alpha1/backupconfiguration_types.go index fdb8ca1..86c8843 100644 --- a/api/v1alpha1/backupconfiguration_types.go +++ b/api/v1alpha1/backupconfiguration_types.go @@ -35,11 +35,21 @@ type Step struct { Env []corev1.EnvVar `json:"env"` } +type Hook struct { + Cmd string `json:"cmd"` + // +optional + Args []string `json:"args,omitempty"` +} + type Target struct { // +kubebuilder:validation:Enum=Deployment;Task Kind string `json:"kind"` Name string `json:"name"` // +optional + BeforeBackup []Hook `json:"beforeBackup,omitempty"` + // +optional + AfterBackup []Hook `json:"afterBackup,omitempty"` + // +optional ApiVersion string `json:"apiVersion,omitempty"` // +optional VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a8b6de9..f33fd4c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -303,6 +303,26 @@ func (in *FunctionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Hook) DeepCopyInto(out *Hook) { + *out = *in + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Hook. +func (in *Hook) DeepCopy() *Hook { + if in == nil { + return nil + } + out := new(Hook) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Keep) DeepCopyInto(out *Keep) { *out = *in @@ -478,6 +498,20 @@ func (in *Step) DeepCopy() *Step { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Target) DeepCopyInto(out *Target) { *out = *in + if in.BeforeBackup != nil { + in, out := &in.BeforeBackup, &out.BeforeBackup + *out = make([]Hook, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AfterBackup != nil { + in, out := &in.AfterBackup, &out.AfterBackup + *out = make([]Hook, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]v1.VolumeMount, len(*in)) diff --git a/controllers/backupconfiguration_controller.go b/controllers/backupconfiguration_controller.go index 5bd9c27..c62059d 100644 --- a/controllers/backupconfiguration_controller.go +++ b/controllers/backupconfiguration_controller.go @@ -214,6 +214,7 @@ func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1 } } deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sidecar) + deployment.Spec.Template.Spec.ShareProcessNamespace = func() *bool { b := true; return &b }() if err := formolrbac.CreateBackupSessionListenerRBAC(r.Client, deployment.Spec.Template.Spec.ServiceAccountName, deployment.Namespace); err != nil { log.Error(err, "unable to create backupsessionlistener RBAC") diff --git a/controllers/backupsession_controller.go b/controllers/backupsession_controller.go index 2409612..5404056 100644 --- a/controllers/backupsession_controller.go +++ b/controllers/backupsession_controller.go @@ -122,7 +122,7 @@ func (r *BackupSessionReconciler) StatusUpdate() error { if len(backupSessionList.Items) < 2 { // Not enough backupSession to proceed log.V(1).Info("Not enough successful backup jobs") - return nil + break } sort.Slice(backupSessionList.Items, func(i, j int) bool { @@ -203,6 +203,7 @@ func (r *BackupSessionReconciler) StatusUpdate() error { } } } + log.V(1).Info("New BackupSession status", "status", r.BackupSession.Status.BackupState) if err := r.Status().Update(ctx, r.BackupSession); err != nil { log.Error(err, "unable to update BackupSession status") return err @@ -276,7 +277,11 @@ func (r *BackupSessionReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, client.IgnoreNotFound(err) } - if r.BackupSession.ObjectMeta.DeletionTimestamp.IsZero() { + if r.IsBackupOngoing() { + // There is already a backup ongoing. We don't do anything and we reschedule + log.V(0).Info("there is an ongoing backup. let's reschedule this operation") + return ctrl.Result{RequeueAfter: 30 * time.Second}, nil + } else if r.BackupSession.ObjectMeta.DeletionTimestamp.IsZero() { if !controllerutil.ContainsFinalizer(r.BackupSession, finalizerName) { controllerutil.AddFinalizer(r.BackupSession, finalizerName) if err := r.Update(ctx, r.BackupSession); err != nil { @@ -284,9 +289,6 @@ func (r *BackupSessionReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, err } } - } else if r.IsBackupOngoing() { - log.V(0).Info("there is an ongoing backup. let's reschedule the deletion of the backupsession") - return ctrl.Result{RequeueAfter: 30 * time.Second}, nil } else { log.V(0).Info("backupsession being deleted", "backupsession", r.BackupSession.Name) if controllerutil.ContainsFinalizer(r.BackupSession, finalizerName) { @@ -308,8 +310,6 @@ func (r *BackupSessionReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, err } - // cleanup old backups - log.V(1).Info("try to cleanup old backups") return reschedule, nil }