feat: keep a rolling backup of the last 10 config versions

This commit is contained in:
garethgeorge
2024-05-18 19:28:19 -07:00
parent 6ded72b684
commit cc7d79b1dc
+47 -3
View File
@@ -7,12 +7,17 @@ import (
"os"
"path/filepath"
"sync"
"time"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"github.com/natefinch/atomic"
"google.golang.org/protobuf/encoding/protojson"
)
var (
configKeepVersions = 10
)
type JsonFileStore struct {
Path string
mu sync.Mutex
@@ -49,17 +54,22 @@ func (f *JsonFileStore) Update(config *v1.Config) error {
Multiline: true,
}.Marshal(config)
if err != nil {
return fmt.Errorf("failed to marshal config: %w", err)
return fmt.Errorf("marshal config: %w", err)
}
err = os.MkdirAll(filepath.Dir(f.Path), 0755)
if err != nil {
return fmt.Errorf("failed to create config directory: %w", err)
return fmt.Errorf("create config directory: %w", err)
}
// backup the old config file
if err := f.makeBackup(); err != nil {
return fmt.Errorf("backup config file: %w", err)
}
err = atomic.WriteFile(f.Path, bytes.NewReader(data))
if err != nil {
return fmt.Errorf("failed to write config file: %w", err)
return fmt.Errorf("write config file: %w", err)
}
// only the user running backrest should be able to read the config.
@@ -69,3 +79,37 @@ func (f *JsonFileStore) Update(config *v1.Config) error {
return nil
}
func (f *JsonFileStore) makeBackup() error {
curConfig, err := os.ReadFile(f.Path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
// backup the current config file
backupName := fmt.Sprintf("%s.bak.%s", f.Path, time.Now().Format("2006-01-02-15-04-05"))
if err := atomic.WriteFile(backupName, bytes.NewBuffer(curConfig)); err != nil {
return err
}
if err := os.Chmod(backupName, 0600); err != nil {
return err
}
// only keep the last 10 versions
files, err := filepath.Glob(f.Path + ".bak.*")
if err != nil {
return err
}
if len(files) > configKeepVersions {
for _, file := range files[:len(files)-configKeepVersions] {
if err := os.Remove(file); err != nil {
return err
}
}
}
return nil
}