check: complain about mixed pack files

This commit is contained in:
Michael Eischer 2022-04-10 14:11:01 +02:00
parent 443cc49afd
commit 8b8bd4e8ac
3 changed files with 41 additions and 24 deletions

View file

@ -221,11 +221,15 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
errorsFound := false
suggestIndexRebuild := false
mixedFound := false
for _, hint := range hints {
switch hint.(type) {
case *checker.ErrDuplicatePacks, *checker.ErrOldIndexFormat:
Printf("%v\n", hint)
suggestIndexRebuild = true
case *checker.ErrMixedPack:
Printf("%v\n", hint)
mixedFound = true
default:
Warnf("error: %v\n", hint)
errorsFound = true
@ -235,6 +239,9 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
if suggestIndexRebuild {
Printf("This is non-critical, you can run `restic rebuild-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")
}
if len(errs) > 0 {
for _, err := range errs {

View file

@ -66,6 +66,15 @@ func (e *ErrDuplicatePacks) Error() string {
return fmt.Sprintf("pack %v contained in several indexes: %v", e.PackID, e.Indexes)
}
// ErrMixedPack is returned when a pack is found that contains both tree and data blobs.
type ErrMixedPack struct {
PackID restic.ID
}
func (e *ErrMixedPack) Error() string {
return fmt.Sprintf("pack %v contains a mix of tree and data blobs", e.PackID.Str())
}
// ErrOldIndexFormat is returned when an index with the old format is
// found.
type ErrOldIndexFormat struct {
@ -141,6 +150,11 @@ func (c *Checker) LoadIndex(ctx context.Context) (hints []error, errs []error) {
Indexes: packToIndex[packID],
})
}
if c.masterIndex.IsMixedPack(packID) {
hints = append(hints, &ErrMixedPack{
PackID: packID,
})
}
}
err = c.repo.SetIndex(c.masterIndex)

View file

@ -63,6 +63,14 @@ func checkData(chkr *checker.Checker) []error {
)
}
func assertOnlyMixedPackHints(t *testing.T, hints []error) {
for _, err := range hints {
if _, ok := err.(*checker.ErrMixedPack); !ok {
t.Fatalf("expected mixed pack hint, got %v", err)
}
}
}
func TestCheckRepo(t *testing.T) {
repodir, cleanup := test.Env(t, checkerTestData)
defer cleanup()
@ -74,9 +82,9 @@ func TestCheckRepo(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
assertOnlyMixedPackHints(t, hints)
if len(hints) == 0 {
t.Fatal("expected mixed pack warnings, got none")
}
test.OKs(t, checkPacks(chkr))
@ -100,10 +108,7 @@ func TestMissingPack(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
}
assertOnlyMixedPackHints(t, hints)
errs = checkPacks(chkr)
@ -136,10 +141,7 @@ func TestUnreferencedPack(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
}
assertOnlyMixedPackHints(t, hints)
errs = checkPacks(chkr)
@ -181,10 +183,7 @@ func TestUnreferencedBlobs(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
}
assertOnlyMixedPackHints(t, hints)
test.OKs(t, checkPacks(chkr))
test.OKs(t, checkStruct(chkr))
@ -269,9 +268,7 @@ func TestModifiedIndex(t *testing.T) {
t.Logf("found expected error %v", err)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
}
assertOnlyMixedPackHints(t, hints)
}
var checkerDuplicateIndexTestData = filepath.Join("testdata", "duplicate-packs-in-index-test-repo.tar.gz")
@ -421,10 +418,7 @@ func TestCheckerNoDuplicateTreeDecodes(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
}
assertOnlyMixedPackHints(t, hints)
test.OKs(t, checkPacks(chkr))
test.OKs(t, checkStruct(chkr))
@ -572,8 +566,10 @@ func loadBenchRepository(t *testing.B) (*checker.Checker, restic.Repository, fun
t.Fatalf("expected no errors, got %v: %v", len(errs), errs)
}
if len(hints) > 0 {
t.Errorf("expected no hints, got %v: %v", len(hints), hints)
for _, err := range hints {
if _, ok := err.(*checker.ErrMixedPack); !ok {
t.Fatalf("expected mixed pack hint, got %v", err)
}
}
return chkr, repo, cleanup
}