Allow for env substitution in backup filename (#39)

This commit is contained in:
Frederik Ring 2021-12-22 14:39:46 +01:00 committed by GitHub
parent 3a7dfe8e60
commit c062710ce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 6 deletions

View File

@ -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" # 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 # 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. # in case a value is given for this key. This has no effect on remote backups.

View File

@ -103,6 +103,7 @@ type script struct {
type config struct { type config struct {
BackupSources string `split_words:"true" default:"/backup"` BackupSources string `split_words:"true" default:"/backup"`
BackupFilename string `split_words:"true" default:"backup-%Y-%m-%dT%H-%M-%S.tar.gz"` 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"` BackupLatestSymlink string `split_words:"true"`
BackupArchive string `split_words:"true" default:"/archive"` BackupArchive string `split_words:"true" default:"/archive"`
BackupRetentionDays int32 `split_words:"true" default:"-1"` BackupRetentionDays int32 `split_words:"true" default:"-1"`
@ -153,6 +154,11 @@ func newScript() (*script, error) {
} }
s.file = path.Join("/tmp", s.c.BackupFilename) 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") _, err := os.Stat("/var/run/docker.sock")
if !os.IsNotExist(err) { 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 // takeBackup creates a tar archive of the configured backup location and
// saves it to disk. // saves it to disk.
func (s *script) takeBackup() error { func (s *script) takeBackup() error {
s.file = timeutil.Strftime(&s.start, s.file)
backupSources := s.c.BackupSources backupSources := s.c.BackupSources
if s.c.BackupFromSnapshot { if s.c.BackupFromSnapshot {

View File

@ -14,6 +14,7 @@ services:
backup: &default_backup_service backup: &default_backup_service
image: offen/docker-volume-backup:${TEST_VERSION} image: offen/docker-volume-backup:${TEST_VERSION}
hostname: hostnametoken
depends_on: depends_on:
- minio - minio
restart: always restart: always
@ -23,8 +24,9 @@ services:
AWS_ENDPOINT: minio:9000 AWS_ENDPOINT: minio:9000
AWS_ENDPOINT_PROTO: http AWS_ENDPOINT_PROTO: http
AWS_S3_BUCKET_NAME: backup AWS_S3_BUCKET_NAME: backup
BACKUP_FILENAME: test.tar.gz BACKUP_FILENAME_EXPAND: 'true'
BACKUP_LATEST_SYMLINK: test.latest.tar.gz.gpg BACKUP_FILENAME: test-$$HOSTNAME.tar.gz
BACKUP_LATEST_SYMLINK: test-$$HOSTNAME.latest.tar.gz.gpg
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ? BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7} BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
BACKUP_PRUNING_LEEWAY: 5s BACKUP_PRUNING_LEEWAY: 5s

View File

@ -14,12 +14,12 @@ docker-compose exec backup backup
docker run --rm -it \ docker run --rm -it \
-v compose_backup_data:/data alpine \ -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." echo "[TEST:PASS] Found relevant files in untared remote backup."
test -L ./local/test.latest.tar.gz.gpg test -L ./local/test-hostnametoken.latest.tar.gz.gpg
echo 1234secret | gpg -d --yes --passphrase-fd 0 ./local/test.tar.gz.gpg > ./local/decrypted.tar.gz 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 tar -xf ./local/decrypted.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db
rm ./local/decrypted.tar.gz rm ./local/decrypted.tar.gz
test -L /tmp/backup/app_data/db.link test -L /tmp/backup/app_data/db.link