Make toolkit in agent container customizable #4

Open
opened 2026-09-17 10:59:45 +00:00 by rs · 1 comment
Owner

Agents in the containers need applications to work effectively (for example golang tooling to work on golang prjects like gofmt). Make the spawn process of the container accept an ansible script to execute before it drops the root access and the agent user then can use the installed programs and configured environment.

Agents in the containers need applications to work effectively (for example golang tooling to work on golang prjects like gofmt). Make the spawn process of the container accept an ansible script to execute before it drops the root access and the agent user then can use the installed programs and configured environment.
Author
Owner

Implemented on main in b6a789b, released as v0.11.0.

harness spawn --setup <playbook.yml> now takes a local Ansible playbook and applies it inside the session container as root before the agent starts, so the agent user can use the installed programs and environment:

cat > tools.yml <<'EOF'
---
- hosts: localhost
  tasks:
    - name: install Go tooling
      apt:
        name: [golang-go, golang-golang-x-tools]
        state: present
        update_cache: true
EOF

harness spawn --repo https://git.pr0.tech/rs/myproject.git --setup tools.yml

How it works:

  • spawn reads/validates the playbook (non-empty, <=256 KiB) and sends it as setup in the create request.
  • the cluster (kube) backend renders it into a harness-<session>-setup ConfigMap, mounts it read-only at /etc/harness-setup/playbook.yml, and sets HARNESS_SETUP.
  • the agent image's new entrypoint (scripts/agent-entrypoint.sh) runs ansible-playbook -i localhost, -c local as root, then drops to the unprivileged agent user (uid 10001) via setpriv and execs harness agentd.
  • the harness-agent chart gained a setup value that renders the same ConfigMap/mount/env.

Security: a session with a setup playbook needs to start as root to install packages, so its pod uses a relaxed security context (no runAsNonRoot, no capability drop) for the setup step; the agent process itself still runs as uid 10001. Sessions without --setup keep the hardened non-root context. The local process backend has no container and rejects --setup rather than ignoring it. Playbooks are treated as code, not secrets.

Tests: kube setup ConfigMap/mount/env/security-context, controller rejection on the process backend, and --setup file reading; helm lint and template checks for both values. Docs: README "Custom session tooling", multi-agent, e2e.

Note: this changes Dockerfile.agent (adds ansible + util-linux and the entrypoint), so it needs the agent image rebuilt for the tag. Leaving open for verification.

Implemented on `main` in `b6a789b`, released as `v0.11.0`. `harness spawn --setup <playbook.yml>` now takes a local Ansible playbook and applies it inside the session container as root before the agent starts, so the agent user can use the installed programs and environment: ```sh cat > tools.yml <<'EOF' --- - hosts: localhost tasks: - name: install Go tooling apt: name: [golang-go, golang-golang-x-tools] state: present update_cache: true EOF harness spawn --repo https://git.pr0.tech/rs/myproject.git --setup tools.yml ``` **How it works:** - `spawn` reads/validates the playbook (non-empty, <=256 KiB) and sends it as `setup` in the create request. - the cluster (`kube`) backend renders it into a `harness-<session>-setup` ConfigMap, mounts it read-only at `/etc/harness-setup/playbook.yml`, and sets `HARNESS_SETUP`. - the agent image's new entrypoint (`scripts/agent-entrypoint.sh`) runs `ansible-playbook -i localhost, -c local` as root, then drops to the unprivileged agent user (uid 10001) via `setpriv` and execs `harness agentd`. - the `harness-agent` chart gained a `setup` value that renders the same ConfigMap/mount/env. **Security:** a session with a setup playbook needs to start as root to install packages, so its pod uses a relaxed security context (no `runAsNonRoot`, no capability drop) for the setup step; the agent process itself still runs as uid 10001. Sessions without `--setup` keep the hardened non-root context. The local process backend has no container and rejects `--setup` rather than ignoring it. Playbooks are treated as code, not secrets. **Tests:** kube setup ConfigMap/mount/env/security-context, controller rejection on the process backend, and `--setup` file reading; `helm lint` and template checks for both values. Docs: README "Custom session tooling", multi-agent, e2e. Note: this changes `Dockerfile.agent` (adds ansible + util-linux and the entrypoint), so it needs the agent image rebuilt for the tag. Leaving open for verification.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rs/harness#4
No description provided.