From c062710ce885818efa3490f116f414001ebb8145 Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Wed, 22 Dec 2021 14:39:46 +0100 Subject: [PATCH] Allow for env substitution in backup filename (#39) --- README.md | 10 ++++++++++ cmd/backup/main.go | 7 ++++++- test/compose/docker-compose.yml | 6 ++++-- test/compose/run.sh | 6 +++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e6a1c3a..653e0f0 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,16 @@ You can populate below template according to your requirements and use it as you # BACKUP_FILENAME="backup-%Y-%m-%dT%H-%M-%S.tar.gz" +# Setting BACKUP_FILENAME_EXPAND to true allows for environment variable +# placeholders in BACKUP_FILENAME and in BACKUP_LATEST_SYMLINK that will get +# expanded at runtime, e.g. `backup-$HOSTNAME-%Y-%m-%dT%H-%M-%S.tar.gz`. +# Expansion happens before interpolating strftime tokens. +# It is disabled by default. +# Please note that you will need to escape the `$` when providing the value +# in a docker-compose.yml file, i.e. using $$VAR instead of $VAR. + +# BACKUP_FILENAME_TEMPLATE="true" + # When storing local backups, a symlink to the latest backup can be created # in case a value is given for this key. This has no effect on remote backups. diff --git a/cmd/backup/main.go b/cmd/backup/main.go index 77b1a2c..38651be 100644 --- a/cmd/backup/main.go +++ b/cmd/backup/main.go @@ -103,6 +103,7 @@ type script struct { type config struct { BackupSources string `split_words:"true" default:"/backup"` BackupFilename string `split_words:"true" default:"backup-%Y-%m-%dT%H-%M-%S.tar.gz"` + BackupFilenameExpand bool `split_words:"true"` BackupLatestSymlink string `split_words:"true"` BackupArchive string `split_words:"true" default:"/archive"` BackupRetentionDays int32 `split_words:"true" default:"-1"` @@ -153,6 +154,11 @@ func newScript() (*script, error) { } s.file = path.Join("/tmp", s.c.BackupFilename) + if s.c.BackupFilenameExpand { + s.file = os.ExpandEnv(s.file) + s.c.BackupLatestSymlink = os.ExpandEnv(s.c.BackupLatestSymlink) + } + s.file = timeutil.Strftime(&s.start, s.file) _, err := os.Stat("/var/run/docker.sock") if !os.IsNotExist(err) { @@ -413,7 +419,6 @@ func (s *script) stopContainers() (func() error, error) { // takeBackup creates a tar archive of the configured backup location and // saves it to disk. func (s *script) takeBackup() error { - s.file = timeutil.Strftime(&s.start, s.file) backupSources := s.c.BackupSources if s.c.BackupFromSnapshot { diff --git a/test/compose/docker-compose.yml b/test/compose/docker-compose.yml index b9ade86..25db200 100644 --- a/test/compose/docker-compose.yml +++ b/test/compose/docker-compose.yml @@ -14,6 +14,7 @@ services: backup: &default_backup_service image: offen/docker-volume-backup:${TEST_VERSION} + hostname: hostnametoken depends_on: - minio restart: always @@ -23,8 +24,9 @@ services: AWS_ENDPOINT: minio:9000 AWS_ENDPOINT_PROTO: http AWS_S3_BUCKET_NAME: backup - BACKUP_FILENAME: test.tar.gz - BACKUP_LATEST_SYMLINK: test.latest.tar.gz.gpg + BACKUP_FILENAME_EXPAND: 'true' + BACKUP_FILENAME: test-$$HOSTNAME.tar.gz + BACKUP_LATEST_SYMLINK: test-$$HOSTNAME.latest.tar.gz.gpg BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ? BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7} BACKUP_PRUNING_LEEWAY: 5s diff --git a/test/compose/run.sh b/test/compose/run.sh index 22fe8c7..cca19b2 100755 --- a/test/compose/run.sh +++ b/test/compose/run.sh @@ -14,12 +14,12 @@ docker-compose exec backup backup docker run --rm -it \ -v compose_backup_data:/data alpine \ - ash -c 'apk add gnupg && echo 1234secret | gpg -d --pinentry-mode loopback --passphrase-fd 0 --yes /data/backup/test.tar.gz.gpg > /tmp/test.tar.gz && tar -xf /tmp/test.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db' + ash -c 'apk add gnupg && echo 1234secret | gpg -d --pinentry-mode loopback --passphrase-fd 0 --yes /data/backup/test-hostnametoken.tar.gz.gpg > /tmp/test-hostnametoken.tar.gz && tar -xf /tmp/test-hostnametoken.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db' echo "[TEST:PASS] Found relevant files in untared remote backup." -test -L ./local/test.latest.tar.gz.gpg -echo 1234secret | gpg -d --yes --passphrase-fd 0 ./local/test.tar.gz.gpg > ./local/decrypted.tar.gz +test -L ./local/test-hostnametoken.latest.tar.gz.gpg +echo 1234secret | gpg -d --yes --passphrase-fd 0 ./local/test-hostnametoken.tar.gz.gpg > ./local/decrypted.tar.gz tar -xf ./local/decrypted.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db rm ./local/decrypted.tar.gz test -L /tmp/backup/app_data/db.link