WIP: Expose a durable VM identity and liveness query #1

Draft
toasterson wants to merge 1 commit from claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes into main
Owner

Anima work item 019f998d-c972-7d73-a4ae-c94c0430f204.

Callers need to answer "is the VM I started for job X still running?" after the caller itself has restarted. Today they cannot, so they track it in their own database and that record silently rots.

Observed downstream on archibald 2026-07-25: Solstice CI had 96 job rows in state running against 5 live qemu processes, four of them stale since 2026-07-05 (20 days). 19 job overlay directories existed for 5 live VMs. Nothing could reconcile because nothing could ask.

Required:

  • A VM handle that is durable across caller restarts — a stable identifier the caller can persist and later use to query, not an in-process struct that dies with the process.
  • A liveness query: given that identifier, report whether the VM is running, exited (with its status if known), or unknown/absent.
  • An enumeration: list VMs this library currently manages on the host, so a caller can find VMs it has lost track of entirely.
  • Liveness must be derived from the host (process/hypervisor state), not from a cache the library keeps in memory.

Design note: "unknown" is a legitimate third answer and must be distinguishable from "not running". A caller reaping jobs needs to treat "definitely gone" differently from "cannot tell" — reaping on "cannot tell" is how you kill a healthy long job.

Acceptance:

  • Start a VM, kill the calling process, start a new one, and correctly determine the VM is still running from the persisted identifier alone.
  • Same sequence but with the VM killed as well correctly reports exited/absent.
  • Enumeration finds a VM whose caller-side record was deleted.

Consumer: solstice-ci 019f998b-9cea-7bf3-87c4-c6a6ad24f0ef (reap orphaned jobs) and 019f998b-dbbd-7e33-8d96-b833ce05e4c5 (GC overlay dirs) both need exactly this predicate; implement it once here rather than twice there.

Anima work item `019f998d-c972-7d73-a4ae-c94c0430f204`. Callers need to answer "is the VM I started for job X still running?" after the caller itself has restarted. Today they cannot, so they track it in their own database and that record silently rots. Observed downstream on archibald 2026-07-25: Solstice CI had 96 job rows in state `running` against 5 live qemu processes, four of them stale since 2026-07-05 (20 days). 19 job overlay directories existed for 5 live VMs. Nothing could reconcile because nothing could ask. Required: - A VM handle that is durable across caller restarts — a stable identifier the caller can persist and later use to query, not an in-process struct that dies with the process. - A liveness query: given that identifier, report whether the VM is running, exited (with its status if known), or unknown/absent. - An enumeration: list VMs this library currently manages on the host, so a caller can find VMs it has lost track of entirely. - Liveness must be derived from the host (process/hypervisor state), not from a cache the library keeps in memory. Design note: "unknown" is a legitimate third answer and must be distinguishable from "not running". A caller reaping jobs needs to treat "definitely gone" differently from "cannot tell" — reaping on "cannot tell" is how you kill a healthy long job. Acceptance: - Start a VM, kill the calling process, start a new one, and correctly determine the VM is still running from the persisted identifier alone. - Same sequence but with the VM killed as well correctly reports exited/absent. - Enumeration finds a VM whose caller-side record was deleted. Consumer: solstice-ci `019f998b-9cea-7bf3-87c4-c6a6ad24f0ef` (reap orphaned jobs) and `019f998b-dbbd-7e33-8d96-b833ce05e4c5` (GC overlay dirs) both need exactly this predicate; implement it once here rather than twice there.
toasterson force-pushed claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes from 14a0563985 to 4b9f08aaa5 2026-07-25 16:00:36 +00:00 Compare
toasterson force-pushed claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes from 4b9f08aaa5 to 3a8815f27f 2026-07-25 16:41:05 +00:00 Compare
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes:claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git rebase main
git switch main
git merge --ff-only claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git rebase main
git switch main
git merge --no-ff claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch main
git merge --squash claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch main
git merge --ff-only claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git switch main
git merge claude/wi-019f998d-expose-a-durable-vm-identity-and-livenes
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
CloudNebulaProject/vm-manager!1
No description provided.