2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-25 14:17:42 +00:00

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 found := false
for _, m := range migrations.All { for _, m := range migrations.All {
ok, err := m.Check(ctx, repo) ok, _, err := m.Check(ctx, repo)
if err != nil { if err != nil {
return err return err
} }
@ -70,14 +70,17 @@ func applyMigrations(opts MigrateOptions, gopts GlobalOptions, repo restic.Repos
for _, name := range args { for _, name := range args {
for _, m := range migrations.All { for _, m := range migrations.All {
if m.Name() == name { if m.Name() == name {
ok, err := m.Check(ctx, repo) ok, reason, err := m.Check(ctx, repo)
if err != nil { if err != nil {
return err return err
} }
if !ok { if !ok {
if !opts.Force { 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 continue
} }

View File

@ -8,8 +8,8 @@ import (
// Migration implements a data migration. // Migration implements a data migration.
type Migration interface { type Migration interface {
// Check returns true if the migration can be applied to a repo. // 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, error) Check(context.Context, restic.Repository) (bool, string, error)
RepoCheck() bool RepoCheck() bool

View File

@ -38,19 +38,19 @@ func toS3Backend(repo restic.Repository) *s3.Backend {
} }
// Check tests whether the migration can be applied. // 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) be := toS3Backend(repo)
if be == nil { if be == nil {
debug.Log("backend is not s3") debug.Log("backend is not s3")
return false, nil return false, "backend is not s3", nil
} }
if be.Layout.Name() != "s3legacy" { if be.Layout.Name() != "s3legacy" {
debug.Log("layout is not 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 { func (m *S3Layout) RepoCheck() bool {

View File

@ -45,9 +45,13 @@ func (*UpgradeRepoV2) Desc() string {
return "upgrade a repository to version 2" 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 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 { func (*UpgradeRepoV2) RepoCheck() bool {

View File

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