Prerequisite for `banger update`'s preflight, which refuses to swap
binaries while anything is in flight. Today's opstate.Registry
exposes Insert/Get/Prune but no iteration; without a snapshot
accessor the update flow can't tell whether a vm.create is
mid-prepare-work-disk.
* opstate.Registry.List(): returns a freshly-allocated snapshot
of every entry. Mutating the slice doesn't poison the
registry. Pinned by tests covering the snapshot semantics
and the empty case.
* api.OperationSummary / OperationsListResult: a public-shape
record per op. Today the Kind is always "vm.create" — the
field exists so future async kinds (image.pull, kernel.pull)
plug in without an API change.
* Daemon.ListOperations + daemon.operations.list RPC:
walks vmService.createOps and emits OperationSummary entries.
Done ops are included in the snapshot; the update preflight
filters by Done itself.
* dispatch_test's documented-methods list updated.
No behaviour change for existing flows; this is a read-only
addition.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two leaves of the daemon package that carry no back-references to Daemon
move out:
- internal/daemon/opstate: generic Registry[T AsyncOp]. The AsyncOp
interface methods are capitalised (ID, IsDone, UpdatedAt, Cancel);
vmCreateOperationState and imageBuildOperationState implement it.
- internal/daemon/dmsnap: Create, Cleanup, Remove plus the Handles type
for device-mapper snapshot lifecycle. Takes an explicit Runner
interface. The daemon-package snapshot.go keeps thin forwarders and a
type alias so existing call sites and tests are untouched.
Skipped on purpose: tap_pool has too many Daemon-scoped dependencies
(config, store, closing, createTap) for a clean extraction at this
stage; nat.go is already a thin facade over internal/hostnat;
dns_routing.go tests tightly couple to package internals, so extraction
would be more churn than payoff. Each can be revisited when a
subsystem-level refactor forces the boundary.
All tests green.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>