feat: add restore function
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
backup/
|
||||
backups/
|
||||
config.yaml
|
||||
compose.yaml
|
||||
ddbb
|
||||
|
||||
1
go.mod
1
go.mod
@@ -5,7 +5,6 @@ go 1.25.2
|
||||
require (
|
||||
github.com/docker/docker v28.5.1+incompatible
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
go.sum
8
go.sum
@@ -63,10 +63,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
@@ -99,8 +95,6 @@ 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/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
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=
|
||||
@@ -166,8 +160,6 @@ google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
125
pkg/backup/backup.go
Normal file
125
pkg/backup/backup.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package backup
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Id string
|
||||
Kind string
|
||||
Host string
|
||||
Port string
|
||||
Database string
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
|
||||
type ConfigList struct {
|
||||
Jobs []Config
|
||||
}
|
||||
|
||||
var outFileRoot = "/backups/"
|
||||
|
||||
func BackupJob(job Config) {
|
||||
|
||||
var err error
|
||||
switch kind := job.Kind; kind {
|
||||
case "mariadb":
|
||||
err = backupMariaDB(job)
|
||||
case "postgres":
|
||||
err = backupPostgres(job)
|
||||
case "mongodb":
|
||||
err = backupMongoDB(job)
|
||||
default:
|
||||
log.Printf("Invalid database kind for job %s", job.Id)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func backupMariaDB(cfg Config) error {
|
||||
log.Printf("Starting dump of mariadb database %s on %s", cfg.Database, cfg.Host)
|
||||
|
||||
outFileName := outFileRoot + cfg.Host + ".sql"
|
||||
outFile, err := os.Create(outFileName)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create output file: %v", err)
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
cmd := exec.Command(
|
||||
"mariadb-dump",
|
||||
"--ssl-verify-server-cert=FALSE",
|
||||
"-h", cfg.Host,
|
||||
"-u", cfg.User,
|
||||
"-p"+cfg.Password,
|
||||
"-P", cfg.Port,
|
||||
cfg.Database,
|
||||
)
|
||||
cmd.Stdout = outFile
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("Mariadb dump failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Database backup saved to %s", outFileName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func backupPostgres(cfg Config) error {
|
||||
outFileName := outFileRoot + cfg.Host + ".sql"
|
||||
outFile, err := os.Create(outFileName)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create output file: %v", err)
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
// Build pg_dump command
|
||||
cmd := exec.Command(
|
||||
"pg_dump",
|
||||
"--dbname="+fmt.Sprintf("postgresql://%s:%s@%s:%s/%s", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Database),
|
||||
)
|
||||
cmd.Stdout = outFile
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
log.Printf("Running pg_dump for database %s", cfg.Database)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("pg_dump failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Database backup saved to %s", outFileName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func backupMongoDB(cfg Config) error {
|
||||
outFileName := outFileRoot + cfg.Host + ".gz"
|
||||
|
||||
cmd := exec.Command(
|
||||
"mongodump",
|
||||
"--uri",
|
||||
fmt.Sprintf("mongodb://%s:%s@%s:%s/%s?authSource=admin", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Database),
|
||||
"--archive="+outFileName,
|
||||
"--gzip",
|
||||
)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
log.Printf("Running mongodump for database %s with gzip compression to file %s", cfg.Database, outFileName)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("mongodump failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("MongoDB backup saved to compressed archive %s", outFileName)
|
||||
return nil
|
||||
}
|
||||
@@ -2,9 +2,91 @@ package restore
|
||||
|
||||
import (
|
||||
"ddbb/pkg/backup"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var dumFileRoot = "/backups/"
|
||||
|
||||
func RestoreJob(cfg backup.Config) {
|
||||
log.Printf("Restore: %v, not yet implemented", cfg.Id)
|
||||
switch strings.ToLower(cfg.Kind) {
|
||||
case "mariadb":
|
||||
restoreMySQL(cfg)
|
||||
case "postgres":
|
||||
restorePostgres(cfg)
|
||||
case "mongodb":
|
||||
restoreMongo(cfg)
|
||||
default:
|
||||
log.Printf("unsupported database kind: %s", cfg.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
func restoreMySQL(cfg backup.Config) error {
|
||||
cmd := exec.Command(
|
||||
"mysql", "-h", cfg.Host, "-u", cfg.User, fmt.Sprintf("-p%s", cfg.Password),
|
||||
cfg.Database,
|
||||
)
|
||||
dumpFileName := dumFileRoot + cfg.Host + ".sql"
|
||||
dumpFile, err := os.Open(dumpFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dumpFile.Close()
|
||||
cmd.Stdin = dumpFile
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("mysql restore failed: %s, output: %s", err, output)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Restore job with ID %s completed successfully", cfg.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func restorePostgres(cfg backup.Config) error {
|
||||
cmd := exec.Command(
|
||||
"psql", "-h", cfg.Host, "-U", cfg.User, "-d", cfg.Database,
|
||||
"-f", "-", // read input from stdin
|
||||
)
|
||||
dumpFileName := dumFileRoot + cfg.Host + ".sql"
|
||||
dumpFile, err := os.Open(dumpFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dumpFile.Close()
|
||||
cmd.Env = append(os.Environ(), fmt.Sprintf("PGPASSWORD=%s", cfg.Password))
|
||||
cmd.Stdin = dumpFile
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("postgres restore failed: %s, output: %s", err, output)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Restore job with ID %s completed successfully", cfg.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func restoreMongo(cfg backup.Config) error {
|
||||
dumpFileName := dumFileRoot + cfg.Host + ".sql"
|
||||
cmd := exec.Command(
|
||||
"mongorestore", "--gzip", "--drop", "--archive="+dumpFileName,
|
||||
"--host", cfg.Host,
|
||||
"--username", cfg.User,
|
||||
"--password", cfg.Password,
|
||||
"--db", cfg.Database,
|
||||
)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("mongodb restore failed: %s, output: %s", err, output)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Restore job with ID %s completed successfully", cfg.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user