Compare commits

..

No commits in common. "994b792d97623db85a4b938da65aa06186208133" and "d4231768d716754dbe85435359bd7ac8befb9fb7" have entirely different histories.

9 changed files with 107 additions and 140 deletions

View File

@ -1,6 +1,6 @@
# Build a small image # Build a small image
FROM --platform=linux/amd64 alpine:3 FROM --platform=linux/amd64 alpine:3
RUN apk add --no-cache su-exec restic RUN apk add --no-cache su-exec restic postgresql-client
COPY ./bin/formolcli /usr/local/bin COPY ./bin/formolcli /usr/local/bin
# Command to run # Command to run

View File

@ -1,8 +0,0 @@
# Build a small image
FROM --platform=linux/arm64 alpine:3
RUN apk add --no-cache su-exec restic postgresql-client
COPY ./bin/formolcli /usr/local/bin
# Command to run
ENTRYPOINT ["/usr/local/bin/formolcli"]
CMD ["--help"]

51
cmd/backupsession.go Normal file
View File

@ -0,0 +1,51 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"fmt"
"github.com/desmo999r/formolcli/backupsession"
"github.com/desmo999r/formolcli/controllers"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
)
var createBackupSessionCmd = &cobra.Command{
Use: "create",
Short: "Create a backupsession",
Run: func(cmd *cobra.Command, args []string) {
name, _ := cmd.Flags().GetString("name")
namespace, _ := cmd.Flags().GetString("namespace")
fmt.Println("create backupsession called")
backupsession.CreateBackupSession(corev1.ObjectReference{
Namespace: namespace,
Name: name,
})
},
}
var startServerCmd = &cobra.Command{
Use: "server",
Short: "Start a BackupSession controller",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("starts backupsession controller")
controllers.StartServer()
},
}
// backupsessionCmd represents the backupsession command
var backupSessionCmd = &cobra.Command{
Use: "backupsession",
Short: "All the BackupSession related commands",
}
func init() {
rootCmd.AddCommand(backupSessionCmd)
backupSessionCmd.AddCommand(createBackupSessionCmd)
backupSessionCmd.AddCommand(startServerCmd)
createBackupSessionCmd.Flags().String("namespace", "", "The namespace of the BackupConfiguration containing the information about the backup.")
createBackupSessionCmd.Flags().String("name", "", "The name of the BackupConfiguration containing the information about the backup.")
createBackupSessionCmd.MarkFlagRequired("namespace")
createBackupSessionCmd.MarkFlagRequired("name")
}

View File

@ -4,42 +4,11 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
package cmd package cmd
import ( import (
"fmt"
"github.com/desmo999r/formolcli/backupsession"
"github.com/desmo999r/formolcli/controllers"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"os" "os"
"github.com/spf13/cobra"
) )
var createBackupSessionCmd = &cobra.Command{
Use: "create",
Short: "Create a backupsession",
Run: func(cmd *cobra.Command, args []string) {
name, _ := cmd.Flags().GetString("name")
namespace, _ := cmd.Flags().GetString("namespace")
fmt.Println("create backupsession called")
backupsession.CreateBackupSession(corev1.ObjectReference{
Namespace: namespace,
Name: name,
})
},
}
var startServerCmd = &cobra.Command{
Use: "server",
Short: "Start a BackupSession / RestoreSession controller",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("starts backupsession controller")
controllers.StartServer()
},
}
var backupSessionCmd = &cobra.Command{
Use: "backupsession",
Short: "All the BackupSession related commands",
}
// rootCmd represents the base command when called without any subcommands // rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "formolcli", Use: "formolcli",
@ -65,11 +34,13 @@ func Execute() {
} }
func init() { func init() {
rootCmd.AddCommand(backupSessionCmd) // Here you will define your flags and configuration settings.
backupSessionCmd.AddCommand(createBackupSessionCmd) // Cobra supports persistent flags, which, if defined here,
rootCmd.AddCommand(startServerCmd) // will be global for your application.
createBackupSessionCmd.Flags().String("namespace", "", "The namespace of the BackupConfiguration containing the information about the backup.")
createBackupSessionCmd.Flags().String("name", "", "The name of the BackupConfiguration containing the information about the backup.") // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.formolcli.yaml)")
createBackupSessionCmd.MarkFlagRequired("namespace")
createBackupSessionCmd.MarkFlagRequired("name") // Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
} }

View File

