diff --git a/controllers/backupconfiguration_controller_helpers.go b/controllers/backupconfiguration_controller_helpers.go index ec13f9b..7b46a9f 100644 --- a/controllers/backupconfiguration_controller_helpers.go +++ b/controllers/backupconfiguration_controller_helpers.go @@ -1,3 +1,19 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package controllers import ( diff --git a/controllers/backupsession_controller.go b/controllers/backupsession_controller.go index 3f744d7..3f09074 100644 --- a/controllers/backupsession_controller.go +++ b/controllers/backupsession_controller.go @@ -18,9 +18,11 @@ package controllers import ( "context" + "time" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -31,6 +33,7 @@ import ( ) const ( + sessionState string = ".metadata.state" finalizerName string = "finalizer.backupsession.formol.desmojim.fr" ) @@ -46,15 +49,6 @@ type BackupSessionReconciler struct { //+kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupsessions/status,verbs=get;update;patch //+kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupsessions/finalizers,verbs=update -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the BackupSession object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.1/pkg/reconcile func (r *BackupSessionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { r.Log = log.FromContext(ctx) r.Context = ctx @@ -97,11 +91,41 @@ func (r *BackupSessionReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, err } + switch backupSession.Status.SessionState { + case formolv1alpha1.New: + 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 + } + default: + // BackupSession has just been created + backupSession.Status.SessionState = formolv1alpha1.New + backupSession.Status.StartTime = &metav1.Time{Time: time.Now()} + if err := r.Status().Update(ctx, &backupSession); err != nil { + r.Log.Error(err, "unable to update BackupSession.Status") + return ctrl.Result{}, err + } + } + return ctrl.Result{}, nil } // SetupWithManager sets up the controller with the Manager. func (r *BackupSessionReconciler) SetupWithManager(mgr ctrl.Manager) error { + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &formolv1alpha1.BackupSession{}, + sessionState, + func(rawObj client.Object) []string { + session := rawObj.(*formolv1alpha1.BackupSession) + return []string{ + string(session.Status.SessionState), + } + }); err != nil { + return err + } return ctrl.NewControllerManagedBy(mgr). For(&formolv1alpha1.BackupSession{}). Complete(r) diff --git a/controllers/backupsession_controller_helpers.go b/controllers/backupsession_controller_helpers.go new file mode 100644 index 0000000..52341e4 --- /dev/null +++ b/controllers/backupsession_controller_helpers.go @@ -0,0 +1,45 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1" + "k8s.io/apimachinery/pkg/fields" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func (r *BackupSessionReconciler) isBackupOngoing(backupConf formolv1alpha1.BackupConfiguration) bool { + backupSessionList := &formolv1alpha1.BackupSessionList{} + if err := r.List(r.Context, backupSessionList, + client.InNamespace(backupConf.Namespace), client.MatchingFieldsSelector{ + Selector: fields.SelectorFromSet(fields.Set{ + sessionState: "Running", + }), + }); err != nil { + r.Log.Error(err, "unable to get backupsessionlist") + return true + } + return len(backupSessionList.Items) > 0 +} + +func (r *BackupSessionReconciler) startNextTask(backupSession formolv1alpha1.BackupSession, backupConf formolv1alpha1.BackupConfiguration) (formolv1alpha1.TargetStatus, error) { + nextTargetIndex := len(backupSession.Status.Targets) + if nextTargetIndex < len(backupConf.Spec.Targets) { + nextTarget := backupConf.Spec.Targets[nextTargetIndex] + } + return nil, nil +}