Port the launcher to Go #2

Merged
benvin merged 4 commits from benvin/go-launcher into main 2026-10-24 18:43:23 +11:00
Member

The bash launcher shells out to podman for every step and is tested by a bash harness; a Go tool gives typed specs, unit tests against a fake engine and a packaged binary.

  • add Go agent-sandbox launcher with the same env, images and refusal checks; every argument passes through to claude or --exec verbatim
  • refuse launch dirs containing the runtime dir that holds the private API socket
  • drive podman through the v5 API bindings via a private per-session podman system service that stops when the launcher dies
  • port allowlist parsing and router config generation; replace tests/test.sh with go tests
  • build with podman-remote tags; RPM ships the binary and allowlist
  • release attaches the binary and RPM to the Gitea release
The bash launcher shells out to podman for every step and is tested by a bash harness; a Go tool gives typed specs, unit tests against a fake engine and a packaged binary. - add Go `agent-sandbox` launcher with the same env, images and refusal checks; every argument passes through to claude or `--exec` verbatim - refuse launch dirs containing the runtime dir that holds the private API socket - drive podman through the v5 API bindings via a private per-session `podman system service` that stops when the launcher dies - port allowlist parsing and router config generation; replace tests/test.sh with go tests - build with podman-remote tags; RPM ships the binary and allowlist - release attaches the binary and RPM to the Gitea release
unkin-agent added 1 commit 2026-10-24 16:49:54 +11:00
Port the launcher to Go on the podman API bindings
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
af55d83de6
Author
Member
  • main.go:337 — checkLaunchDir does not refuse launch dirs that are/contain $XDG_RUNTIME_DIR (or the /tmp fallback), so launching from e.g. /run/user/1000 bind-mounts the private podman.sock (podman.go:49) into claude: the sandbox gets the full host podman API (create containers with host mounts / egress net) → refuse any pwd that contains the api dir (and router tmp dir), same as the $HOME check; add a refusal test.
  • podman.go:59 — podman system service --time=0 in its own process group outlives a SIGKILLed launcher forever, leaving a live API socket in the runtime dir → add Pdeathsig: syscall.SIGTERM to SysProcAttr.
  • nit: .woodpecker/lint.yaml:6 — golangci/golangci-lint:latest is unpinned; lint results drift with upstream releases → pin a version.
- main.go:337 — `checkLaunchDir` does not refuse launch dirs that are/contain `$XDG_RUNTIME_DIR` (or the `/tmp` fallback), so launching from e.g. `/run/user/1000` bind-mounts the private `podman.sock` (podman.go:49) into claude: the sandbox gets the full host podman API (create containers with host mounts / egress net) → refuse any pwd that contains the api dir (and router tmp dir), same as the `$HOME` check; add a refusal test. - podman.go:59 — `podman system service --time=0` in its own process group outlives a SIGKILLed launcher forever, leaving a live API socket in the runtime dir → add `Pdeathsig: syscall.SIGTERM` to `SysProcAttr`. - nit: .woodpecker/lint.yaml:6 — `golangci/golangci-lint:latest` is unpinned; lint results drift with upstream releases → pin a version.
unkin-agent added 1 commit 2026-10-24 17:29:09 +11:00
Refuse launch dirs containing the API socket and stop the service with the launcher
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
818ec3f59c
Author
Member
  • main.go:48 — cobra resolves its version/help/completion subcommands from the first non-flag word anywhere in argv, so passthrough args are hijacked: agent-sandbox --exec podman version fails with Error: unknown flag: --exec instead of running in the sandbox, agent-sandbox help prints launcher help instead of claude help (bash passed all args through) → only dispatch a subcommand when os.Args[1] is exactly its name (otherwise go straight to launch), and add a test for --exec podman version.
- main.go:48 — cobra resolves its `version`/`help`/`completion` subcommands from the first non-flag word anywhere in argv, so passthrough args are hijacked: `agent-sandbox --exec podman version` fails with `Error: unknown flag: --exec` instead of running in the sandbox, `agent-sandbox help` prints launcher help instead of `claude help` (bash passed all args through) → only dispatch a subcommand when `os.Args[1]` is exactly its name (otherwise go straight to `launch`), and add a test for `--exec podman version`.
unkin-agent added 1 commit 2026-10-24 17:37:18 +11:00
Pass all arguments through to claude or --exec
ci/woodpecker/pr/pre-commit Pipeline was canceled
ci/woodpecker/pr/lint Pipeline was canceled
ci/woodpecker/pr/test Pipeline was canceled
ci/woodpecker/pr/build Pipeline was canceled
ea4ed4af9d
unkin-agent added 1 commit 2026-10-24 17:38:07 +11:00
Drop shell completions from the RPM
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2e3dafb28a
benvin merged commit 06e86ffd37 into main 2026-10-24 18:43:23 +11:00
benvin deleted branch benvin/go-launcher 2026-10-24 18:43:23 +11:00
Sign in to join this conversation.