github.com/mckael/restic@v0.8.3/cmd/restic/cmd_migrate.go (about) 1 package main 2 3 import ( 4 "github.com/restic/restic/internal/migrations" 5 "github.com/restic/restic/internal/restic" 6 7 "github.com/spf13/cobra" 8 ) 9 10 var cmdMigrate = &cobra.Command{ 11 Use: "migrate [name]", 12 Short: "Apply migrations", 13 Long: ` 14 The "migrate" command applies migrations to a repository. When no migration 15 name is explicitly given, a list of migrations that can be applied is printed. 16 `, 17 DisableAutoGenTag: true, 18 RunE: func(cmd *cobra.Command, args []string) error { 19 return runMigrate(migrateOptions, globalOptions, args) 20 }, 21 } 22 23 // MigrateOptions bundles all options for the 'check' command. 24 type MigrateOptions struct { 25 Force bool 26 } 27 28 var migrateOptions MigrateOptions 29 30 func init() { 31 cmdRoot.AddCommand(cmdMigrate) 32 f := cmdMigrate.Flags() 33 f.BoolVarP(&migrateOptions.Force, "force", "f", false, `apply a migration a second time`) 34 } 35 36 func checkMigrations(opts MigrateOptions, gopts GlobalOptions, repo restic.Repository) error { 37 ctx := gopts.ctx 38 Printf("available migrations:\n") 39 for _, m := range migrations.All { 40 ok, err := m.Check(ctx, repo) 41 if err != nil { 42 return err 43 } 44 45 if ok { 46 Printf(" %v: %v\n", m.Name(), m.Desc()) 47 } 48 } 49 50 return nil 51 } 52 53 func applyMigrations(opts MigrateOptions, gopts GlobalOptions, repo restic.Repository, args []string) error { 54 ctx := gopts.ctx 55 56 var firsterr error 57 for _, name := range args { 58 for _, m := range migrations.All { 59 if m.Name() == name { 60 ok, err := m.Check(ctx, repo) 61 if err != nil { 62 return err 63 } 64 65 if !ok { 66 if !opts.Force { 67 Warnf("migration %v cannot be applied: check failed\nIf you want to apply this migration anyway, re-run with option --force\n", m.Name()) 68 continue 69 } 70 71 Warnf("check for migration %v failed, continuing anyway\n", m.Name()) 72 } 73 74 Printf("applying migration %v...\n", m.Name()) 75 if err = m.Apply(ctx, repo); err != nil { 76 Warnf("migration %v failed: %v\n", m.Name(), err) 77 if firsterr == nil { 78 firsterr = err 79 } 80 continue 81 } 82 83 Printf("migration %v: success\n", m.Name()) 84 } 85 } 86 } 87 88 return firsterr 89 } 90 91 func runMigrate(opts MigrateOptions, gopts GlobalOptions, args []string) error { 92 repo, err := OpenRepository(gopts) 93 if err != nil { 94 return err 95 } 96 97 lock, err := lockRepoExclusive(repo) 98 defer unlockRepo(lock) 99 if err != nil { 100 return err 101 } 102 103 if len(args) == 0 { 104 return checkMigrations(opts, gopts, repo) 105 } 106 107 return applyMigrations(opts, gopts, repo, args) 108 }