Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

run

migrate and data plan stay plan-only: they write an Ansible role and attested runbooks, and a human applies them. run is a separate, explicitly-invoked command for an operator or pipeline that wants that same chain executed unattended instead: plan → apply the role over real SSH → carry the promised config → optional workload-data copy → verify → optional Kubernetes/OpenShift cutover.

vrtmv run --root centos7-mnt --target rocky9 --target-ssh root@10.0.1.20 -o out/
vrtmv run --image centos7.vmdk --target rhel9 --target-ssh admin@10.0.1.30 \
  --copy /srv/www --copy /var/lib/mysql --notify-webhook https://hooks.example.com/vrtmv
vrtmv run-status -o out/
FlagPurpose
--root / --image / --sshThe source (see Sources). With --ssh, --copy runs directly on the source host — see below.
--target <spec>Target OS (default rocky9). See Supported targets.
--target-ssh <user@host>Where to apply the migration. A real host run connects to and changes.
--target-ssh-port, --target-ssh-key, --target-jump, --target-sudoTarget SSH connection options, mirroring the source’s.
-o, --out <dir>Output directory for the role, attestation, verify report, and run-state file (default vrtmv-out).
--format <list>Must include ansible (default) — that’s what run applies.
--copy <path>A guest data path to copy onto the target automatically (repeatable). Omit to carry OS/config only, as migrate alone promises.
--resumeSkip phases already recorded complete under --out instead of restarting.
--retries <n>Attempts per external step — ssh, ansible-playbook, API calls (default 3; 1 disables retry).
--not-before <epoch seconds>Wait until this time before touching the target; planning still runs immediately.
--notify-webhook <url>Best-effort JSON POST on the terminal state (done/blocked/failed). Never fails the run.
--require-health, --health-key-file, --health-max-age-mins, --health-strictThe same vrtmn HealthReport gate verify --require-health offers, checked before run can report done.
--job-id <id>Stamp an external id into the run-state file and any webhook payload. Generated if omitted.
--engagement, --vm-id, --migration-typeTag the run — see Tagging VM migrations.
--cutoverAfter a passing verify (and health gate, if requested), APPLY the cutover manifest instead of only emitting it. Requires --deploy-image or --deploy-disk-url.
--deploy-image / --deploy-disk-url, --deploy-disk-size, --deploy-storage-classThe cutover VM’s disk source — a containerDisk image, or an imported disk via CDI DataVolume. Same shape as deploy.
--deploy-namespace, --deploy-nameNamespace and name for the cutover manifest.
--deploy-server, --deploy-token, --deploy-insecure-skip-tls-verify, --deploy-kubectlCluster connection for --cutover. Omit --deploy-server/--deploy-token to use the current oc/kubectl login.

vrtmv run-status -o <dir> prints the last recorded phase/verdict without running anything — poll this from a pipeline instead of tailing output.

Phases and the run-state file

Progress is written to <out>/.vrtmv-run-state.json after each phase (plan, apply, config_carry, data_copy, verify, cutover). --resume re-reads it and skips whatever already completed. run always re-runs planning even on resume — it’s cheap, and it’s what holds the source root open for the phases after it.

What it refuses to automate

Database export/import. If the data plan includes a database, run stops and names it as a blocking manual step rather than running an export/import command with no verified credentials to run it with. Follow <out>/data/vrtmv-db-runbook.md by hand, then --resume.

Workload data from an --ssh source runs on the source host itself. SSH collection only pulls the paths config analysis needs, not arbitrary application data, so the locally collected root has nothing to copy from. run instead discovers, hashes, and copies --copy paths directly on the source over its own SSH connection — database classification is the same path match data plan uses, so a database is still refused. The copy needs the orchestrator’s ssh-agent forwarded to the source so it can authenticate to the target without the target’s key ever being copied there: use an agent that already has the target’s key loaded, or pass --target-ssh-key to load one into a throwaway agent.

A partial package-install does not abort the run

The generated role installs packages individually and reports whenever any package can’t install under its own name — including the common case where the target’s base already provides that capability under a different name (curl-minimal providing curl on an EL9-family target). That makes ansible-playbook itself exit non-zero, but run doesn’t treat it as fatal: it logs the failure and continues to config-carry and verify, because verify’s provides-aware check is the real judge of parity, not one Ansible task’s exit code.

Exit codes

Only a Done outcome with verdict equivalent exits zero. Blocked (a translation blocker, a refused unattended step, or a non-equivalent verify verdict) and Failed (a genuine infrastructure error — couldn’t connect, couldn’t run ansible-playbook) both exit non-zero, so a pipeline can’t go green on an incomplete migration.