diff --git a/changelog/unreleased/issue-4602 b/changelog/unreleased/issue-4602 new file mode 100644 index 000000000..3cba63876 --- /dev/null +++ b/changelog/unreleased/issue-4602 @@ -0,0 +1,13 @@ +Change: Deprecate legacy index format + +Support for the legacy index format used by restic before version 0.2.0 has +been depreacted and will be removed in the next minor restic version. You can +use `restic repair index` to update the index to the current format. + +It is possible to temporarily reenable support for the legacy index format by +setting the environment variable +`RESTIC_FEATURES=deprecate-legacy-index=false`. Note that this feature flag +will be removed in the next minor restic version. + +https://github.com/restic/restic/issues/4602 +https://github.com/restic/restic/pull/4724 diff --git a/cmd/restic/cmd_check.go b/cmd/restic/cmd_check.go index 990702b61..cbe388877 100644 --- a/cmd/restic/cmd_check.go +++ b/cmd/restic/cmd_check.go @@ -231,12 +231,17 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args errorsFound := false suggestIndexRebuild := false + suggestLegacyIndexRebuild := false mixedFound := false for _, hint := range hints { switch hint.(type) { - case *checker.ErrDuplicatePacks, *checker.ErrOldIndexFormat: + case *checker.ErrDuplicatePacks: Printf("%v\n", hint) suggestIndexRebuild = true + case *checker.ErrOldIndexFormat: + Warnf("error: %v\n", hint) + suggestLegacyIndexRebuild = true + errorsFound = true case *checker.ErrMixedPack: Printf("%v\n", hint) mixedFound = true @@ -247,7 +252,10 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args } if suggestIndexRebuild { - Printf("Duplicate packs/old indexes are non-critical, you can run `restic repair index' to correct this.\n") + Printf("Duplicate packs are non-critical, you can run `restic repair index' to correct this.\n") + } + if suggestLegacyIndexRebuild { + Warnf("Found indexes using the legacy format, you must run `restic repair index' to correct this.\n") } if mixedFound { Printf("Mixed packs with tree and data blobs are non-critical, you can run `restic prune` to correct this.\n") diff --git a/cmd/restic/testdata/repo-restore-permissions-test.tar.gz b/cmd/restic/testdata/repo-restore-permissions-test.tar.gz index 36aa62dbf..dc8e9bc80 100644 Binary files a/cmd/restic/testdata/repo-restore-permissions-test.tar.gz and b/cmd/restic/testdata/repo-restore-permissions-test.tar.gz differ diff --git a/internal/feature/registry.go b/internal/feature/registry.go index 7a9cbf560..620c9ec35 100644 --- a/internal/feature/registry.go +++ b/internal/feature/registry.go @@ -5,11 +5,13 @@ var Flag = New() // flag names are written in kebab-case const ( - ExampleFeature FlagName = "example-feature" + ExampleFeature FlagName = "example-feature" + DeprecateLegacyIndex FlagName = "deprecate-legacy-index" ) func init() { Flag.SetFlags(map[FlagName]FlagDesc{ - ExampleFeature: {Type: Alpha, Description: "just for testing"}, + ExampleFeature: {Type: Alpha, Description: "just for testing"}, + DeprecateLegacyIndex: {Type: Beta, Description: "disable support for index format used by restic 0.1.0. Use `restic repair index` to update the index if necessary."}, }) } diff --git a/internal/index/index.go b/internal/index/index.go index ecd481594..1fb2c155e 100644 --- a/internal/index/index.go +++ b/internal/index/index.go @@ -3,12 +3,14 @@ package index import ( "context" "encoding/json" + "fmt" "io" "sync" "time" "github.com/restic/restic/internal/crypto" "github.com/restic/restic/internal/errors" + "github.com/restic/restic/internal/feature" "github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/debug" @@ -515,8 +517,13 @@ func DecodeIndex(buf []byte, id restic.ID) (idx *Index, oldFormat bool, err erro debug.Log("Error %v", err) if isErrOldIndex(err) { + if feature.Flag.Enabled(feature.DeprecateLegacyIndex) { + return nil, false, fmt.Errorf("index seems to use the legacy format. update it using `restic repair index`") + } + debug.Log("index is probably old format, trying that") idx, err = decodeOldIndex(buf) + idx.ids = append(idx.ids, id) return idx, err == nil, err } diff --git a/internal/index/index_test.go b/internal/index/index_test.go index 4f0dbd2a0..78e4800ca 100644 --- a/internal/index/index_test.go +++ b/internal/index/index_test.go @@ -8,6 +8,7 @@ import ( "sync" "testing" + "github.com/restic/restic/internal/feature" "github.com/restic/restic/internal/index" "github.com/restic/restic/internal/restic" rtest "github.com/restic/restic/internal/test" @@ -427,6 +428,8 @@ func BenchmarkEncodeIndex(b *testing.B) { } func TestIndexUnserializeOld(t *testing.T) { + defer feature.TestSetFlag(t, feature.Flag, feature.DeprecateLegacyIndex, false)() + idx, oldFormat, err := index.DecodeIndex(docOldExample, restic.NewRandomID()) rtest.OK(t, err) rtest.Assert(t, oldFormat, "old index format recognized as new format")