Passing a full duration as retention period is more flexible

This commit is contained in:
Frederik Ring 2025-02-06 15:33:08 +01:00
parent 23756074f9
commit 378217e517
6 changed files with 23 additions and 7 deletions

View File

@ -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"`

View File

@ -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 {

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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