(svc advancedAppServices, parent commandParent)
| 47 | ) |
| 48 | |
| 49 | func (c *commandRepositoryUpgrade) setup(svc advancedAppServices, parent commandParent) { |
| 50 | // override the parent, the upgrade sub-command becomes the new parent here-onwards |
| 51 | parent = parent.Command("upgrade", "Upgrade repository format.\n\n"+warningColor.Sprint(experimentalWarning)).Hidden(). |
| 52 | Validate(func(_ *kingpin.CmdClause) error { |
| 53 | if v := os.Getenv(c.svc.EnvName(upgradeLockFeatureEnv)); v == "" { |
| 54 | return errors.Errorf("please set %q env variable to use this feature", upgradeLockFeatureEnv) |
| 55 | } |
| 56 | |
| 57 | return nil |
| 58 | }) |
| 59 | |
| 60 | beginCmd := parent.Command("begin", "Begin upgrade.") |
| 61 | beginCmd.Flag("io-drain-timeout", "Max time it should take all other Kopia clients to drop repository connections").Default(format.DefaultRepositoryBlobCacheDuration.String()).DurationVar(&c.ioDrainTimeout) |
| 62 | beginCmd.Flag("allow-unsafe-upgrade", "Force using an unsafe io-drain-timeout for the upgrade lock").Default("false").Hidden().BoolVar(&c.allowUnsafeUpgradeTimings) |
| 63 | beginCmd.Flag("status-poll-interval", "An advisory polling interval to check for the status of upgrade").Default("60s").DurationVar(&c.statusPollInterval) |
| 64 | beginCmd.Flag("max-permitted-clock-drift", "The maximum drift between repository and client clocks").Default(maxPermittedClockDriftDefault.String()).DurationVar(&c.maxPermittedClockDrift) |
| 65 | beginCmd.Flag("lock-only", "Advertise the upgrade lock and exit without actually performing the drain or upgrade").Default("false").Hidden().BoolVar(&c.lockOnly) // this is used by tests |
| 66 | beginCmd.Flag("commit-mode", "Change behavior of commit. When not set, commit on validation success. 'always': always commit. 'never': always exit before commit.").Hidden().EnumVar(&c.commitMode, commitModeAlwaysCommit, commitModeNeverCommit) |
| 67 | |
| 68 | // upgrade phases |
| 69 | |
| 70 | // Set the upgrade lock intent. |
| 71 | beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.setLockIntent))) |
| 72 | // If requested then drain all the clients otherwise stop here. |
| 73 | beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.drainOrCommit))) |
| 74 | // If the lock is fully established then perform the upgrade. |
| 75 | beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.upgrade))) |
| 76 | // Validate index upgrade success |
| 77 | beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.ignoreErrorOnAlwaysCommit(c.validateAction)))) |
| 78 | // Commit the upgrade and revoke the lock, this will also cleanup any |
| 79 | // backups used for rollback. |
| 80 | beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.commitUpgrade))) |
| 81 | |
| 82 | rollbackCmd := parent.Command("rollback", "Rollback the repository upgrade.") |
| 83 | rollbackCmd.Flag("force", "Force rollback the repository upgrade, this action can cause repository corruption").BoolVar(&c.forceRollback) |
| 84 | |
| 85 | rollbackCmd.Action(svc.directRepositoryWriteAction(c.forceRollbackAction)) |
| 86 | |
| 87 | validateCmd := parent.Command("validate", "Validate the upgraded indexes.") |
| 88 | |
| 89 | validateCmd.Action(svc.directRepositoryWriteAction(c.validateAction)) |
| 90 | |
| 91 | c.svc = svc |
| 92 | } |
| 93 | |
| 94 | // assign store the info struct in a map that can be used to compare indexes. |
| 95 | func assign(iif content.Info, i int, m map[content.ID][2]content.Info) { |
nothing calls this directly
no test coverage detected