Skip to content

Commit

Permalink
feat: keep a rolling backup of the last 10 config versions
Browse files Browse the repository at this point in the history
  • Loading branch information
garethgeorge committed May 19, 2024
1 parent 711064f commit 1a053f2
Showing 1 changed file with 47 additions and 3 deletions.
50 changes: 47 additions & 3 deletions internal/config/jsonstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
}

0 comments on commit 1a053f2

Please sign in to comment.