fix(template): make deploy/prepare deterministic and safe to re-run
Four defects, each of which could waste a full template rebuild: 1. getGuestIPAddress was called without -wait, so vmrun answered "The VMware Tools are not running" unless the Tools happened to have registered the IP at that exact instant. A guest that was booted, on the network and answering SSH could still burn the entire 10-minute Step 7 budget. This race is the likely cause of every intermittent "no guest IP" incident so far, including ones previously attributed to wedged vmnet DHCP. AGENTS.md #10 already prescribed -wait; the code did not follow it. 2. --force did not check whether the target VM was powered on. It deleted the live .vmdk.lck as a stale artifact and Step 4 rewrote the base VMDK under the running guest, killing it; the damage surfaced ten minutes later as an IP timeout because `vmrun list` still showed the OLD instance. 3. Step 6 accepted "VM appears in vmrun list" as proof of power-on, which a pre-existing instance satisfies. Check the exit code of `vmrun start`. 4. The cloud-init seed ISO was detached while the VM was still running, and VMware rewrote the VMX from its in-memory copy at power-off, restoring ide1:0.present = "TRUE". Every clone would boot with the seed attached (AGENTS.md #6). Detach it in prepare, after power-off and before the snapshot. Also in this change: - --then-prepare chains deploy into the matching prepare in one run, reusing the VM deploy leaves running. The two commands stay separately invocable. The guest toolchain script is resolved and verified BEFORE any VM work, so a wrong working directory costs two seconds instead of failing the hand-off after a 45-minute deploy; --toolchain-script allows running from anywhere. - Corrected the final messages: deploy-rust told the user to run prepare-linux, and both deploy commands reported a snapshot name (PostInstall-Linux) that no command ever creates. The prepare hand-off hint passed a bare filename to --template and omitted --snapshot, so copy-pasting it cloned BaseClean, the Windows snapshot. - template backup --exclude, repeatable, for retired templates. An unknown name or --exclude without --all-templates is an error rather than a silent no-op. test_deploy_linux_full_happy_path declared the VM already running before Step 6, an impossible state that masked the new --force guard; its vmrun mock is now stateful.
This commit is contained in: