Skip to content

Commit

Permalink
add data path parameter and fixed bug with extra args
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Bigun committed Jun 26, 2024
1 parent 6a12fb8 commit a960c51
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 22 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ To further more configure commands execution provide `comma separated list` of a
| `RESTORE_TIMEOUT` | `"4s"` | Execute `pg_restore` command with that timeout |
| `RESTORE_GPG_PASSPHRASE` | `""` | If set, decrypts backup file with `gpg` using that passphrase |
| `RESTORE_EXTRA_ARGS` | `""` | If set, adds extra arguments to `pg_restore` command (reserved arguments will be ommited) |
| `DATA_PATH` | `"/tmp"` | Where to store working temporary working data |
1 change: 1 addition & 0 deletions daemon/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func Run() {
log.Info().Str("job_id", job.ID().String()).Time("next_run", nr).Msg("Successfully created dump job")
}
if cfg.Restore.Enabled {
cfg.Restore.ExtraArgs = filterArgs(cfg.Restore.ExtraArgs)
var jd gocron.JobDefinition
if cfg.Restore.Crontab != "" {
jd = gocron.CronJob(cfg.Restore.Crontab, cfg.Restore.CrontabWithSeconds)
Expand Down
1 change: 1 addition & 0 deletions daemon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type AppCfg struct {
GPG `json:"gpg" yaml:"gpg" env-prefix:"GPG_"`
ExtraArgs []string `json:"extraArgs" yaml:"extraArgs" env:"EXTRA_ARGS" env-default:""`
} `json:"restore" yaml:"restore" env-prefix:"RESTORE_"`
DataPath string `json:"dataPath" yaml:"dataPath" env:"DATA_PATH" env-default:"/tmp"`
}

var cfg AppCfg
Expand Down
56 changes: 36 additions & 20 deletions daemon/crons.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,26 @@ const (
tmpPath = "/tmp"
dmpFilename = "dmp.dump"
dmpFilenameEncrypted = "dmp.dump.gpg"
dmpFilepath = tmpPath + "/" + dmpFilename
dmpFilepathEncrypted = tmpPath + "/" + dmpFilenameEncrypted
resFilename = "res.dump"
resFilenameDecrypted = "decrypted_res.dump"
resFilepath = tmpPath + "/" + resFilename
resFilepathDecrypted = tmpPath + "/" + resFilenameDecrypted
)

func dmpFilepath() string {
return cfg.DataPath + "/" + dmpFilename
}

func dmpFilepathEncrypted() string {
return cfg.DataPath + "/" + dmpFilenameEncrypted
}

func resFilepath() string {
return cfg.DataPath + "/" + resFilename
}

func resFilepathDecrypted() string {
return cfg.DataPath + "/" + resFilenameDecrypted
}

const (
cmdPgDump = "pg_dump"
cmdPgRestore = "pg_restore"
Expand Down Expand Up @@ -104,7 +116,7 @@ func dmp(mc *minio.Client) {
fmt.Sprintf("--username=%s", cfg.Dump.Postgres.User),
argNoPassword,
argFormat,
fmt.Sprintf("--file=%s", dmpFilepath),
fmt.Sprintf("--file=%s", dmpFilepath()),
argVerbose,
}
args = append(args, cfg.Dump.ExtraArgs...)
Expand Down Expand Up @@ -133,7 +145,7 @@ func dmp(mc *minio.Client) {
}
if cfg.Dump.GPG.Passphrase != "" {
dmpLog.Info().Msg("Encrypting backup file")
if err := deleteFile(dmpFilepathEncrypted); err != nil {
if err := deleteFile(dmpFilepathEncrypted()); err != nil {
return
}
cmd = exec.CommandContext(
Expand All @@ -142,34 +154,34 @@ func dmp(mc *minio.Client) {
argSymmetric,
argBatch,
fmt.Sprintf("--passphrase=%s", cfg.Dump.GPG.Passphrase),
fmt.Sprintf("--output=%s", dmpFilepathEncrypted),
fmt.Sprintf("--output=%s", dmpFilepathEncrypted()),
argVerbose,
dmpFilepath,
dmpFilepath(),
)
cmd.Stderr = &gpgStd{}
cmd.Stdout = &gpgStd{}
if err := cmd.Run(); err != nil {
dmpLog.Error().Err(err).Msgf("Failed to run '%s' command", cmdGPG)
return
}
if err := deleteFile(dmpFilepath); err != nil {
if err := deleteFile(dmpFilepath()); err != nil {
return
}
dmpLog.Info().Msg("Successfully encrypted backup file")
f, err = os.Open(dmpFilepathEncrypted)
f, err = os.Open(dmpFilepathEncrypted())
if err != nil {
dmpLog.Error().Err(err).Msg("Failed to open encrypted backup file")
return
}
defer deleteFile(dmpFilepathEncrypted)
defer deleteFile(dmpFilepathEncrypted())
objectName = objectName + ".gpg"
} else {
f, err = os.Open(dmpFilepath)
f, err = os.Open(dmpFilepath())
if err != nil {
dmpLog.Error().Err(err).Msg("Failed to open backup file")
return
}
defer deleteFile(dmpFilepath)
defer deleteFile(dmpFilepath())
}
defer f.Close()

Expand Down Expand Up @@ -218,14 +230,18 @@ func res(mc *minio.Client) {
}) {
objects = append(objects, object)
}
if len(objects) == 0 {
resLog.Info().Msg("No backup files found on S3, skipping restore")
return
}
sort.Slice(objects, func(i, j int) bool {
return objects[i].LastModified.After(objects[j].LastModified)
})
if err := mc.FGetObject(ctx, cfg.S3.Bucket, objects[0].Key, resFilepath, minio.GetObjectOptions{}); err != nil {
if err := mc.FGetObject(ctx, cfg.S3.Bucket, objects[0].Key, resFilepath(), minio.GetObjectOptions{}); err != nil {
resLog.Error().Err(err).Msgf("Failed to get latest backup file from S3")
return
}
defer deleteFile(resFilepath)
defer deleteFile(resFilepath())
resLog.Info().Str("key", objects[0].Key).Msg("Successfully downloaded latest backup file from S3")

ctx, cancel = context.WithTimeout(ctx, cfg.Restore.Timeout)
Expand All @@ -239,21 +255,21 @@ func res(mc *minio.Client) {
argDecrypt,
argBatch,
fmt.Sprintf("--passphrase=%s", cfg.Dump.GPG.Passphrase),
fmt.Sprintf("--output=%s", resFilepathDecrypted),
fmt.Sprintf("--output=%s", resFilepathDecrypted()),
argVerbose,
resFilepath,
resFilepath(),
)
cmd.Stderr = &gpgStd{}
cmd.Stdout = &gpgStd{}
if err := cmd.Run(); err != nil {
resLog.Error().Err(err).Msgf("Failed to run '%s' command", cmdGPG)
return
}
defer deleteFile(resFilepathDecrypted)
defer deleteFile(resFilepathDecrypted())
resLog.Info().Msg("Successfully decrypted backup file")
bkpFilepath = resFilepathDecrypted
bkpFilepath = resFilepathDecrypted()
} else {
bkpFilepath = resFilepath
bkpFilepath = resFilepath()
}

resLog.Info().
Expand Down
9 changes: 7 additions & 2 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ services:
- S3_ACCESS_SECRET=minioadmin
- DUMP_ENABLED=true
- DUMP_POSTGRES_HOST=postgres
- DUMP_INTERVAL=4s
- DUMP_INTERVAL=5s
# - DUMP_CRONTAB=@weekly
# - DUMP_CRONTAB="* * * * *"
- DUMP_GPG_PASSPHRASE=secret
- DUMP_ROTATE=8s
- DUMP_EXTRA_ARGS=--verbose, -Ft, -v, --no-password
- RESTORE_ENABLED=true
- RESTORE_INTERVAL=4s
- RESTORE_GPG_PASSPHRASE=secret
- RESTORE_EXTRA_ARGS=--verbose, -Ft, -v, --no-password
- DATA_PATH=/data
volumes:
- ./data:/data
networks:
- intranet
depends_on:
Expand Down Expand Up @@ -65,6 +69,7 @@ services:
networks:
- intranet
volumes:
- ~/postgres/data:/var/lib/postgresql/data
- ./postgres/db.sql:/docker-entrypoint-initdb.d/db.sql
- ~/postgres/data1:/var/lib/postgresql/data
networks:
intranet:
3 changes: 3 additions & 0 deletions docker/postgres/db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CREATE TABLE IF NOT EXISTS public.test(ID SERIAL PRIMARY KEY);
INSERT INTO public.test()
VALUES ((), (), ());

0 comments on commit a960c51

Please sign in to comment.