migrate: Report why an migration cannot be applied

Just returning that `Migration upgrade cannot be applied: check failed`
is not too useful when running `migrate upgrade_repo_v2`.
This commit is contained in:
Michael Eischer 2022-09-03 11:49:31 +02:00
parent 6c69f08a7b
commit 8b4dd70013
5 changed files with 20 additions and 13 deletions

View File

@ -45,7 +45,7 @@ func checkMigrations(opts MigrateOptions, gopts GlobalOptions, repo restic.Repos
found := false
for _, m := range migrations.All {
ok, err := m.Check(ctx, repo)
ok, _, err := m.Check(ctx, repo)
if err != nil {
return err
}
@ -70,14 +70,17 @@ func applyMigrations(opts MigrateOptions, gopts GlobalOptions, repo restic.Repos
for _, name := range args {
for _, m := range migrations.All {
if m.Name() == name {
ok, err := m.Check(ctx, repo)
ok, reason, err := m.Check(ctx, repo)
if err != nil {
return err
}
if !ok {
if !opts.Force {
Warnf("migration %v cannot be applied: check failed\nIf you want to apply this migration anyway, re-run with option --force\n", m.Name())
if reason == "" {
reason = "check failed"
}
Warnf("migration %v cannot be applied: %v\nIf you want to apply this migration anyway, re-run with option --force\n", m.Name(), reason)
continue
}

View File

@ -8,8 +8,8 @@ import (
// Migration implements a data migration.
type Migration interface {
// Check returns true if the migration can be applied to a repo.
Check(context.Context, restic.Repository) (bool, error)
// Check returns true if the migration can be applied to a repo. If the option is not applicable it can return a specific reason.
Check(context.Context, restic.Repository) (bool, string, error)
RepoCheck() bool

View File

@ -38,19 +38,19 @@ func toS3Backend(repo restic.Repository) *s3.Backend {
}
// Check tests whether the migration can be applied.
func (m *S3Layout) Check(ctx context.Context, repo restic.Repository) (bool, error) {
func (m *S3Layout) Check(ctx context.Context, repo restic.Repository) (bool, string, error) {
be := toS3Backend(repo)
if be == nil {
debug.Log("backend is not s3")
return false, nil
return false, "backend is not s3", nil
}
if be.Layout.Name() != "s3legacy" {
debug.Log("layout is not s3legacy")
return false, nil
return false, "not using the legacy s3 layout", nil
}
return true, nil
return true, "", nil
}
func (m *S3Layout) RepoCheck() bool {

View File

@ -45,9 +45,13 @@ func (*UpgradeRepoV2) Desc() string {
return "upgrade a repository to version 2"
}
func (*UpgradeRepoV2) Check(ctx context.Context, repo restic.Repository) (bool, error) {
func (*UpgradeRepoV2) Check(ctx context.Context, repo restic.Repository) (bool, string, error) {
isV1 := repo.Config().Version == 1
return isV1, nil
reason := ""
if !isV1 {
reason = fmt.Sprintf("repository is already upgraded to version %v", repo.Config().Version)
}
return isV1, reason, nil
}
func (*UpgradeRepoV2) RepoCheck() bool {

View File

@ -23,7 +23,7 @@ func TestUpgradeRepoV2(t *testing.T) {
m := &UpgradeRepoV2{}
ok, err := m.Check(context.Background(), repo)
ok, _, err := m.Check(context.Background(), repo)
if err != nil {
t.Fatal(err)
}
@ -81,7 +81,7 @@ func TestUpgradeRepoV2Failure(t *testing.T) {
m := &UpgradeRepoV2{}
ok, err := m.Check(context.Background(), repo)
ok, _, err := m.Check(context.Background(), repo)
if err != nil {
t.Fatal(err)
}