Commit 2c920d23 authored by ale's avatar ale

Add 'autoprune' config parameter for restic backend

If disabled, we won't run "restic prune" on the remote
repository. Allows support of append-only repositories.
parent ac49cdbc
...@@ -24,6 +24,7 @@ type resticRepository struct { ...@@ -24,6 +24,7 @@ type resticRepository struct {
shell *Shell shell *Shell
excludes []string excludes []string
excludeFiles []string excludeFiles []string
autoPrune bool
} }
func (r *resticRepository) resticCmd() string { func (r *resticRepository) resticCmd() string {
...@@ -80,13 +81,17 @@ func newResticRepository(params map[string]interface{}, shell *Shell) (Repositor ...@@ -80,13 +81,17 @@ func newResticRepository(params map[string]interface{}, shell *Shell) (Repositor
ex, _ := params["exclude"].([]string) ex, _ := params["exclude"].([]string)
exf, _ := params["exclude_files"].([]string) exf, _ := params["exclude_files"].([]string)
bin, _ := params["restic_binary"].(string) bin := "restic"
if bin == "" { if s, ok := params["restic_binary"].(string); ok {
bin = "restic" bin = s
} }
if err := checkResticVersion(bin); err != nil { if err := checkResticVersion(bin); err != nil {
return nil, err return nil, err
} }
autoPrune := true
if b, ok := params["autoprune"].(bool); ok {
autoPrune = b
}
tmpf, err := ioutil.TempFile("", "restic-pw-") tmpf, err := ioutil.TempFile("", "restic-pw-")
if err != nil { if err != nil {
...@@ -108,6 +113,7 @@ func newResticRepository(params map[string]interface{}, shell *Shell) (Repositor ...@@ -108,6 +113,7 @@ func newResticRepository(params map[string]interface{}, shell *Shell) (Repositor
excludes: ex, excludes: ex,
excludeFiles: exf, excludeFiles: exf,
shell: shell, shell: shell,
autoPrune: autoPrune,
}, nil }, nil
} }
...@@ -125,6 +131,9 @@ func (r *resticRepository) Init(ctx context.Context) error { ...@@ -125,6 +131,9 @@ func (r *resticRepository) Init(ctx context.Context) error {
} }
func (r *resticRepository) Prepare(ctx context.Context, backup Backup) error { func (r *resticRepository) Prepare(ctx context.Context, backup Backup) error {
if !r.autoPrune {
return nil
}
return r.shell.Run(ctx, fmt.Sprintf( return r.shell.Run(ctx, fmt.Sprintf(
"%s forget --host %s --keep-last 10 --prune", "%s forget --host %s --keep-last 10 --prune",
r.resticCmd(), r.resticCmd(),
...@@ -221,6 +230,9 @@ type resticSnapshot struct { ...@@ -221,6 +230,9 @@ type resticSnapshot struct {
} }
func parseResticSnapshots(output []byte) (snapshots []resticSnapshot, err error) { func parseResticSnapshots(output []byte) (snapshots []resticSnapshot, err error) {
err = json.Unmarshal(output, &snapshots) // An empty input is not necessarily an error.
if len(output) > 0 {
err = json.Unmarshal(output, &snapshots)
}
return return
} }
...@@ -15,6 +15,8 @@ import ( ...@@ -15,6 +15,8 @@ import (
// Create a temporary directory with two subdirs: 'data', for // Create a temporary directory with two subdirs: 'data', for
// the test backup data, and 'repo' to store the (remote) // the test backup data, and 'repo' to store the (remote)
// repository. Populate 'data' with two tiny files. // repository. Populate 'data' with two tiny files.
//
// nolint
func createTempDirWithData(t *testing.T) string { func createTempDirWithData(t *testing.T) string {
tmpdir, err := ioutil.TempDir("", "") tmpdir, err := ioutil.TempDir("", "")
if err != nil { if err != nil {
...@@ -112,10 +114,13 @@ func TestRestic(t *testing.T) { ...@@ -112,10 +114,13 @@ func TestRestic(t *testing.T) {
} }
// Check the 'restic snapshots' output. // Check the 'restic snapshots' output.
output, _ := exec.Command("env", "RESTIC_PASSWORD=testpass", "restic", "-r", tmpdir+"/repo", "snapshots", "--json").Output() output, err := exec.Command("env", "RESTIC_PASSWORD=testpass", "restic", "-r", tmpdir+"/repo", "snapshots", "--json").Output()
if err != nil {
t.Fatalf("'restic snapshots' failed: %v", err)
}
snaps, err := parseResticSnapshots(output) snaps, err := parseResticSnapshots(output)
if err != nil { if err != nil {
t.Fatalf("parsing restic snaphots output: %v", err) t.Fatalf("parsing restic snaphots output: %v, output:\n%s", err, string(output))
} }
if len(snaps) != 1 { if len(snaps) != 1 {
t.Fatalf("wrong number of snapshots: %+v", snaps) t.Fatalf("wrong number of snapshots: %+v", snaps)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment