banger/internal/daemon
Thales Maciel a59958d4f5
daemon: roll back host state on any Open() failure
Open() touched several pieces of host state before hitting the step
that returned the error:

  * SQLite handle (store.Open)
  * managed SSH client config block (ensureVMSSHClientConfig)
  * vm-DNS UDP listener goroutine (startVMDNS)
  * systemd-resolved per-interface routing (ensureVMDNSResolverRouting)

The only deferred cleanup guarded stopVMDNS. A reconcile() or
initializeTapPool() failure therefore left the listener running, the
resolver wiring in place, and the SQLite handle open. A subsequent
startup attempt ran into "port 42069 already in use" or silently
published stale state.

Fix: once `d` exists, defer `d.Close()` on `err != nil`. Close is
idempotent (sync.Once) and every teardown step (listener close, DNS
listener close, resolver revert, session registry close, store close)
is nil-guarded, so calling it on a daemon that never got past the
first startup step is safe.

Tests (internal/daemon/open_close_test.go):

  - TestCloseOnPartiallyInitialisedDaemon: Close survives a daemon
    with only store + closing channel, and with a vmDNS listener but
    nothing else. Catches regressions where a teardown step forgets
    to nil-check.
  - TestCloseIdempotentUnderConcurrency: 5 goroutines racing on
    Close() never panic (sync.Once + close(d.closing) survive).
  - TestOpenFailureRunsCloseCleanup: structural check that the
    `defer cleanup() if err != nil` pattern actually fires.

Live: `banger daemon stop` cleanly, `banger vm ls` restarts daemon
without a residual listener on port 42069.
2026-04-19 16:36:29 -03:00
..
dmsnap Extract opstate and dmsnap into subpackages 2026-04-15 16:02:43 -03:00
fcproc Extract fcproc subpackage for firecracker process helpers 2026-04-15 16:11:39 -03:00
imagemgr Remove image build --from-image; doctor treats catalog images as OK 2026-04-18 15:54:29 -03:00
opstate coverage: medium batch — hostnat runner, store guest-sessions, daemon helpers 2026-04-18 18:03:37 -03:00
session coverage: medium batch — hostnat runner, store guest-sessions, daemon helpers 2026-04-18 18:03:37 -03:00
workspace Extract workspace subpackage with pure repo helpers 2026-04-15 16:37:19 -03:00
ARCHITECTURE.md remove experimental web UI 2026-04-19 14:28:08 -03:00
autopull_test.go vm create: auto-pull image and kernel from catalogs if missing 2026-04-18 15:10:26 -03:00
capabilities.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
capabilities_test.go Remove opencode package + vm acp command (dead code) 2026-04-18 16:54:37 -03:00
daemon.go daemon: roll back host state on any Open() failure 2026-04-19 16:36:29 -03:00
daemon_test.go remove experimental web UI 2026-04-19 14:28:08 -03:00
dns_routing.go Route .vm DNS through systemd-resolved 2026-03-22 15:07:22 -03:00
dns_routing_test.go Route .vm DNS through systemd-resolved 2026-03-22 15:07:22 -03:00
doc.go remove experimental web UI 2026-04-19 14:28:08 -03:00
doctor.go vm defaults: host-aware sizing + spec line on spawn + doctor check 2026-04-19 13:06:51 -03:00
fastpath_test.go Manage image artifacts and show VM create progress 2026-03-21 14:48:01 -03:00
guest_sessions.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
guest_sessions_test.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
image_seed.go guest sshd: drop DEBUG3 + StrictModes no; normalise /root perms 2026-04-19 13:40:40 -03:00
images.go Remove image build --from-image; doctor treats catalog images as OK 2026-04-18 15:54:29 -03:00
images_helpers_test.go coverage: medium batch — hostnat runner, store guest-sessions, daemon helpers 2026-04-18 18:03:37 -03:00
images_pull.go vm create: auto-pull image and kernel from catalogs if missing 2026-04-18 15:10:26 -03:00
images_pull_bundle_test.go image pull: dispatch to imagecat bundle path before OCI 2026-04-17 15:43:33 -03:00
images_pull_test.go Phase B-2: pre-inject banger guest agents into pulled rootfs 2026-04-16 18:08:56 -03:00
kernels.go Phase 4: remote catalog + banger kernel pull 2026-04-16 15:05:42 -03:00
kernels_test.go Phase 4: remote catalog + banger kernel pull 2026-04-16 15:05:42 -03:00
logger.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
logger_test.go Remove image build --from-image; doctor treats catalog images as OK 2026-04-18 15:54:29 -03:00
nat.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
nat_test.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
open_close_test.go daemon: roll back host state on any Open() failure 2026-04-19 16:36:29 -03:00
ports.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
preflight.go Remove image build --from-image; doctor treats catalog images as OK 2026-04-18 15:54:29 -03:00
runtime_assets.go Remove runtime-bundle image dependencies 2026-03-21 18:34:53 -03:00
session_attach.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
session_controller.go Extract session subpackage with pure guest-session helpers 2026-04-15 16:33:12 -03:00
session_lifecycle.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
session_stream.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
snapshot.go Extract opstate and dmsnap into subpackages 2026-04-15 16:02:43 -03:00
snapshot_test.go Harden VM stop cleanup for stale snapshots 2026-03-18 12:28:15 -03:00
ssh_client_config.go Configure direct SSH access for .vm hosts 2026-03-22 16:48:42 -03:00
ssh_client_config_test.go Configure direct SSH access for .vm hosts 2026-03-22 16:48:42 -03:00
sshd_config_test.go guest sshd: drop DEBUG3 + StrictModes no; normalise /root perms 2026-04-19 13:40:40 -03:00
tap_pool.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_authsync.go guest sshd: drop DEBUG3 + StrictModes no; normalise /root perms 2026-04-19 13:40:40 -03:00
vm_create.go vm create: auto-pull image and kernel from catalogs if missing 2026-04-18 15:10:26 -03:00
vm_create_ops.go Add lint targets, fix gofmt drift, broaden Makefile build inputs 2026-04-16 16:49:17 -03:00
vm_disk.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_handles.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_handles_test.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_lifecycle.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_locks.go Move subsystem state/locks off Daemon into owning types 2026-04-15 15:58:33 -03:00
vm_set.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_stats.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
vm_test.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
workspace.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00
workspace_test.go vm state: split transient kernel/process handles off the durable schema 2026-04-19 14:18:13 -03:00