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

View File

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1" formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
"io" "io"
"io/fs"
"io/ioutil" "io/ioutil"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"os" "os"
@ -181,7 +182,7 @@ func (r *BackupSessionReconciler) runInitializeBackupSteps(target formolv1alpha1
// Runs the given command in the target container chroot // Runs the given command in the target container chroot
func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args ...string) error { func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args ...string) error {
env := regexp.MustCompile(`/proc/[0-9]+/environ`) 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 { if err != nil {
return nil return nil
} }
@ -194,7 +195,7 @@ func (r *BackupSessionReconciler) runTargetContainerChroot(runCmd string, args .
content, err := ioutil.ReadFile(path) content, err := ioutil.ReadFile(path)
// cannot read environ file. not the process we want to backup // cannot read environ file. not the process we want to backup
if err != nil { if err != nil {
return filepath.SkipDir return fs.SkipDir
} }
// Loops over the process environement variable looking for TARGETCONTAINER_TAG // Loops over the process environement variable looking for TARGETCONTAINER_TAG
for _, env := range bytes.Split(content, []byte{'\000'}) { 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()) 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