Reworked the scheduling. Tasks are run by SessionState now and not by Target

This commit is contained in:
Jean-Marc ANDRE 2023-02-27 00:54:43 +01:00
parent e3aa5f3844
commit d91f1e3f5d
3 changed files with 91 additions and 70 deletions

View File

@ -53,77 +53,93 @@ func (r *BackupSessionReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, err
}
targetName := os.Getenv(formolv1alpha1.TARGET_NAME)
// targetName := os.Getenv(formolv1alpha1.TARGET_NAME)
// we don't want a copy because we will modify and update it.
currentTargetStatus := &(backupSession.Status.Targets[len(backupSession.Status.Targets)-1])
currentTarget := backupConf.Spec.Targets[len(backupSession.Status.Targets)-1]
var target formolv1alpha1.Target
var targetStatus *formolv1alpha1.TargetStatus
var result error
if currentTargetStatus.TargetName == targetName {
// The current task is for us
var newSessionState formolv1alpha1.SessionState
switch currentTargetStatus.SessionState {
case formolv1alpha1.New:
r.Log.V(0).Info("New session, move to Initializing state")
newSessionState = formolv1alpha1.Init
case formolv1alpha1.Init:
r.Log.V(0).Info("Start to run the backup initializing steps is any")
// Runs the Steps functions in chroot env
if result = r.runInitializeBackupSteps(currentTarget); result != nil {
r.Log.Error(result, "unable to run the initialization steps")
newSessionState = formolv1alpha1.Finalize
} else {
newSessionState = formolv1alpha1.Running
}
case formolv1alpha1.Running:
r.Log.V(0).Info("Running state. Do the backup")
// Actually do the backup with restic
switch currentTarget.BackupType {
case formolv1alpha1.JobKind:
if backupResult, err := r.backupJob(backupSession.Name, currentTarget); err != nil {
r.Log.Error(err, "unable to run backup job", "target", targetName)
} else {
r.Log.V(0).Info("Backup Job is over", "target", targetName, "snapshotID", backupResult.SnapshotId, "duration", backupResult.Duration)
currentTargetStatus.SnapshotId = backupResult.SnapshotId
currentTargetStatus.Duration = &metav1.Duration{Duration: time.Now().Sub(currentTargetStatus.StartTime.Time)}
}
case formolv1alpha1.OnlineKind:
backupPaths := strings.Split(os.Getenv(formolv1alpha1.BACKUP_PATHS), string(os.PathListSeparator))
if backupResult, result := r.backupPaths(backupSession.Name, backupPaths); result != nil {
r.Log.Error(result, "unable to backup paths", "target name", targetName, "paths", backupPaths)
} else {
r.Log.V(0).Info("Backup of the paths is over", "target name", targetName, "paths", backupPaths,
"snapshotID", backupResult.SnapshotId, "duration", backupResult.Duration)
currentTargetStatus.SnapshotId = backupResult.SnapshotId
currentTargetStatus.Duration = &metav1.Duration{Duration: time.Now().Sub(currentTargetStatus.StartTime.Time)}
}
}
newSessionState = formolv1alpha1.Finalize
case formolv1alpha1.Finalize:
r.Log.V(0).Info("Backup is over. Run the finalize steps is any")
// Runs the finalize Steps functions in chroot env
if result = r.runFinalizeBackupSteps(currentTarget); result != nil {
r.Log.Error(err, "unable to run finalize steps")
}
if currentTargetStatus.SnapshotId == "" {
newSessionState = formolv1alpha1.Failure
} else {
newSessionState = formolv1alpha1.Success
}
case formolv1alpha1.Success:
r.Log.V(0).Info("Backup is over")
case formolv1alpha1.Failure:
r.Log.V(0).Info("Backup is over")
}
if newSessionState != "" {
currentTargetStatus.SessionState = newSessionState
err := r.Status().Update(ctx, &backupSession)
if err != nil {
r.Log.Error(err, "unable to update BackupSession status")
}
return ctrl.Result{}, err
targetName := os.Getenv(formolv1alpha1.TARGET_NAME)
for i, t := range backupConf.Spec.Targets {
if t.TargetName == targetName {
target = t
targetStatus = &(backupSession.Status.Targets[i])
break
}
}
var newSessionState formolv1alpha1.SessionState
switch targetStatus.SessionState {
case formolv1alpha1.New:
// New session move to Initializing
r.Log.V(0).Info("New session. Move to Initializing state")
newSessionState = formolv1alpha1.Initializing
case formolv1alpha1.Initializing:
// Run the initializing Steps and then move to Initialized or Failure
r.Log.V(0).Info("Start to run the backup initializing steps is any")
// Runs the Steps functions in chroot env
if err := r.runInitializeBackupSteps(target); err != nil {
r.Log.Error(err, "unable to run the initialization steps")
newSessionState = formolv1alpha1.Failure
} else {
r.Log.V(0).Info("Done with the initializing Steps. Move to Initialized state")
newSessionState = formolv1alpha1.Initialized
}
case formolv1alpha1.Running:
// Actually do the backup and move to Waiting or Failure
r.Log.V(0).Info("Running state. Do the backup")
// Actually do the backup with restic
newSessionState = formolv1alpha1.Waiting
switch target.BackupType {
case formolv1alpha1.JobKind:
if backupResult, err := r.backupJob(backupSession.Name, target); err != nil {
r.Log.Error(err, "unable to run backup job", "target", targetName)
newSessionState = formolv1alpha1.Failure
} else {
r.Log.V(0).Info("Backup Job is over", "target", targetName, "snapshotID", backupResult.SnapshotId, "duration", backupResult.Duration)
targetStatus.SnapshotId = backupResult.SnapshotId
targetStatus.Duration = &metav1.Duration{Duration: time.Now().Sub(targetStatus.StartTime.Time)}
}
case formolv1alpha1.OnlineKind:
backupPaths := strings.Split(os.Getenv(formolv1alpha1.BACKUP_PATHS), string(os.PathListSeparator))
if backupResult, result := r.backupPaths(backupSession.Name, backupPaths); result != nil {
r.Log.Error(result, "unable to backup paths", "target name", targetName, "paths", backupPaths)
newSessionState = formolv1alpha1.Failure
} else {
r.Log.V(0).Info("Backup of the paths is over", "target name", targetName, "paths", backupPaths,
"snapshotID", backupResult.SnapshotId, "duration", backupResult.Duration)
targetStatus.SnapshotId = backupResult.SnapshotId
targetStatus.Duration = &metav1.Duration{Duration: time.Now().Sub(targetStatus.StartTime.Time)}
}
}
r.Log.V(0).Info("Backup is over and is a success. Move to Waiting state")
case formolv1alpha1.Finalize:
// Run the finalize Steps and move to Success or Failure
r.Log.V(0).Info("Backup is over. Run the finalize steps is any")
// Runs the finalize Steps functions in chroot env
if result = r.runFinalizeBackupSteps(target); result != nil {
r.Log.Error(err, "unable to run finalize steps")
}
if targetStatus.SnapshotId == "" {
newSessionState = formolv1alpha1.Failure
} else {
newSessionState = formolv1alpha1.Success
}
case formolv1alpha1.Success:
// Target backup is a success
r.Log.V(0).Info("Backup was a success")
case formolv1alpha1.Failure:
// Target backup is a failure
}
if newSessionState != "" {
targetStatus.SessionState = newSessionState
err := r.Status().Update(ctx, &backupSession)
if err != nil {
r.Log.Error(err, "unable to update BackupSession status")
}
return ctrl.Result{}, err
}
return ctrl.Result{}, result
}

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
"io"
"io/fs"
"io/ioutil"
corev1 "k8s.io/api/core/v1"
"os"
@ -181,7 +182,7 @@ func (r *BackupSessionReconciler) runInitializeBackupSteps(target formolv1alpha1
// Runs the given command in the target container chroot
func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args ...string) error {
env := regexp.MustCompile(`/proc/[0-9]+/environ`)
if err := filepath.Walk("/proc", func(path string, info os.FileInfo, err error) error {
if err := filepath.WalkDir("/proc", func(path string, info fs.DirEntry, err error) error {
if err != nil {
return nil
}
@ -194,7 +195,7 @@ func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args .
content, err := ioutil.ReadFile(path)
// cannot read environ file. not the process we want to backup
if err != nil {
return filepath.SkipDir
return fs.SkipDir
}
// Loops over the process environement variable looking for TARGETCONTAINER_TAG
for _, env := range bytes.Split(content, []byte{'\000'}) {
@ -223,7 +224,11 @@ func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args .
r.Log.V(0).Info("cmd output", "output", scanner.Text())
}
return cmd.Wait()
if err := cmd.Wait(); err != nil {
return err
} else {
return filepath.SkipAll
}
}
}
}

2
formol

@ -1 +1 @@
Subproject commit b42bd46efe822ddad250448d7ed2578efe5460f7
Subproject commit b5a217bc3a536095084b48e19f935bc1508baedf