Skip to content

Review round: restart the Windows service on an error exit, deps, cuts, docs - #17

Merged
CMGS merged 9 commits into
mainfrom
review/round-2026-09-24
Sep 24, 2026
Merged

CMGS merged 9 commits into
mainfrom
review/round-2026-09-24

Conversation

@CMGS

@CMGS CMGS commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Whole-repo review round: dependency bump, one Windows service fix, review and cut commits, and docs the code contradicted.

Commits

  • build: mdlayher/vsock v1.3.0, x/sys v0.48.0, grpc v1.83.2 (GO-2026-6443; grpc is linked through core/log). projecteru2/core stays at v0.1.3: only its log package is borrowed.
    • vsock now maps a closed conn/listener to net.ErrClosed. Serve already handles a listener closed by the ctx, so nothing changes.
    • x/sys only adds symbols; every symbol the agent calls is unchanged.
  • fix: restart the Windows service after an error exit, not only after a crash.
    • serve returns an error after the 2-minute vsock listen retry runs out, or on a permanent accept error. Execute then returns exit code 1, so the SCM sees SERVICE_STOPPED with a non-zero exit code.
    • The installer set restart actions but never the failure-actions flag. Without it, the SCM queues those actions only when the process dies without reporting STOPPED. The agent stayed down until the next reboot, although the installer comment says it mirrors Restart=always.
    • sc.exe failure plus sc.exe failureflag 1 now run after the create/update branch, so a fresh install and a re-run over an existing service converge to the same settings.
    • The shipped win11 image has FAILURE_ACTIONS_ON_NONCRASH_FAILURES: FALSE today. It needs a re-bake after the next agent release.
  • review: the Linux vsock constructors move below the listener type they build, matching the Windows file (review: json.Encoder frames, mergeEnv cut, comment budget across the agent #12). Layout only.
  • review: errors.AsType for the exit code; the serve log tag is cmd.serve (Cobra dispatch rule); the host-peer test conn embeds net.Conn.
  • cut: the Windows process controller folds into setupProcess closures. The syscalls, their order, and the single job close are unchanged.
  • docs:
    • The auth boundary is access to the hypervisor's host-side vsock socket (cocoon's per-VM hybrid-vsock Unix socket), not vhost_vsock.
    • The README quick start uses cocoon vm exec.
  • cut: drop the client subcommand.
    • It came in 06dee79 (2026-05-05) for the pre-integration kernel-vsock design. Six hours later cocoon 7174e76 reached the agent over Cloud Hypervisor hybrid vsock: a per-VM Unix socket plus CONNECT, constant guest CID 3. So host AF_VSOCK never had a cocoon VM to reach, and the guest-side dial is refused by the host-only listeners.
    • No caller in the workspace. The client Go package stays (cocoon imports it). With dialVsock gone, the Windows newVsockSocket helper had one caller and is inlined.
    • usage.md, configuration.md, index.md and the README highlights now describe cocoon vm exec as the host path.

Numbers

  • Production Go net −107 (1499 → 1392 lines); tests +2/−10 (net −8); go.mod/go.sum/ps1/docs, see the diff.
  • Go comment lines: +1/−4 (one rewritten in place; three deleted with their code).

Evidence

Gates on the final HEAD:

golangci-lint v2.13.2 GOOS=linux|darwin|windows   0 issues. (each)
asl ./... linux/darwin/windows: no findings; go vet linux/darwin/windows: ok
make fmt-check rc=0
go test -race -count=1 ./... (darwin): agent ok, client ok
go test -race -count=1 ./... (golang:1.27 linux/arm64 container):
ok  github.com/cocoonstack/cocoon-agent/agent   3.136s
ok  github.com/cocoonstack/cocoon-agent/client  1.023s
ok  github.com/cocoonstack/cocoon-agent/cmd     1.020s

Windows guest run: win11:25h2 cloudimg, 16 vCPU, cloud-hypervisor. The agent was swapped in place as a service through a SYSTEM scheduled task, and the installed binary's --version rev was checked before each arm. Arms: main = 5afc189, round = this branch's HEAD, both built with the Makefile ldflags.

Installer, run over the image's existing service (the update branch):

before:  FAILURE_ACTIONS_ON_NONCRASH_FAILURES:  FALSE      (shipped image)
install: rc=0, "Service status: Running", viosock present
after:   FAILURE_ACTIONS: RESTART/5000 x3, RESET_PERIOD 86400
         FAILURE_ACTIONS_ON_NONCRASH_FAILURES:  TRUE

Error-exit restart. binPath is set to serve --bogus, so Execute returns exit code 1 on every start. Each arm is one sc start plus 32 s, with SCM events read from the System log:

NEG failureflag=0: 1 event   id=7023 "terminated with the following error"; no restart; final Stopped exit=1
POS failureflag=1: 14 events 7023 + 7031 "terminated unexpectedly ... corrective action ... Restart the service" every 5 s (7 restarts in 32 s)
restored binPath: Running, failureflag TRUE

Job and exec matrix. The ping.exe detector was checked with a positive control first: a live session running ping is seen.

                                                         main 5afc189   round
T0 detector positive control                             PASS           PASS
T1 echo / T2 exit 7 / T3 stderr / T4 stdin               PASS           PASS
T5 cmd start/b grandchild, client SIGKILL at 3 s         0/10 left      0/10 left
T6 powershell Start-Process grandchild, client SIGKILL   0/5 left       0/5 left
T9 grandchild after a normal exit (job closed)           0/10 left      0/10 left
T7 8 concurrent execs                                    8/8            8/8

Exec latency: 50 sequential cmd.exe /c echo per batch, arms interleaved by swapping the service binary:

A1-main 71 ms   B1-round 70 ms
A2-main 70 ms   B2-round 69 ms
A3-main 70 ms   B3-round 71 ms

Windows smoke of the cut (5b03f5c) on a fresh win11:25h2 guest, agent swapped in as the service:

T0 detector positive control  PASS
T1 echo / T2 exit 7 / T3 stderr / T4 stdin   PASS
T5 cmd start/b grandchild, client SIGKILL    0/10 left
T6 powershell Start-Process grandchild       0/5 left
T9 grandchild after a normal exit            0/10 left
T7 8 concurrent execs                        8/8
50 sequential execs                          76 ms/exec (one batch, not interleaved)

…cteru2/core v0.1.3→v0.1.5, golang.org/x/sys v0.47.0→v0.48.0
SCM queues failure actions for a STOPPED status with a non-zero exit code only when the failure-actions flag is set; serve returns exit code 1 after the 2-minute listen retry or a permanent accept error. The failure actions and the flag now apply on both fresh installs and re-runs over an existing service.
…AF_VSOCK

The subcommand came in 06dee79 for the pre-integration kernel-vsock design. Six hours later cocoon 7174e76 reached the agent over Cloud Hypervisor hybrid vsock (per-VM Unix socket plus CONNECT, constant guest CID 3), so the subcommand never had a target. Nothing in the workspace calls it; the client Go package stays because cocoon imports it.
The agent borrows only core/log; the round's bump moved core and its sentry-go without a reason. vsock, x/sys and the grpc security fix stay.
It moved only with the reverted core bump and is not linked into the binary.
@CMGS
CMGS merged commit 88f21d0 into main Sep 24, 2026
2 checks passed
@CMGS
CMGS deleted the review/round-2026-09-24 branch September 24, 2026 02:38
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.

1 participant