From 378217e517881dbe9d356308d8345e211af63b25 Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Thu, 6 Feb 2025 15:33:08 +0100 Subject: [PATCH] Passing a full duration as retention period is more flexible --- cmd/backup/config.go | 1 + cmd/backup/prune_backups.go | 11 +++++++++-- cmd/backup/script.go | 4 ++++ docs/how-tos/automatically-prune-old-backups.md | 7 +++++-- docs/recipes/index.md | 2 +- docs/reference/index.md | 5 +++-- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/cmd/backup/config.go b/cmd/backup/config.go index b5a98d9..21ff257 100644 --- a/cmd/backup/config.go +++ b/cmd/backup/config.go @@ -38,6 +38,7 @@ type Config struct { BackupArchive string `split_words:"true" default:"/archive"` BackupCronExpression string `split_words:"true" default:"@daily"` BackupRetentionDays int32 `split_words:"true" default:"-1"` + BackupRetentionPeriod time.Duration `split_words:"true"` BackupPruningLeeway time.Duration `split_words:"true" default:"1m"` BackupPruningPrefix string `split_words:"true"` BackupStopContainerLabel string `split_words:"true"` diff --git a/cmd/backup/prune_backups.go b/cmd/backup/prune_backups.go index 370829d..6cde2ac 100644 --- a/cmd/backup/prune_backups.go +++ b/cmd/backup/prune_backups.go @@ -17,11 +17,18 @@ import ( // the given configuration. In case the given configuration would delete all // backups, it does nothing instead and logs a warning. func (s *script) pruneBackups() error { - if s.c.BackupRetentionDays < 0 { + if s.c.BackupRetentionDays < 0 && s.c.BackupRetentionPeriod == 0 { return nil } - deadline := time.Now().AddDate(0, 0, -int(s.c.BackupRetentionDays)).Add(s.c.BackupPruningLeeway) + var deadline time.Time + if s.c.BackupRetentionPeriod != 0 { + deadline = time.Now().Add(-s.c.BackupRetentionPeriod) + } else { + s.logger.Warn("Using BACKUP_RETENTION_DAYS has been deprecated and will be removed in the next major version. Please use BACKUP_RETENTION_PERIOD instead.") + deadline = time.Now().AddDate(0, 0, -int(s.c.BackupRetentionDays)) + } + deadline = deadline.Add(s.c.BackupPruningLeeway) eg := errgroup.Group{} for _, backend := range s.storages { diff --git a/cmd/backup/script.go b/cmd/backup/script.go index 56b8af8..e9a1ed7 100644 --- a/cmd/backup/script.go +++ b/cmd/backup/script.go @@ -225,6 +225,10 @@ func (s *script) init() error { s.storages = append(s.storages, dropboxBackend) } + if s.c.BackupRetentionDays > 0 && s.c.BackupRetentionPeriod > 0 { + return errwrap.Wrap(nil, "both BACKUP_RETENTION_DAYS and BACKUP_RETENTION_PERIOD were configured, which are mutually exclusive") + } + if s.c.EmailNotificationRecipient != "" { emailURL := fmt.Sprintf( "smtp://%s:%s@%s:%d/?from=%s&to=%s", diff --git a/docs/how-tos/automatically-prune-old-backups.md b/docs/how-tos/automatically-prune-old-backups.md index 26cbaa5..ff4cbe7 100644 --- a/docs/how-tos/automatically-prune-old-backups.md +++ b/docs/how-tos/automatically-prune-old-backups.md @@ -7,7 +7,8 @@ nav_order: 3 # Automatically prune old backups -When `BACKUP_RETENTION_DAYS` is configured, the command will check if there are any archives in the remote storage backend(s) or local archive that are older than the given retention value and rotate these backups away. +When `BACKUP_RETENTION_PERIOD` is configured, the command will check if there are any archives in the remote storage backend(s) or local archive that are older than the given retention value and rotate these backups away. +The value is a duration as per Go's [`time.ParseDuration`][duration]. {: .note } Be aware that this mechanism looks at __all files in the target bucket or archive__, which means that other files that are older than the given deadline are deleted as well. @@ -23,7 +24,7 @@ services: environment: BACKUP_FILENAME: backup-%Y-%m-%dT%H-%M-%S.tar.gz BACKUP_PRUNING_PREFIX: backup- - BACKUP_RETENTION_DAYS: '7' + BACKUP_RETENTION_PERIOD: '168h' volumes: - ${HOME}/backups:/archive - data:/backup/my-app-backup:ro @@ -32,3 +33,5 @@ services: volumes: data: ``` + +[duration]: https://pkg.go.dev/time#ParseDuration diff --git a/docs/recipes/index.md b/docs/recipes/index.md index 14f40f7..53c2747 100644 --- a/docs/recipes/index.md +++ b/docs/recipes/index.md @@ -280,7 +280,7 @@ services: AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY BACKUP_FILENAME: backup-%Y-%m-%dT%H-%M-%S.tar.gz BACKUP_PRUNING_PREFIX: backup- - BACKUP_RETENTION_DAYS: 7 + BACKUP_RETENTION_PERIOD: 168h volumes: - data:/backup/my-app-backup:ro - /var/run/docker.sock:/var/run/docker.sock:ro diff --git a/docs/reference/index.md b/docs/reference/index.md index 3b6cce2..6c43ff9 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -312,9 +312,10 @@ You can populate below template according to your requirements and use it as you # removal to certain files. # Define this value to enable automatic rotation of old backups. The value -# declares the number of days for which a backup is kept. +# declares the duration for which a backup is kept. It is formatted as per +# https://pkg.go.dev/time#ParseDuration -# BACKUP_RETENTION_DAYS="7" +# BACKUP_RETENTION_PERIOD="168h" # In case the duration a backup takes fluctuates noticeably in your setup # you can adjust this setting to make sure there are no race conditions