@ -12,6 +12,49 @@ import (
"strings" "strings"
) )
const (
RESTIC_EXEC = "/usr/bin/restic"
)
func (r *BackupSessionReconciler) setResticEnv(backupConf formolv1alpha1.BackupConfiguration) error {
repo := formolv1alpha1.Repo{}
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: backupConf.Spec.Repository,
}, &repo); err != nil {
r.Log.Error(err, "unable to get repo")
return err
}
if repo.Spec.Backend.S3 != nil {
os.Setenv(formolv1alpha1.RESTIC_REPOSITORY, fmt.Sprintf("s3:http://%s/%s/%s-%s",
repo.Spec.Backend.S3.Server,
repo.Spec.Backend.S3.Bucket,
strings.ToUpper(backupConf.Namespace),
strings.ToLower(backupConf.Name)))
data := r.getSecretData(repo.Spec.RepositorySecrets)
os.Setenv(formolv1alpha1.AWS_SECRET_ACCESS_KEY, string(data[formolv1alpha1.AWS_SECRET_ACCESS_KEY]))
os.Setenv(formolv1alpha1.AWS_ACCESS_KEY_ID, string(data[formolv1alpha1.AWS_ACCESS_KEY_ID]))
os.Setenv(formolv1alpha1.RESTIC_PASSWORD, string(data[formolv1alpha1.RESTIC_PASSWORD]))
}
return nil
}
func (r *BackupSessionReconciler) checkRepo() error {
r.Log.V(0).Info("Checking repo")
if err := exec.Command(RESTIC_EXEC, "unlock").Run(); err != nil {
r.Log.Error(err, "unable to unlock repo", "repo", os.Getenv(formolv1alpha1.RESTIC_REPOSITORY))
}
output, err := exec.Command(RESTIC_EXEC, "check").CombinedOutput()
if err != nil {
r.Log.V(0).Info("Initializing new repo")
output, err = exec.Command(RESTIC_EXEC, "init").CombinedOutput()
if err != nil {
r.Log.Error(err, "something went wrong during repo init", "output", output)
}
}
return err
}
type BackupResult struct { type BackupResult struct {
SnapshotId string SnapshotId string
Duration float64 Duration float64

View File

@ -1,37 +0,0 @@
package controllers
import (
"context"
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log"
)
type RestoreSessionReconciler struct {
Session
}
func (r *RestoreSessionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
r.Log = log.FromContext(ctx)
r.Context = ctx
restoreSession := formolv1alpha1.RestoreSession{}
err := r.Get(r.Context, req.NamespacedName, &restoreSession)
if err != nil {
if errors.IsNotFound(err) {
return ctrl.Result{}, nil
}
return ctrl.Result{}, err
}
switch restoreSession.Status.SessionState {
case formolv1alpha1.New:
}
return ctrl.Result{}, nil
}
func (r *RestoreSessionReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&formolv1alpha1.RestoreSession{}).
Complete(r)
}

View File

@ -37,16 +37,6 @@ func StartServer() {
setupLog.Error(err, "unable to create manager") setupLog.Error(err, "unable to create manager")
os.Exit(1) os.Exit(1)
} }
if err = (&RestoreSessionReconciler{
Session: Session{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
},
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "RestoreSession")
os.Exit(1)
}
if err = (&BackupSessionReconciler{ if err = (&BackupSessionReconciler{
Session: Session{ Session: Session{
Client: mgr.GetClient(), Client: mgr.GetClient(),

View File

@ -27,49 +27,6 @@ type Session struct {
Namespace string Namespace string
} }
const (
RESTIC_EXEC = "/usr/bin/restic"
)
func (s Session) setResticEnv(backupConf formolv1alpha1.BackupConfiguration) error {
repo := formolv1alpha1.Repo{}
if err := s.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: backupConf.Spec.Repository,
}, &repo); err != nil {
s.Log.Error(err, "unable to get repo")
return err
}
if repo.Spec.Backend.S3 != nil {
os.Setenv(formolv1alpha1.RESTIC_REPOSITORY, fmt.Sprintf("s3:http://%s/%s/%s-%s",
repo.Spec.Backend.S3.Server,
repo.Spec.Backend.S3.Bucket,
strings.ToUpper(backupConf.Namespace),
strings.ToLower(backupConf.Name)))
data := s.getSecretData(repo.Spec.RepositorySecrets)
os.Setenv(formolv1alpha1.AWS_SECRET_ACCESS_KEY, string(data[formolv1alpha1.AWS_SECRET_ACCESS_KEY]))
os.Setenv(formolv1alpha1.AWS_ACCESS_KEY_ID, string(data[formolv1alpha1.AWS_ACCESS_KEY_ID]))
os.Setenv(formolv1alpha1.RESTIC_PASSWORD, string(data[formolv1alpha1.RESTIC_PASSWORD]))
}
return nil
}
func (s Session) checkRepo() error {
s.Log.V(0).Info("Checking repo")
if err := exec.Command(RESTIC_EXEC, "unlock").Run(); err != nil {
s.Log.Error(err, "unable to unlock repo", "repo", os.Getenv(formolv1alpha1.RESTIC_REPOSITORY))
}
output, err := exec.Command(RESTIC_EXEC, "check").CombinedOutput()
if err != nil {
s.Log.V(0).Info("Initializing new repo")
output, err = exec.Command(RESTIC_EXEC, "init").CombinedOutput()
if err != nil {
s.Log.Error(err, "something went wrong during repo init", "output", output)
}
}
return err
}
func (s Session) getSecretData(name string) map[string][]byte { func (s Session) getSecretData(name string) map[string][]byte {
secret := corev1.Secret{} secret := corev1.Secret{}
namespace := os.Getenv(formolv1alpha1.POD_NAMESPACE) namespace := os.Getenv(formolv1alpha1.POD_NAMESPACE)

2
formol

@ -1 +1 @@
Subproject commit 3486ad2efe7bcf40990212299a87aaa70f88965f Subproject commit 19d74cda40b40eaea1d633f30400abd46d898f7a