From ea72298a0f32eb097c2610107b6189388703302d Mon Sep 17 00:00:00 2001 From: RamiusLr Date: Thu, 6 Nov 2025 09:52:24 +0100 Subject: [PATCH] feat: add cron --- cmd/ddbb/main.go | 7 ++++++- go.mod | 1 + go.sum | 2 ++ pkg/api/api.go | 7 +++++++ pkg/cron/cron.go | 28 ++++++++++++++++++++++++++++ pkg/restore/restore.go | 14 +++++++++----- 6 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 pkg/cron/cron.go diff --git a/cmd/ddbb/main.go b/cmd/ddbb/main.go index bc86984..d5766e6 100644 --- a/cmd/ddbb/main.go +++ b/cmd/ddbb/main.go @@ -1,11 +1,16 @@ package main import ( - api "ddbb/pkg/api" + "ddbb/pkg/api" + "ddbb/pkg/cron" "log" ) func main() { + // Set up the cron job + cron.ScheduleBackupFromEnv() + + // Run the api endpoint r := api.SetupRouter() err := r.Run(":12345") if err != nil { diff --git a/go.mod b/go.mod index d04bf9c..a13d71e 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.25.2 require ( github.com/docker/docker v28.5.1+incompatible github.com/gin-gonic/gin v1.11.0 + github.com/robfig/cron/v3 v3.0.1 ) require ( diff --git a/go.sum b/go.sum index 5e5845b..a430dc3 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,8 @@ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/pkg/api/api.go b/pkg/api/api.go index 36c577b..8b91c8f 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -17,6 +17,13 @@ var ( statusMutex sync.Mutex ) +func BackupAllDatabases() { + allBackups, _ := docker.GetBackupConfigsFromContainers() + for _, job := range allBackups { + backup.BackupJob(job) + } +} + // Dump any database giving an Id func triggerDump(c *gin.Context) { // Extract backup job name from the form POST data diff --git a/pkg/cron/cron.go b/pkg/cron/cron.go new file mode 100644 index 0000000..274a34b --- /dev/null +++ b/pkg/cron/cron.go @@ -0,0 +1,28 @@ +package cron + +import ( + "ddbb/pkg/api" + "github.com/robfig/cron/v3" + "log" + "os" +) + +func ScheduleBackupFromEnv() { + expr := os.Getenv("BACKUP_CRON") + if expr == "" { + log.Fatal("Environment variable BACKUP_CRON not set") + } + + c := cron.New() + + _, err := c.AddFunc(expr, func() { + log.Println("Starting scheduled backup") + api.BackupAllDatabases() + }) + if err != nil { + log.Fatalf("Invalid cron expression in BACKUP_CRON: %v", err) + } + + c.Start() + // defer c.Stop() on application shutdown if needed +} diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 28ba3d4..2561489 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -9,7 +9,7 @@ import ( "strings" ) -var dumFileRoot = "/backups/" +var dumpFileRoot = "/backups/" func RestoreJob(cfg backup.Config) { switch strings.ToLower(cfg.Kind) { @@ -26,10 +26,14 @@ func RestoreJob(cfg backup.Config) { func restoreMySQL(cfg backup.Config) error { cmd := exec.Command( - "mysql", "-h", cfg.Host, "-u", cfg.User, fmt.Sprintf("-p%s", cfg.Password), + "mariadb", + "--ssl-verify-server-cert=FALSE", + "-h", cfg.Host, + "-u", cfg.User, + fmt.Sprintf("-p%s", cfg.Password), cfg.Database, ) - dumpFileName := dumFileRoot + cfg.Host + ".sql" + dumpFileName := dumpFileRoot + cfg.Host + ".sql" dumpFile, err := os.Open(dumpFileName) if err != nil { return err @@ -52,7 +56,7 @@ func restorePostgres(cfg backup.Config) error { "psql", "-h", cfg.Host, "-U", cfg.User, "-d", cfg.Database, "-f", "-", // read input from stdin ) - dumpFileName := dumFileRoot + cfg.Host + ".sql" + dumpFileName := dumpFileRoot + cfg.Host + ".sql" dumpFile, err := os.Open(dumpFileName) if err != nil { return err @@ -72,7 +76,7 @@ func restorePostgres(cfg backup.Config) error { } func restoreMongo(cfg backup.Config) error { - dumpFileName := dumFileRoot + cfg.Host + ".gz" + dumpFileName := dumpFileRoot + cfg.Host + ".gz" cmd := exec.Command( "mongorestore", "--archive", "--gzip", "--drop", "--archive="+dumpFileName, "--uri",