Skip to content

Commit

Permalink
fix: migrate prune policy options to oneof
Browse files Browse the repository at this point in the history
  • Loading branch information
garethgeorge committed Feb 20, 2024
1 parent bf6fb7e commit ef41d34
Show file tree
Hide file tree
Showing 7 changed files with 681 additions and 208 deletions.
547 changes: 374 additions & 173 deletions gen/go/v1/config.pb.go

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions internal/config/migrations/001prunepolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package migrations

import v1 "github.com/garethgeorge/backrest/gen/go/v1"

func migration001PrunePolicy(config *v1.Config) {
// loop over plans and examine prune policy's
for _, plan := range config.Plans {
policy := plan.GetRetention()
if policy == nil {
continue
}

if policy.Policy != nil {
continue // already migrated
}

if policy.KeepLastN != 0 {
plan.Retention = &v1.RetentionPolicy{
Policy: &v1.RetentionPolicy_PolicyKeepLastN{
PolicyKeepLastN: policy.KeepLastN,
},
}
} else if policy.KeepDaily != 0 || policy.KeepHourly != 0 || policy.KeepMonthly != 0 || policy.KeepWeekly != 0 || policy.KeepYearly != 0 {
plan.Retention = &v1.RetentionPolicy{
Policy: &v1.RetentionPolicy_PolicyTimeBucketed{
PolicyTimeBucketed: &v1.RetentionPolicy_TimeBucketedCounts{
Hourly: policy.KeepHourly,
Daily: policy.KeepDaily,
Weekly: policy.KeepWeekly,
Monthly: policy.KeepMonthly,
Yearly: policy.KeepYearly,
},
},
}
} else {
policy.Policy = &v1.RetentionPolicy_PolicyKeepAll{
PolicyKeepAll: true,
}
}
}
}
111 changes: 111 additions & 0 deletions internal/config/migrations/001prunepolicy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package migrations

import (
"testing"

v1 "github.com/garethgeorge/backrest/gen/go/v1"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)

func Test001Migration(t *testing.T) {
cases := []struct {
name string
config string
want *v1.Config
}{
{
name: "time bucketed policy",
config: `{
"plans": [
{
"retention": {
"keepHourly": 1,
"keepDaily": 2,
"keepWeekly": 3,
"keepMonthly": 4,
"keepYearly": 5
}
}
]
}`,
want: &v1.Config{
Plans: []*v1.Plan{
{
Retention: &v1.RetentionPolicy{
Policy: &v1.RetentionPolicy_PolicyTimeBucketed{
PolicyTimeBucketed: &v1.RetentionPolicy_TimeBucketedCounts{
Hourly: 1,
Daily: 2,
Weekly: 3,
Monthly: 4,
Yearly: 5,
},
},
},
},
},
},
},
{
name: "keep all policy",
config: `{
"plans": [
{
"retention": {}
}
]
}`,
want: &v1.Config{
Plans: []*v1.Plan{
{
Retention: &v1.RetentionPolicy{
Policy: &v1.RetentionPolicy_PolicyKeepAll{
PolicyKeepAll: true,
},
},
},
},
},
},
{
name: "keep by count",
config: `{
"plans": [
{
"retention": {
"keepLastN": 5
}
}
]
}`,
want: &v1.Config{
Plans: []*v1.Plan{
{
Retention: &v1.RetentionPolicy{
Policy: &v1.RetentionPolicy_PolicyKeepLastN{
PolicyKeepLastN: 5,
},
},
},
},
},
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
config := v1.Config{}
err := protojson.Unmarshal([]byte(tc.config), &config)
if err != nil {
t.Fatalf("failed to unmarshal config: %v", err)
}

migration001PrunePolicy(&config)

if !proto.Equal(&config, tc.want) {
t.Errorf("got: %+v, want: %+v", &config, tc.want)
}
})
}
}
10 changes: 10 additions & 0 deletions internal/config/migrations/migrations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package migrations

import v1 "github.com/garethgeorge/backrest/gen/go/v1"

func ApplyMigrations(config *v1.Config) {
if config.Version <= 1 {
migration001PrunePolicy(config)
}
config.Version = 1
}
34 changes: 24 additions & 10 deletions proto/v1/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ option go_package = "github.com/garethgeorge/backrest/gen/go/v1";
message Config {
// modification number, used for read-modify-write consistency in the UI. Incremented on every write.
int32 modno = 1 [json_name="modno"];
int32 version = 6 [json_name="version"]; // version of the config file format. Used to determine when to run migrations.

// override the hostname tagged on backups. If provided it will be used in addition to tags to group backups.
string host = 2 [json_name="host"];
Expand Down Expand Up @@ -40,16 +41,29 @@ message Plan {
}

message RetentionPolicy {
// max_unused_limit is used to decide when forget should be run.
string max_unused_limit = 1 [json_name="maxUnusedLimit"]; // e.g. a percentage i.e. 25% or a number of megabytes.

int32 keep_last_n = 2 [json_name="keepLastN"]; // keep the last n snapshots.
int32 keep_hourly = 3 [json_name="keepHourly"]; // keep the last n hourly snapshots.
int32 keep_daily = 4 [json_name="keepDaily"]; // keep the last n daily snapshots.
int32 keep_weekly = 5 [json_name="keepWeekly"]; // keep the last n weekly snapshots.
int32 keep_monthly = 6 [json_name="keepMonthly"]; // keep the last n monthly snapshots.
int32 keep_yearly = 7 [json_name="keepYearly"]; // keep the last n yearly snapshots.
string keep_within_duration = 8 [json_name="keepWithinDuration"]; // keep snapshots within a duration e.g. 1y2m3d4h5m6s
string max_unused_limit = 1 [json_name="maxUnusedLimit", deprecated = true];

int32 keep_last_n = 2 [json_name="keepLastN", deprecated = true];
int32 keep_hourly = 3 [json_name="keepHourly", deprecated = true];
int32 keep_daily = 4 [json_name="keepDaily", deprecated = true];
int32 keep_weekly = 5 [json_name="keepWeekly", deprecated = true];
int32 keep_monthly = 6 [json_name="keepMonthly", deprecated = true];
int32 keep_yearly = 7 [json_name="keepYearly", deprecated = true];
string keep_within_duration = 8 [json_name="keepWithinDuration", deprecated = true]; // keep snapshots within a duration e.g. 1y2m3d4h5m6s

oneof policy {
int32 policy_keep_last_n = 10 [json_name="policyKeepLastN"];
TimeBucketedCounts policy_time_bucketed = 11 [json_name="policyTimeBucketed"];
bool policy_keep_all = 12 [json_name="policyKeepAll"];
}

message TimeBucketedCounts {
int32 hourly = 1 [json_name="hourly"]; // keep the last n hourly snapshots.
int32 daily = 2 [json_name="daily"]; // keep the last n daily snapshots.
int32 weekly = 3 [json_name="weekly"]; // keep the last n weekly snapshots.
int32 monthly = 4 [json_name="monthly"]; // keep the last n monthly snapshots.
int32 yearly = 5 [json_name="yearly"]; // keep the last n yearly snapshots.
}
}

message PrunePolicy {
Expand Down
Loading

0 comments on commit ef41d34

Please sign in to comment.