Prepared RestoreSession for OnlineKind with initContainer

This commit is contained in:
jandre 2023-03-21 17:57:14 +01:00
parent 3486ad2efe
commit 7e007bfd44
3 changed files with 59 additions and 39 deletions

View File

@ -17,7 +17,10 @@ limitations under the License.
package v1alpha1
import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// +kubebuilder:validation:Enum=Deployment;StatefulSet;Pod
@ -38,6 +41,22 @@ const (
JobKind BackupType = "Job"
)
func GetTargetObjects(kind TargetKind) (targetObject client.Object, targetPodSpec *corev1.PodSpec) {
switch kind {
case Deployment:
deployment := appsv1.Deployment{}
targetObject = &deployment
targetPodSpec = &deployment.Spec.Template.Spec
case StatefulSet:
statefulSet := appsv1.StatefulSet{}
targetObject = &statefulSet
targetPodSpec = &statefulSet.Spec.Template.Spec
}
return
}
const (
BACKUP_PREFIX_PATH = `backup`
FORMOL_SHARED_VOLUME = `formol-shared`

View File

@ -18,7 +18,6 @@ package controllers
import (
"fmt"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
@ -130,36 +129,6 @@ func (r *BackupConfigurationReconciler) AddCronJob(backupConf formolv1alpha1.Bac
}
}
func (r *BackupConfigurationReconciler) getTargetObjects(kind formolv1alpha1.TargetKind, namespace string, name string) (targetObject client.Object, targetPodSpec *corev1.PodSpec, err error) {
switch kind {
case formolv1alpha1.Deployment:
deployment := appsv1.Deployment{}
if err = r.Get(r.Context, client.ObjectKey{
Namespace: namespace,
Name: name,
}, &deployment); err != nil {
r.Log.Error(err, "cannot get deployment", "Deployment", name)
return
}
targetObject = &deployment
targetPodSpec = &deployment.Spec.Template.Spec
case formolv1alpha1.StatefulSet:
statefulSet := appsv1.StatefulSet{}
if err = r.Get(r.Context, client.ObjectKey{
Namespace: namespace,
Name: name,
}, &statefulSet); err != nil {
r.Log.Error(err, "cannot get StatefulSet", "StatefulSet", name)
return
}
targetObject = &statefulSet
targetPodSpec = &statefulSet.Spec.Template.Spec
}
return
}
func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.BackupConfiguration) error {
removeTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) {
for i, container := range podSpec.Containers {
@ -190,9 +159,12 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
}
r.Log.V(1).Info("Got Repository", "repo", repo)
for _, target := range backupConf.Spec.Targets {
targetObject, targetPodSpec, err := r.getTargetObjects(target.TargetKind, backupConf.Namespace, target.TargetName)
if err != nil {
r.Log.Error(err, "unable to get target objects")
targetObject, targetPodSpec := formolv1alpha1.GetTargetObjects(target.TargetKind)
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: target.TargetName,
}, targetObject); err != nil {
r.Log.Error(err, "cannot get target", "target", target.TargetName)
return err
}
restoreContainers := []corev1.Container{}
@ -225,7 +197,7 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
}
targetPodSpec.Volumes = restoreVolumes
removeTags(targetPodSpec, target)
if err = r.Update(r.Context, targetObject); err != nil {
if err := r.Update(r.Context, targetObject); err != nil {
r.Log.Error(err, "unable to remove sidecar", "targetObject", targetObject)
return err
}
@ -275,9 +247,12 @@ func (r *BackupConfigurationReconciler) addSidecar(backupConf formolv1alpha1.Bac
Privileged: func() *bool { b := true; return &b }(),
},
}
targetObject, targetPodSpec, err := r.getTargetObjects(target.TargetKind, backupConf.Namespace, target.TargetName)
if err != nil {
r.Log.Error(err, "unable to get target objects")
targetObject, targetPodSpec := formolv1alpha1.GetTargetObjects(target.TargetKind)
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: target.TargetName,
}, targetObject); err != nil {
r.Log.Error(err, "cannot get target", "target", target.TargetName)
return err
}
if !hasSidecar(targetPodSpec) {

View File

@ -65,7 +65,33 @@ func (r *RestoreSessionReconciler) Reconcile(ctx context.Context, req ctrl.Reque
var newSessionState formolv1alpha1.SessionState
switch restoreSession.Status.SessionState {
case formolv1alpha1.New:
newSessionState = r.initRestore(&restoreSession, backupConf)
// Go through the Targets and create the corresponding TargetStatus. Move to Initializing.
if r.isBackupOngoing(backupConf) {
r.Log.V(0).Info("there is an ongoing backup. Let's reschedule this operation")
return ctrl.Result{
RequeueAfter: 30 * time.Second,
}, nil
}
restoreSession.Status.Targets = r.initSession(backupConf)
newSessionState = formolv1alpha1.Initializing
case formolv1alpha1.Initializing:
// Wait for all the Targets to be in the Initialized state then move them to Running and move to Running myself.
// if one of the Target fails to initialize, move it back to New state and decrement Try.
// if try reaches 0, move all the Targets to Finalize and move myself to Failure.
newSessionState = r.checkInitialized(restoreSession.Status.Targets, backupConf)
case formolv1alpha1.Running:
// Wait for all the target to be in Waiting state then move them to the Finalize state. Move myself to Finalize.
// if one of the Target fails the backup, move it back to Running state and decrement Try.
// if try reaches 0, move all the Targets to Finalize and move myself to Failure.
newSessionState = r.checkWaiting(restoreSession.Status.Targets, backupConf)
case formolv1alpha1.Finalize:
// Check the TargetStatus of all the Targets. If they are all Success then move myself to Success.
// if one of the Target fails to Finalize, move it back to Finalize state and decrement Try.
// if try reaches 0, move myself to Success because the backup was a Success even if the Finalize failed.
if newSessionState = r.checkSuccess(restoreSession.Status.Targets, backupConf); newSessionState == formolv1alpha1.Failure {
r.Log.V(0).Info("One of the target did not manage to Finalize but the backup is still a Success")
newSessionState = formolv1alpha1.Success
}
case "":
newSessionState = formolv1alpha1.New
restoreSession.Status.StartTime = &metav1.Time{Time: time.Now()}