Host-level sandbox tasks: LocalExecutor + bwrap workspace-write
Docker outer layer and bwrap inner layer are mutually exclusive on this host (fresh proc mounts fail with kernel EPERM inside Docker's nested pidns, but work on the host under a userns profile). So tasks that need an inner sandbox run on the host: - Worker --claim-executor-only: strict executor claim (only executor == own type, never NULL). The host worker MUST use it, or it would steal NULL-executor tasks meant for Docker workers (those tasks would lose the Docker outer layer). Default behavior unchanged (NULL claimable by any worker). - host-config-host.json: sandbox workspace-write, state work/host-state-host.json (distinct from Docker tasks' host-state.json), same relay home and test repo as Docker. - deploy/apparmor/codex-host: docker-codex base + userns, mount, pivot_root for bwrap; still denies raw network, ptrace, dangerous capabilities, /proc/sys writes. - deploy/host-worker/codex-host-worker.service: aa-exec -p codex-host, --executor local --claim-executor-only, capacity 2, proxy env 127.0.0.1:8888 so host tasks' relay/git egress also goes through the Tinyproxy allowlist (host direct egress would bypass it). POST /tasks already accepts executor (local/docker/cloud), so no API change was needed for routing. Tests: 4 host-sandbox-routing tests (strict claim incl. CAS, default still takes NULL, config sandbox/state, profile allows bwrap without deny mount). Full suites pass.
This commit is contained in:
1 parent
67acddaf7c
commit
5d09af855f
6 files changed
+266
-2
No files matched your search
@@ -0,0 +1,35 @@
|
||||
[Unit]
|
||||
Description=Codex host-level sandbox worker (LocalExecutor, bwrap inner sandbox)
|
||||
After=network.target codex-cloud-server.service
|
||||
Wants=codex-cloud-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=codexsvc
|
||||
Group=codexsvc
|
||||
WorkingDirectory=/opt/codex-app-server
|
||||
# EnvironmentFile supplies CLOUD_DB_* and XCM_API_KEY (0600, root-owned).
|
||||
# The worker never prints env values.
|
||||
EnvironmentFile=/etc/codex-app-server/env
|
||||
# Egress allowlist for host-level tasks: relay/git go through the same
|
||||
# Tinyproxy as container tasks (127.0.0.1 is allowed by the iptables
|
||||
# rules; without this, host tasks would bypass the allowlist).
|
||||
Environment=HTTP_PROXY=http://127.0.0.1:8888
|
||||
Environment=HTTPS_PROXY=http://127.0.0.1:8888
|
||||
Environment=http_proxy=http://127.0.0.1:8888
|
||||
Environment=https_proxy=http://127.0.0.1:8888
|
||||
Environment=NO_PROXY=localhost,127.0.0.1
|
||||
Environment=no_proxy=localhost,127.0.0.1
|
||||
# aa-exec confines the worker (and its children: host.py, app-server,
|
||||
# codex, bwrap, tools) under the codex-host AppArmor profile, which
|
||||
# allows userns+mount for bwrap. Without aa-exec, bwrap fails on
|
||||
# AppArmor userns/mount restrictions. --claim-executor-only is
|
||||
# REQUIRED: this worker must only take executor='local' tasks and
|
||||
# must never steal NULL-executor tasks meant for Docker workers.
|
||||
ExecStart=/usr/bin/aa-exec -p codex-host -- /usr/bin/python3 -m cloud.worker --interval 10 --config /opt/codex-app-server/host-config-host.json --executor local --claim-executor-only --worker-capacity 2 --loop --db /var/lib/codex-app-server/control.db --worker-id host-1 --repos-dir /var/lib/codex-app-server/repos
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
TimeoutStopSec=180
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user