Files
shadow/docker/Dockerfile.e2e
T
Pierre Warnier e29b06c461 e2e: add end-to-end deployment tests (#102)
Add automated deployment testing in Docker that simulates a real
system-wide installation: build from source, install replacing GNU
shadow-utils, then run 97 assertions covering:

- Symlink dispatch and multicall dispatch (all 14 tools)
- Setuid bits and non-root privilege enforcement
- Full user lifecycle (useradd → chpasswd → usermod → pwck → userdel)
- Full group lifecycle (groupadd → groupmod → groupdel → grpck)
- Individual tool tests (chage, chfn, chsh, passwd -l/-u)
- PAM authentication (su with known password via expect)
- nscd cache invalidation
- Landlock sandboxing (when kernel supports it)
- Ansible integration (user/group modules as real-world consumer)

New files:
- docker/Dockerfile.e2e — multi-stage build + debian:trixie runtime
- tests/e2e/deploy-test.sh — bash test harness with 97 assertions
- tests/e2e/ansible-test.yml — Ansible playbook integration test
- .dockerignore — prevent sending target/ and .git/ to Docker

Modified:
- docker-compose.yml — add e2e service (no changes to existing services)
- Cargo.toml — add pam feature forwarding to root package
- shadow-core/pam.rs — add #[link(name = "pam")] for linker

Closes #109, closes #110, closes #111, closes #112, closes #113
Refs #102
2026-04-03 13:22:55 +02:00

64 lines
1.9 KiB
Docker

# shadow-rs end-to-end deployment test image
#
# Simulates a real deployment: build from source, install system-wide
# (replacing GNU shadow-utils), then run ~100 assertions.
#
# Usage:
# docker compose build e2e
# docker compose run --rm e2e # run all tests
# docker compose run --rm e2e bash # debug interactively
# ── Stage 1: build shadow-rs ────────────────────────────────────────
FROM rust:latest AS builder
RUN apt-get update && apt-get install -y --no-install-recommends \
libpam0g-dev \
libselinux1-dev \
libaudit-dev \
pkg-config \
make \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
COPY . .
RUN cargo build --release --features pam \
&& make install DESTDIR=/install PREFIX=/usr
# ── Stage 2: runtime with tests ────────────────────────────────────
FROM debian:trixie
# Install GNU shadow-utils first — this creates /etc/pam.d/passwd,
# /etc/pam.d/su, and other PAM configs we need. We overwrite the
# binaries below but keep the PAM configuration intact.
RUN apt-get update && apt-get install -y --no-install-recommends \
passwd \
login \
&& rm -rf /var/lib/apt/lists/*
# Overwrite GNU binaries with shadow-rs
COPY --from=builder /install/usr/sbin/ /usr/sbin/
# Setuid-root — chmod on symlink sets the bit on the target binary
RUN chmod 4755 /usr/sbin/shadow-rs
# Install test dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
expect \
nscd \
ansible-core \
python3-passlib \
procps \
openssl \
&& rm -rf /var/lib/apt/lists/*
# Create a non-root test runner using our own tools
RUN /usr/sbin/useradd -m -s /bin/bash testrunner
# Copy test scripts
COPY tests/e2e/ /tests/e2e/
RUN chmod +x /tests/e2e/deploy-test.sh
WORKDIR /tests/e2e
CMD ["./deploy-test.sh"]