test: cover the legacy -v migration with go and bats tests
Adds plugins/storage/migrate_test.go exercising migrateApp and MigrateLegacyMounts: single deploy phase, cross-phase grouping into one attachment, :ro and free-form volume options preserved on the attachment, idempotency on a second pass, the per-app flag-file fast path that skips already-migrated apps, and the name-collision refusal that aborts before draining. tests/unit/storage.bats gains an end-to-end case that stages a -v line via docker-options:add, runs storage:migrate, and asserts the synthesized colon form shows up in storage:list, the legacy-<hash> entry shows up in storage:list-entries, and the original -v line is gone from docker-options:report on both phases. To make that test (and operators with restored backups) practical, storage gains a storage:migrate <app>|--all subcommand backed by a new MigrateApp helper that skips the per-app flag file so a re-run actually re-scans.
This commit is contained in:
@@ -323,6 +323,44 @@ func stdinModes() (interactive bool, tty bool) {
|
||||
return interactive, tty
|
||||
}
|
||||
|
||||
// CommandMigrate re-runs the legacy `-v` → entry/attachment migration
|
||||
// for a single app or every app on the install. Useful when an operator
|
||||
// has restored an app from a backup that predates the install-time
|
||||
// migration, or when they've added `-v` lines via docker-options:add
|
||||
// after the per-app flag was set.
|
||||
func CommandMigrate(appName string, all bool) error {
|
||||
if all && appName != "" {
|
||||
return errors.New("storage:migrate accepts either an app name or --all, not both")
|
||||
}
|
||||
if !all && appName == "" {
|
||||
return errors.New("storage:migrate requires an app name (or --all)")
|
||||
}
|
||||
if all {
|
||||
apps, err := common.DokkuApps()
|
||||
if err != nil {
|
||||
if errors.Is(err, common.NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
for _, app := range apps {
|
||||
if err := MigrateApp(app); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
common.LogInfo1(fmt.Sprintf("Re-migrated %d app(s)", len(apps)))
|
||||
return nil
|
||||
}
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := MigrateApp(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
common.LogInfo1(fmt.Sprintf("Re-migrated %s", appName))
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommandWait blocks until a k3s storage entry's PVC is bound.
|
||||
func CommandWait(name string) error {
|
||||
if !EntryExists(name) {
|
||||
|
||||
Reference in New Issue
Block a user