Skip to content

libvirt ssh: Start the domain if it is shut off - #406

Open
cgwalters-bot wants to merge 2 commits into
bootc-dev:mainfrom
cgwalters-forge:bot/libvirt-ssh-autostart
Open

cgwalters-bot wants to merge 2 commits into
bootc-dev:mainfrom
cgwalters-forge:bot/libvirt-ssh-autostart

Conversation

@cgwalters-bot

Copy link
Copy Markdown
Contributor

A persistent VM that was stopped (by bcvk libvirt stop, a host reboot, or shutting down from inside the guest) made bcvk libvirt ssh fail with a hint to run virsh start. Since starting it and retrying is always the next step, libvirt ssh now does that itself for a domain that is shut off: it prints a notice on stderr (so a remote command's stdout stays clean), starts the domain, and waits for SSH with the same 180s timeout libvirt run --ssh-wait uses, since the guest has to boot first. Other states (paused, crashed, ...) still produce an error, since the right action there is less clear.

This is a behavior change for scripts: bcvk libvirt ssh VM -- cmd against a stopped VM used to fail fast, and now boots the VM (which keeps running afterwards) and runs the command.

This is the auto-start half of #158. Stopping idle VMs automatically would need something inside the guest (and, as noted in the issue, not every use case runs systemd), so it's left for later.

A second commit gives libvirt start --ssh the same longer wait: it used to connect with the 60s retry meant for an already running guest, right after virsh start.

A new integration test, test_libvirt_ssh_autostart, creates a VM, force-stops it, then checks that libvirt ssh VM -- echo hello succeeds with exactly hello on stdout, the notice on stderr, and the domain running afterwards. It boots a full VM, so it's added to the tests nextest runs one at a time. The man page documents the new behavior.

Tested on a 16-core RHEL 10.2 devspace with KVM and libvirt (qemu:///session):

  • make validate and cargo test pass (82 + 22 unit tests).
  • test_libvirt_ssh_autostart passes under the integration profile on centos-bootc:stream10.
  • By hand: after libvirt stop --force, bcvk libvirt start --ssh VM </dev/null waited for the boot and exited 0 after 29s, with the domain running.

CI note (2026-09-24): the integration-tests (2) failure is unrelated to this change: just pull-test-images failed with "fetching blob: authentication required" from quay mid-pull, before any test ran, the flake targeted by cgwalters-forge#2. Reran the failed jobs once.

Related: #158

The Signed-off-by: Colin Walters <walters@verbum.org> on these commits was added on cgwalters's approval of the review draft: cgwalters-forge#6 (review)

Generated-by: https://github.com/cgwalters/#llms

A persistent VM that was stopped (by `bcvk libvirt stop`, a host
reboot, or shutting down from inside the guest) previously made
`bcvk libvirt ssh` fail with a hint to run `virsh start`. The obvious
next step is always to start it and retry, so just do that: start a
shut off domain, say so on stderr (so that the output of a remote
command stays clean), and wait for SSH with the same longer timeout
`libvirt run --ssh-wait` uses, since the guest has to boot first.

Other states (paused, crashed, ...) still produce an error, since
it's less clear what the right action is there.

This is only the auto-start half of the issue; stopping idle VMs
automatically would need something inside the guest and is left
for later.

The new integration test boots a full VM, so it joins the tests that
nextest runs one at a time.

Related: bootc-dev#158
Generated-by: AI
Signed-off-by: Colin Walters <walters@verbum.org>
`libvirt start --ssh` connected with the 60s retry of `libvirt ssh`,
which is meant for a guest that is already up. Right after `virsh
start` the guest still has to boot, which can take longer, so wait
for SSH with the same timeout as `libvirt run --ssh` and a `libvirt
ssh` that just started the domain.

Generated-by: AI
Signed-off-by: Colin Walters <walters@verbum.org>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Automatically booting and leaving VMs running changes script-visible lifecycle behavior and warrants final human review.

No open issues 🎉

What changed in this PR

This PR implements the auto-start portion of #158: bcvk libvirt ssh starts shut-off VMs before connecting, while continuing to reject other non-running states.

Changes:

  • Auto-start shut-off domains with a stderr notice and a 180-second SSH retry window.
  • Give libvirt start --ssh the same boot-time wait.
  • Document the behavior and add a serialized integration test covering auto-start, output, and final domain state.
File Description
docs/​src/​man/​bcvk-libvirt-ssh.md Documents automatic startup and adds a stopped-VM example.
crates/​kit/​src/​libvirt/​start.rs Waits for SSH readiness after starting the VM.
crates/​kit/​src/​libvirt/​ssh.rs Starts shut-off domains and selects the longer boot timeout.
crates/​kit/​src/​libvirt/​run.rs Exposes the shared boot timeout and SSH readiness helper.
crates/​integration-tests/​src/​tests/​libvirt_verb.rs Tests auto-start, clean stdout, the stderr notice, and running state.
.config/​nextest.toml Includes the new VM test in the serialized test group.

Review effort: Balanced

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants