// Copyright 2024 - offen.software // SPDX-License-Identifier: MPL-2.0 package main import ( "fmt" "slices" "strings" "time" "github.com/offen/docker-volume-backup/internal/errwrap" "golang.org/x/sync/errgroup" ) // pruneBackups rotates away backups from local and remote storages using // 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 { return nil } deadline := time.Now().AddDate(0, 0, -int(s.c.BackupRetentionDays)).Add(s.c.BackupPruningLeeway) eg := errgroup.Group{} for _, backend := range s.storages { b := backend eg.Go(func() error { if skipPrune(b.Name(), s.c.BackupSkipBackendsFromPrune) { s.logger.Info( fmt.Sprintf("Skipping pruning for backend `%s`.", b.Name()), ) return nil } stats, err := b.Prune(deadline, s.c.BackupPruningPrefix) if err != nil { return err } s.stats.Lock() s.stats.Storages[b.Name()] = StorageStats{ Total: stats.Total, Pruned: stats.Pruned, } s.stats.Unlock() return nil }) } if err := eg.Wait(); err != nil { return errwrap.Wrap(err, "error pruning backups") } return nil } // skipPrune returns true if the given backend name is contained in the // list of skipped backends. func skipPrune(name string, skippedBackends []string) bool { return slices.ContainsFunc( skippedBackends, func(b string) bool { return strings.EqualFold(b, name) // ignore case on both sides }, ) }