Target sbx 0.37 clone mode
sbx 0.29 isolated the agent with --branch, creating a host-side Git worktree. 0.37 removed that flag and reinstated --clone, which gives the agent a private in-container clone mounted read-only and exposes its commits through a sandbox-<name> git remote on the host. Setup fails outright against 0.37 with '--branch is no longer supported'. Drops the branch name plumbing entirely, since the sandbox now owns the clone and there is no host branch to name. Documents the two host prerequisites this surfaced: membership of the kvm group, because sandboxes are microVMs, and the docker-sbx package rather than docker-sandbox-bin on Arch derivatives - the latter installs only the CLI, omitting the microVM kernel, rootfs and nerdbox shim, which makes sbx fall back to mounting filesystems on the host and fail for any non-root user.
This commit is contained in:
@@ -55,7 +55,8 @@ Install these on the **host** — none of them are needed inside the sandbox.
|
|||||||
| Tool | Purpose | Install |
|
| Tool | Purpose | Install |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| [mise](https://mise.jdx.dev/) | Runs the task and distributes it | [Getting started](https://mise.jdx.dev/getting-started.html) |
|
| [mise](https://mise.jdx.dev/) | Runs the task and distributes it | [Getting started](https://mise.jdx.dev/getting-started.html) |
|
||||||
| [Docker Sandboxes (`sbx`)](https://docs.docker.com/ai/sandboxes/) | Sandbox, secret store, credential proxy | Ships with [Docker Desktop](https://docs.docker.com/desktop/) |
|
| [Docker Sandboxes (`sbx`)](https://docs.docker.com/ai/sandboxes/) | Sandbox, secret store, credential proxy | [Get started](https://docs.docker.com/ai/sandboxes/get-started/) — Docker Desktop is **not** required |
|
||||||
|
| KVM + membership of the `kvm` group | Sandboxes are microVMs | `sudo usermod -aG kvm $USER`, then re-login |
|
||||||
| [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), [`jq`](https://jqlang.org/) | `aws configure export-credentials` | Required only when using `--aws-profile` |
|
| [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), [`jq`](https://jqlang.org/) | `aws configure export-credentials` | Required only when using `--aws-profile` |
|
||||||
| `git`, `sha256sum` | Repository identity | Already present on most systems |
|
| `git`, `sha256sum` | Repository identity | Already present on most systems |
|
||||||
| `xdg-open` / `open` / `$BROWSER` | Opens the token form | Optional — the link is printed if absent |
|
| `xdg-open` / `open` / `$BROWSER` | Opens the token form | Optional — the link is printed if absent |
|
||||||
@@ -73,8 +74,19 @@ mise --version
|
|||||||
sbx version
|
sbx version
|
||||||
aws --version
|
aws --version
|
||||||
jq --version
|
jq --version
|
||||||
|
lsmod | grep kvm # must show kvm_intel, kvm_amd or kvm
|
||||||
|
id -nG | grep -w kvm # you must be in the kvm group
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`sbx` requires **0.37 or later** — `--clone` replaced the older `--branch` flag, and
|
||||||
|
this task uses `--clone`.
|
||||||
|
|
||||||
|
On Arch derivatives, install the **`docker-sbx`** AUR package, not
|
||||||
|
`docker-sandbox-bin`. The latter ships only the CLI binary, omitting the microVM
|
||||||
|
kernel, rootfs, and `containerd-shim-nerdbox-v1`. Without those, `sbx` has no VM to
|
||||||
|
boot and falls back to mounting filesystems on the host, which fails with
|
||||||
|
`operation not permitted` for any non-root user.
|
||||||
|
|
||||||
### User-level install (recommended)
|
### User-level install (recommended)
|
||||||
|
|
||||||
Adding the task to your personal mise config makes `ai:sbx` available in every Git
|
Adding the task to your personal mise config makes `ai:sbx` available in every Git
|
||||||
@@ -109,7 +121,6 @@ Optional personal defaults:
|
|||||||
[env]
|
[env]
|
||||||
AI_SBX_AGENT = "codex"
|
AI_SBX_AGENT = "codex"
|
||||||
AI_SBX_MODE = "clone"
|
AI_SBX_MODE = "clone"
|
||||||
AI_SBX_BRANCH = "ai-sbx"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Confirm it loaded:
|
Confirm it loaded:
|
||||||
@@ -246,9 +257,8 @@ provider "aws" {
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `--aws-profile NAME` | none | Host profile to expose. Repeatable. Trailing `-readonly` stripped inside the sandbox |
|
| `--aws-profile NAME` | none | Host profile to expose. Repeatable. Trailing `-readonly` stripped inside the sandbox |
|
||||||
| `--agent NAME` | `codex` | Sandbox agent. See `sbx create --help` for the list |
|
| `--agent NAME` | `codex` | Sandbox agent. See `sbx create --help` for the list |
|
||||||
| `--clone` | on | Give the agent a Git worktree on its own branch |
|
| `--clone` | on | Give the agent a private in-container clone; its commits reach the host via the `sandbox-<name>` git remote |
|
||||||
| `--direct` | off | Mount the host working tree read-write |
|
| `--direct` | off | Mount the host working tree read-write |
|
||||||
| `--branch NAME` | `ai-sbx` | Branch used by `--clone` |
|
|
||||||
| `--replace` | off | Destroy and recreate an existing sandbox |
|
| `--replace` | off | Destroy and recreate an existing sandbox |
|
||||||
|
|
||||||
### Environment defaults
|
### Environment defaults
|
||||||
@@ -257,7 +267,6 @@ provider "aws" {
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `AI_SBX_AGENT` | `codex` | `--agent` |
|
| `AI_SBX_AGENT` | `codex` | `--agent` |
|
||||||
| `AI_SBX_MODE` | `clone` | `--clone` / `--direct` |
|
| `AI_SBX_MODE` | `clone` | `--clone` / `--direct` |
|
||||||
| `AI_SBX_BRANCH` | `ai-sbx` | `--branch` |
|
|
||||||
| `AI_SBX_TOKEN_DAYS` | `30` | token expiry pre-filled on the form (1–366, or `none`) |
|
| `AI_SBX_TOKEN_DAYS` | `30` | token expiry pre-filled on the form (1–366, or `none`) |
|
||||||
|
|
||||||
## AWS profile naming
|
## AWS profile naming
|
||||||
@@ -285,7 +294,7 @@ Variants such as `_readonly`, `-ro`, and `-read-only` are **not** stripped.
|
|||||||
~/.config/ai-sbx/repos/<digest>/config mode 600, no secrets
|
~/.config/ai-sbx/repos/<digest>/config mode 600, no secrets
|
||||||
```
|
```
|
||||||
|
|
||||||
Holds repository identity, sandbox name, agent, mode, branch, and the approved host
|
Holds repository identity, sandbox name, agent, mode, and the approved host
|
||||||
profile names — no secrets. The GitHub token lives in the `sbx` secret store; AWS
|
profile names — no secrets. The GitHub token lives in the `sbx` secret store; AWS
|
||||||
credentials exist only inside the sandbox and only until they expire.
|
credentials exist only inside the sandbox and only until they expire.
|
||||||
|
|
||||||
|
|||||||
+9
-23
@@ -5,7 +5,6 @@ PROGRAM="ai:sbx"
|
|||||||
CONFIG_ROOT="${XDG_CONFIG_HOME:-$HOME/.config}/ai-sbx"
|
CONFIG_ROOT="${XDG_CONFIG_HOME:-$HOME/.config}/ai-sbx"
|
||||||
DEFAULT_AGENT="${AI_SBX_AGENT:-codex}"
|
DEFAULT_AGENT="${AI_SBX_AGENT:-codex}"
|
||||||
DEFAULT_MODE="${AI_SBX_MODE:-clone}"
|
DEFAULT_MODE="${AI_SBX_MODE:-clone}"
|
||||||
DEFAULT_BRANCH="${AI_SBX_BRANCH:-ai-sbx}"
|
|
||||||
DEFAULT_TOKEN_DAYS="${AI_SBX_TOKEN_DAYS:-30}"
|
DEFAULT_TOKEN_DAYS="${AI_SBX_TOKEN_DAYS:-30}"
|
||||||
|
|
||||||
# GitHub accepts these as query parameters on the token creation form. A write
|
# GitHub accepts these as query parameters on the token creation form. A write
|
||||||
@@ -51,9 +50,10 @@ Setup options:
|
|||||||
written into the sandbox.
|
written into the sandbox.
|
||||||
--agent NAME Sandbox agent. Default: codex
|
--agent NAME Sandbox agent. Default: codex
|
||||||
--direct Mount the host working tree read-write.
|
--direct Mount the host working tree read-write.
|
||||||
--clone Give the agent a Git worktree on its own
|
--clone Give the agent a private in-container clone
|
||||||
branch. This is the default.
|
of the repository, mounted read-only.
|
||||||
--branch NAME Branch used by --clone. Default: ai-sbx
|
Its commits reach the host through the
|
||||||
|
sandbox-<name> git remote. This is the default.
|
||||||
--replace Replace the existing sandbox.
|
--replace Replace the existing sandbox.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@@ -289,7 +289,6 @@ load_config() {
|
|||||||
[[ -n "${CONFIG_AGENT:-}" ]] ||
|
[[ -n "${CONFIG_AGENT:-}" ]] ||
|
||||||
die "Agent is missing from $REPO_CONFIG_FILE"
|
die "Agent is missing from $REPO_CONFIG_FILE"
|
||||||
|
|
||||||
CONFIG_BRANCH="${CONFIG_BRANCH:-$DEFAULT_BRANCH}"
|
|
||||||
|
|
||||||
declare -p CONFIG_AWS_PROFILES >/dev/null 2>&1 ||
|
declare -p CONFIG_AWS_PROFILES >/dev/null 2>&1 ||
|
||||||
CONFIG_AWS_PROFILES=()
|
CONFIG_AWS_PROFILES=()
|
||||||
@@ -298,8 +297,7 @@ load_config() {
|
|||||||
save_config() {
|
save_config() {
|
||||||
local agent="$1"
|
local agent="$1"
|
||||||
local mode="$2"
|
local mode="$2"
|
||||||
local branch="$3"
|
shift 2
|
||||||
shift 3
|
|
||||||
local -a profiles=("$@")
|
local -a profiles=("$@")
|
||||||
|
|
||||||
mkdir -p "$REPO_CONFIG_DIR"
|
mkdir -p "$REPO_CONFIG_DIR"
|
||||||
@@ -310,7 +308,6 @@ save_config() {
|
|||||||
printf 'CONFIG_SANDBOX=%q\n' "$SANDBOX_NAME"
|
printf 'CONFIG_SANDBOX=%q\n' "$SANDBOX_NAME"
|
||||||
printf 'CONFIG_AGENT=%q\n' "$agent"
|
printf 'CONFIG_AGENT=%q\n' "$agent"
|
||||||
printf 'CONFIG_MODE=%q\n' "$mode"
|
printf 'CONFIG_MODE=%q\n' "$mode"
|
||||||
printf 'CONFIG_BRANCH=%q\n' "$branch"
|
|
||||||
|
|
||||||
printf 'CONFIG_AWS_PROFILES=('
|
printf 'CONFIG_AWS_PROFILES=('
|
||||||
local profile
|
local profile
|
||||||
@@ -514,10 +511,10 @@ create_sandbox() {
|
|||||||
--name "$SANDBOX_NAME"
|
--name "$SANDBOX_NAME"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Clone mode gives the agent a Git worktree on its own branch, so its
|
# Clone mode gives the agent its own in-container clone, so its commits
|
||||||
# commits never land on whatever the host has checked out.
|
# never land on whatever the host has checked out.
|
||||||
if [[ "$CONFIG_MODE" == "clone" ]]; then
|
if [[ "$CONFIG_MODE" == "clone" ]]; then
|
||||||
create_args+=(--branch "$CONFIG_BRANCH")
|
create_args+=(--clone)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
create_args+=(
|
create_args+=(
|
||||||
@@ -531,7 +528,6 @@ create_sandbox() {
|
|||||||
setup_command() {
|
setup_command() {
|
||||||
local agent="$DEFAULT_AGENT"
|
local agent="$DEFAULT_AGENT"
|
||||||
local mode="$DEFAULT_MODE"
|
local mode="$DEFAULT_MODE"
|
||||||
local branch="$DEFAULT_BRANCH"
|
|
||||||
local replace=false
|
local replace=false
|
||||||
local -a aws_profiles=()
|
local -a aws_profiles=()
|
||||||
|
|
||||||
@@ -551,11 +547,6 @@ setup_command() {
|
|||||||
mode="clone"
|
mode="clone"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--branch)
|
|
||||||
(($# >= 2)) || die "--branch requires a value"
|
|
||||||
branch="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--direct)
|
--direct)
|
||||||
mode="direct"
|
mode="direct"
|
||||||
shift
|
shift
|
||||||
@@ -581,7 +572,7 @@ setup_command() {
|
|||||||
validate_aws_profile "$profile"
|
validate_aws_profile "$profile"
|
||||||
done
|
done
|
||||||
|
|
||||||
save_config "$agent" "$mode" "$branch" "${aws_profiles[@]}"
|
save_config "$agent" "$mode" "${aws_profiles[@]}"
|
||||||
|
|
||||||
if sandbox_exists; then
|
if sandbox_exists; then
|
||||||
if [[ "$replace" == true ]]; then
|
if [[ "$replace" == true ]]; then
|
||||||
@@ -610,7 +601,6 @@ Repository: $REPOSITORY
|
|||||||
Sandbox: $SANDBOX_NAME
|
Sandbox: $SANDBOX_NAME
|
||||||
Agent: $agent
|
Agent: $agent
|
||||||
Mode: $mode
|
Mode: $mode
|
||||||
Branch: $branch
|
|
||||||
|
|
||||||
Run it with:
|
Run it with:
|
||||||
|
|
||||||
@@ -666,10 +656,6 @@ status_command() {
|
|||||||
printf 'Agent: %s\n' "$CONFIG_AGENT"
|
printf 'Agent: %s\n' "$CONFIG_AGENT"
|
||||||
printf 'Mode: %s\n' "$CONFIG_MODE"
|
printf 'Mode: %s\n' "$CONFIG_MODE"
|
||||||
|
|
||||||
if [[ "$CONFIG_MODE" == "clone" ]]; then
|
|
||||||
printf 'Branch: %s\n' "$CONFIG_BRANCH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf 'Token days: %s\n' "$DEFAULT_TOKEN_DAYS"
|
printf 'Token days: %s\n' "$DEFAULT_TOKEN_DAYS"
|
||||||
|
|
||||||
printf 'AWS profiles (host -> sandbox):\n'
|
printf 'AWS profiles (host -> sandbox):\n'
|
||||||
|
|||||||
Reference in New Issue
Block a user