CI smoke test does not exercise AWX's real invocation (ansible-runner worker as uid 1000) #3

Closed
opened 2026-09-19 12:23:55 +00:00 by daniel · 1 comment
Owner

Summary

The CI smoke test and tests/smoke-test.sh do not exercise the code path AWX actually uses, so failures like the world-writable warning (#1) or a broken non-root worker slip through CI.

What CI does today

.gitea/workflows/build.yml:63-72:

CID=$(docker create --user 0 "$IMAGE" ansible-runner run /runner -p playbook.yml)
docker cp tests/playbook.yml "$CID:/runner/project/playbook.yml"
docker start -a "$CID" || rc=$?

and tests/smoke-test.sh:25:

"$ENGINE" run --rm -v "$WORKDIR:/runner:Z" "$IMAGE" ansible-runner run /runner -p playbook.yml

What AWX actually does

awx/main/utils/execution_environments.py builds the job pod with:

containers[0].args = ['ansible-runner', 'worker', '--private-data-dir=/runner']

and the pod runs as the image's USER 1000 / gid 0, with no volumes. So the real invocation is ansible-runner worker, as uid 1000, against an in-image /runner (not a bind mount).

Why it matters

  • ansible-runner run as root cannot catch permission/ownership problems that only show up for uid 1000.
  • The worker subcommand is the one that sets up /runner/project and triggers the world-writable warning; run does not.
  • A bind mount (-v ...:Z) masks the image's own /runner permissions.

Suggested fix

Add a second check to CI/smoke test that mirrors AWX:

# as uid 1000 / gid 0, no bind mount
docker run --rm --user 1000:0 "$IMAGE" \
  ansible-runner worker --private-data-dir=/runner --worker-info

Plus an assertion that /runner and /runner/project are not world-writable, and a check that the worker starts as uid 1000 without errors.

Impact

Test gap only, but it hides the exact class of bug that motivated this file (a Debian EE that works locally but not in AWX).

## Summary The CI smoke test and `tests/smoke-test.sh` do not exercise the code path AWX actually uses, so failures like the world-writable warning (#1) or a broken non-root worker slip through CI. ## What CI does today `.gitea/workflows/build.yml:63-72`: ``` CID=$(docker create --user 0 "$IMAGE" ansible-runner run /runner -p playbook.yml) docker cp tests/playbook.yml "$CID:/runner/project/playbook.yml" docker start -a "$CID" || rc=$? ``` and `tests/smoke-test.sh:25`: ``` "$ENGINE" run --rm -v "$WORKDIR:/runner:Z" "$IMAGE" ansible-runner run /runner -p playbook.yml ``` ## What AWX actually does `awx/main/utils/execution_environments.py` builds the job pod with: ``` containers[0].args = ['ansible-runner', 'worker', '--private-data-dir=/runner'] ``` and the pod runs as the image's `USER 1000` / gid 0, with no volumes. So the real invocation is `ansible-runner worker`, as uid 1000, against an in-image `/runner` (not a bind mount). ## Why it matters - `ansible-runner run` as root cannot catch permission/ownership problems that only show up for uid 1000. - The `worker` subcommand is the one that sets up `/runner/project` and triggers the world-writable warning; `run` does not. - A bind mount (`-v ...:Z`) masks the image's own `/runner` permissions. ## Suggested fix Add a second check to CI/smoke test that mirrors AWX: ``` # as uid 1000 / gid 0, no bind mount docker run --rm --user 1000:0 "$IMAGE" \ ansible-runner worker --private-data-dir=/runner --worker-info ``` Plus an assertion that `/runner` and `/runner/project` are not world-writable, and a check that the worker starts as uid 1000 without errors. ## Impact Test gap only, but it hides the exact class of bug that motivated this file (a Debian EE that works locally but not in AWX).
Author
Owner

Moved to beads: work-po8

Moved to beads: `work-po8`
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
daniel/awx-debian-ee#3
No description provided.