fix(opencode): resolve /usr/local/bin -> /usr/bin opencode path in pod

The npm prefix in the Dockerfile is /usr, so opencode installs to
/usr/bin/opencode (symlink to /usr/lib/node_modules/...), not
/usr/local/bin/opencode. The cluster E2E failed with ENOENT on
/usr/local/bin/opencode. Fix in three places:
- Dockerfile ENV PRAGENT_OPENCODE_BIN=/usr/bin/opencode
- ~/k8s/pragent-webhook.yaml env value
- _opencode_bin() now defensive: if the configured path is missing,
  falls back to shutil.which('opencode') before the linuxbrew last-resort.
- Dockerfile + README deploy notes: containerd import is sudoless via
  the group-readable raw socket (the microk8s ctr wrapper sudo-wraps).

Verified: rebuilt + reimported + rolled out; PR #5 (sha 985061c0) review
posted in-pod via the opencode engine (findings=2 inline=2 ok=True),
summary + 2 [CRITICAL] inline comments with suggestions + refs + sha marker.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Marcos
2026-08-17 23:31:53 +00:00
parent 8912f6721b
commit c7c6c3edd2
3 changed files with 15 additions and 7 deletions
+7 -4
View File
@@ -8,9 +8,12 @@
# #
# Build: # Build:
# docker build -t pragent-webhook:opencode -f pilot/Dockerfile . # docker build -t pragent-webhook:opencode -f pilot/Dockerfile .
# Import into microk8s (needs sudo for containerd): # Import into microk8s containerd (sudoless — the raw socket is group-readable
# docker save pragent-webhook:opencode | sudo microk8s ctr images import - # by the microk8s group; the `microk8s ctr` wrapper itself sudo-wraps, so use
# (or: sudo microk8s ctr images import pragent-webhook-opencode.tar) # the raw binary against the socket directly):
# docker save pragent-webhook:opencode | \
# /snap/microk8s/current/bin/ctr --address /var/snap/microk8s/common/run/containerd.sock \
# --namespace k8s.io image import -
# #
FROM python:3.12-slim FROM python:3.12-slim
@@ -42,7 +45,7 @@ WORKDIR /app
COPY . /app COPY . /app
ENV PRAGENT_FACTORY_DIR=/app \ ENV PRAGENT_FACTORY_DIR=/app \
PRAGENT_OPENCODE_BIN=/usr/local/bin/opencode \ PRAGENT_OPENCODE_BIN=/usr/bin/opencode \
PRAGENT_ENGINE=opencode \ PRAGENT_ENGINE=opencode \
OPENCODE_MODEL=headroom/glm-5.2:cloud \ OPENCODE_MODEL=headroom/glm-5.2:cloud \
OPENCODE_EXPERIMENTAL_LSP_TOOL=true \ OPENCODE_EXPERIMENTAL_LSP_TOOL=true \
+6 -2
View File
@@ -230,8 +230,12 @@ Build + deploy after editing the pilot scripts or the factory:
K="microk8s kubectl"; cd ~/Projects/pragent K="microk8s kubectl"; cd ~/Projects/pragent
# 1. build the image (docker is in the microk8s group, no sudo) # 1. build the image (docker is in the microk8s group, no sudo)
docker build -t pragent-webhook:opencode -f pilot/Dockerfile . docker build -t pragent-webhook:opencode -f pilot/Dockerfile .
# 2. import into microk8s containerd (needs sudo — one command) # 2. import into microk8s containerd — sudoless. the `microk8s ctr` wrapper
docker save pragent-webhook:opencode | sudo microk8s ctr images import - # sudo-wraps even in the microk8s group, so use the raw binary against the
# group-readable containerd socket directly:
docker save pragent-webhook:opencode | \
/snap/microk8s/current/bin/ctr --address /var/snap/microk8s/common/run/containerd.sock \
--namespace k8s.io image import -
# 3. apply + roll # 3. apply + roll
$K apply -f ~/k8s/pragent-webhook.yaml $K apply -f ~/k8s/pragent-webhook.yaml
$K -n pragent rollout restart deploy/pragent-webhook $K -n pragent rollout restart deploy/pragent-webhook
+2 -1
View File
@@ -56,11 +56,12 @@ def _factory_dir() -> str:
def _opencode_bin() -> str: def _opencode_bin() -> str:
b = os.environ.get("PRAGENT_OPENCODE_BIN") b = os.environ.get("PRAGENT_OPENCODE_BIN")
if b: if b and os.path.isfile(b):
return b return b
found = shutil.which("opencode") found = shutil.which("opencode")
if found: if found:
return found return found
# last resort: the known linuxbrew path on the dev host.
return "/home/linuxbrew/.linuxbrew/bin/opencode" return "/home/linuxbrew/.linuxbrew/bin/opencode"