Skip to content

Commit 7f992ed

Browse files
committed
Adapt docker to antithesis
1 parent 03c0a5f commit 7f992ed

6 files changed

Lines changed: 213 additions & 52 deletions

File tree

.github/regression.sh

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,25 @@ case "${CARDANO_CLI_REV:-}" in
115115
esac
116116

117117
# setup cardano-node binaries
118-
case "${NODE_REV:-}" in
119-
"" | "none" )
120-
NODE_REV=master
121-
;;
122-
esac
123-
# shellcheck disable=SC1091
124-
. .github/source_cardano_node.sh
125-
cardano_bins_build_all "$NODE_REV" "${CARDANO_CLI_REV:-}"
126-
PATH_PREPEND="$(cardano_bins_print_path_prepend "${CARDANO_CLI_REV:-}")${PATH_PREPEND}"
127-
export PATH_PREPEND
118+
if [ -n "${CARDANO_PREBUILT_DIR:-}" ]; then
119+
# Pre-built binaries were baked into the image (e.g. for Antithesis).
120+
# Skip all nix builds and point PATH_PREPEND at the pre-built directories.
121+
_d="${CARDANO_PREBUILT_DIR}"
122+
PATH_PREPEND="${_d}/cardano-node/bin:${_d}/cardano-submit-api/bin:${_d}/cardano-cli/bin:${_d}/bech32/bin:${PATH_PREPEND}"
123+
export PATH_PREPEND
124+
unset _d
125+
else
126+
case "${NODE_REV:-}" in
127+
"" | "none" )
128+
NODE_REV=master
129+
;;
130+
esac
131+
# shellcheck disable=SC1091
132+
. .github/source_cardano_node.sh
133+
cardano_bins_build_all "$NODE_REV" "${CARDANO_CLI_REV:-}"
134+
PATH_PREPEND="$(cardano_bins_print_path_prepend "${CARDANO_CLI_REV:-}")${PATH_PREPEND}"
135+
export PATH_PREPEND
136+
fi
128137

129138
# optimize nix store if running in GitHub Actions
130139
if [ -n "${GITHUB_ACTIONS:-}" ]; then
@@ -254,7 +263,14 @@ nix develop --accept-flake-config .#testenv --command bash -c '
254263

255264
echo "::group::Python venv setup"
256265
printf "start: %(%H:%M:%S)T\n" -1
257-
. .github/setup_venv.sh clean
266+
# When _VENV_DIR points to a pre-built venv (e.g. baked into the image for
267+
# Antithesis), skip the `clean` flag so the existing venv is reused as-is
268+
# without re-downloading packages.
269+
if [ -n "${_VENV_DIR:-}" ] && [ -e "${_VENV_DIR}" ]; then
270+
. .github/setup_venv.sh
271+
else
272+
. .github/setup_venv.sh clean
273+
fi
258274
echo "::endgroup::" # end group for "Python venv setup"
259275

260276
echo "::group::🧪 Testrun"

docker/Dockerfile

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,75 @@
1-
# Dockerfile for cardano-node-tests (Antithesis/Moog driver image)
1+
# Dockerfile for cardano-node-tests (Antithesis-compatible driver image)
22
#
3-
# Minimal image: nix is configured and the repo is copied in.
4-
# All heavy setup (cardano binaries, Python venv) happens at runtime
5-
# via regression.sh, which manages its own nix environment through its shebang.
3+
# All heavy dependencies are baked in at image build time so the container
4+
# runs without any network access (required by Antithesis environments).
65
#
7-
# Build and push to GHCR before submitting to Moog:
8-
# docker build -f docker/Dockerfile -t ghcr.io/intersectmbo/cardano-node-tests-antithesis:latest .
6+
# Build args:
7+
# GIT_REVISION — git commit hash stored as $GIT_REVISION in the image
8+
# NODE_REV — cardano-node git ref to pre-build (default: master)
9+
#
10+
# Build and push to GHCR before submitting to Antithesis:
11+
# docker build -f docker/Dockerfile \
12+
# --build-arg GIT_REVISION=$(git rev-parse HEAD) \
13+
# --build-arg NODE_REV=master \
14+
# -t ghcr.io/intersectmbo/cardano-node-tests-antithesis:latest .
915
# docker push ghcr.io/intersectmbo/cardano-node-tests-antithesis:latest
1016

1117
FROM nixos/nix:2.25.5
1218

1319
ARG GIT_REVISION
20+
ARG NODE_REV=master
21+
1422
ENV GIT_REVISION=${GIT_REVISION}
23+
# Store the baked-in node revision for reference at runtime.
24+
ENV BAKED_NODE_REV=${NODE_REV}
1525

26+
# Configure Nix with IOG binary cache and required experimental features.
1627
RUN mkdir -p /etc/nix && \
17-
echo "extra-substituters = https://cache.iog.io" >> /etc/nix/nix.conf && \
18-
echo "extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" >> /etc/nix/nix.conf && \
19-
echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf && \
20-
echo "accept-flake-config = true" >> /etc/nix/nix.conf
28+
printf 'extra-substituters = https://cache.iog.io\n\
29+
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=\n\
30+
experimental-features = nix-command flakes\n\
31+
accept-flake-config = true\n' >> /etc/nix/nix.conf
2132

2233
WORKDIR /work
2334
COPY . /work/
35+
36+
# Pre-build cardano-node, cardano-submit-api, cardano-cli, and bech32 into /opt/cardano/.
37+
# NODE_REV is fixed at image build time — no network access is needed at runtime.
38+
RUN mkdir -p /opt/cardano && \
39+
nix build \
40+
--accept-flake-config --no-write-lock-file \
41+
"github://github.com/IntersectMBO/cardano-node?ref=${NODE_REV}#cardano-node" \
42+
-o /opt/cardano/cardano-node && \
43+
nix build \
44+
--accept-flake-config --no-write-lock-file \
45+
"github://github.com/IntersectMBO/cardano-node?ref=${NODE_REV}#cardano-submit-api" \
46+
-o /opt/cardano/cardano-submit-api && \
47+
nix build \
48+
--accept-flake-config --no-write-lock-file \
49+
"github://github.com/IntersectMBO/cardano-node?ref=${NODE_REV}#cardano-cli" \
50+
-o /opt/cardano/cardano-cli && \
51+
nix build \
52+
--accept-flake-config --no-write-lock-file \
53+
"github://github.com/IntersectMBO/cardano-node?ref=${NODE_REV}#bech32" \
54+
-o /opt/cardano/bech32
55+
56+
# Pre-warm the testenv dev shell (pulls nixpkgs, postgres, uv, python313 into the
57+
# nix store) and create the Python venv at /opt/tests-venv with all project
58+
# dependencies installed. This is the same step regression.sh does at runtime
59+
# but done here so no pip/uv network calls are needed in the Antithesis env.
60+
RUN nix develop --accept-flake-config .#testenv --command \
61+
bash -c 'python3 -m venv /opt/tests-venv --prompt tests-venv && \
62+
. /opt/tests-venv/bin/activate && \
63+
cd /work && \
64+
uv sync --active --no-dev'
65+
66+
# Pre-warm the base dev shell (bash, coreutils, git, jq, …) so its store
67+
# paths are cached and the regression.sh shebang resolves offline.
68+
RUN nix develop --accept-flake-config .#base --command true
69+
70+
# Create the Antithesis test driver directory and install the entry-point.
71+
# singleton_driver_* files are run once per test run by Antithesis.
72+
RUN mkdir -p /opt/antithesis/test/v1/quickstart && \
73+
cp /work/docker/antithesis_run.sh \
74+
/opt/antithesis/test/v1/quickstart/singleton_driver_regression.sh && \
75+
chmod +x /opt/antithesis/test/v1/quickstart/singleton_driver_regression.sh

docker/Dockerfile.config

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Config image for Antithesis.
2+
#
3+
# Contains only the docker-compose.yaml that tells Antithesis how to run
4+
# the services. Must be pushed to the Antithesis registry alongside the
5+
# driver image.
6+
#
7+
# Build:
8+
# docker build -f docker/Dockerfile.config \
9+
# -t us-central1-docker.pkg.dev/<tenant>/antithesis/config:latest .
10+
# docker push us-central1-docker.pkg.dev/<tenant>/antithesis/config:latest
11+
12+
FROM scratch
13+
COPY docker/docker-compose.yaml /docker-compose.yaml

docker/README.md

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,81 @@
1-
# Docker setup for cardano-node-tests (Antithesis/Moog)
1+
# Docker setup for cardano-node-tests (Antithesis)
22

3-
This directory contains the driver image and compose file for submitting
4-
`cardano-node-tests` to Antithesis via the Moog platform.
3+
This directory contains the driver image and compose files for submitting
4+
`cardano-node-tests` to Antithesis.
55

66
## How it works
77

8-
- `Dockerfile` — minimal image: configures Nix and copies the repo into
9-
`/work/`. No binaries are pre-built; `regression.sh` handles all setup at
10-
runtime via its own Nix shebang. Requires `GIT_REVISION` build arg (the
11-
current commit hash) so pytest can identify the revision without a `.git`
12-
directory inside the image.
13-
- `docker-compose.yaml` — single `driver` service for Moog submission.
8+
Antithesis environments have **no internet access** at runtime, so all
9+
dependencies are baked into the image at build time:
10+
11+
- `Dockerfile` — builds the driver image. At build time it:
12+
1. Pre-builds `cardano-node`, `cardano-submit-api`, `cardano-cli`, and
13+
`bech32` from `NODE_REV` into `/opt/cardano/` via `nix build`.
14+
2. Pre-warms the `testenv` dev shell and creates the Python venv at
15+
`/opt/tests-venv/` with all project dependencies installed.
16+
3. Pre-warms the `base` dev shell so the `regression.sh` shebang resolves
17+
from the local nix store without network access.
18+
4. Installs `antithesis_run.sh` as the Antithesis test driver at
19+
`/opt/antithesis/test/v1/quickstart/singleton_driver_regression.sh`.
20+
21+
- `antithesis_run.sh` — container entrypoint that:
22+
1. Forces nix into offline mode (`offline = true`).
23+
2. Exports `CARDANO_PREBUILT_DIR=/opt/cardano` and `_VENV_DIR=/opt/tests-venv`
24+
so `regression.sh` skips all downloads and uses the pre-built artefacts.
25+
3. Emits the Antithesis `setup_complete` lifecycle signal.
26+
4. Hands off to `.github/regression.sh`.
27+
28+
- `Dockerfile.config` — builds the Antithesis config image (`FROM scratch`)
29+
containing only `docker-compose.yaml`.
30+
31+
- `docker-compose.yaml` — single `driver` service.
1432

1533
## Workflow
1634

17-
### 1. Build and push the image
35+
### 1. Build and push the driver image
1836

1937
```bash
2038
docker build -f docker/Dockerfile \
2139
--build-arg GIT_REVISION=$(git rev-parse HEAD) \
40+
--build-arg NODE_REV=master \
2241
-t ghcr.io/intersectmbo/cardano-node-tests-antithesis:latest .
2342

2443
docker push ghcr.io/intersectmbo/cardano-node-tests-antithesis:latest
2544
```
2645

27-
### 2. Validate the compose locally
46+
`NODE_REV` is locked at build time — the same binaries are used every run
47+
regardless of what is on the `master` branch when the container starts.
48+
49+
### 2. Build and push the config image
50+
51+
```bash
52+
docker build -f docker/Dockerfile.config \
53+
-t us-central1-docker.pkg.dev/<tenant>/antithesis/config:latest .
54+
55+
docker push us-central1-docker.pkg.dev/<tenant>/antithesis/config:latest
56+
```
57+
58+
### 3. Validate locally (internet-connected build, isolated network at runtime)
2859

2960
```bash
3061
docker compose -f docker/docker-compose.yaml config
3162
docker compose -f docker/docker-compose.yaml up --build
3263
```
3364

34-
### 3. Submit to Moog
65+
To fully simulate the Antithesis no-internet constraint, run inside an
66+
isolated network namespace on Linux:
3567

3668
```bash
37-
moog requester create-test \
38-
--platform github \
39-
--username saratomaz \
40-
--repository IntersectMBO/cardano-node-tests \
41-
--directory ./docker \
42-
--commit $(git rev-parse HEAD) \
43-
--try 1 \
44-
--duration 2
69+
unshare -n docker compose -f docker/docker-compose.yaml up
4570
```
4671

4772
## Environment variables
4873

74+
`NODE_REV` is baked into the image at build time and must **not** be set at
75+
runtime. All other variables are passed through docker-compose as before.
76+
4977
| Variable | Default | Description |
5078
|-------------------|------------|------------------------------------------|
51-
| `NODE_REV` | `master` | cardano-node git revision |
5279
| `CARDANO_CLI_REV` | (built-in) | cardano-cli revision, empty = use node's |
5380
| `DBSYNC_REV` | (disabled) | db-sync revision, empty = disabled |
5481
| `RUN_TARGET` | `tests` | `tests`, `testpr`, or `testnets` |

docker/antithesis_run.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bash
2+
# Antithesis entrypoint for cardano-node-tests.
3+
#
4+
# Runs the full test suite without any network access by:
5+
# 1. Forcing nix into offline mode (all store paths were pre-built into
6+
# the image by docker/Dockerfile).
7+
# 2. Pointing regression.sh at the pre-built cardano binaries and Python
8+
# venv so it skips all download / build steps.
9+
# 3. Emitting the Antithesis `setup_complete` lifecycle signal before
10+
# starting pytest.
11+
#
12+
# This file is installed at:
13+
# /opt/antithesis/test/v1/quickstart/singleton_driver_regression.sh
14+
# and is also usable directly as the docker-compose `command`.
15+
16+
set -Eeuo pipefail
17+
18+
# ---------------------------------------------------------------------------
19+
# 1. Force nix offline — all required store paths were pre-built into the
20+
# image. This prevents nix from attempting any network calls at runtime,
21+
# which would fail inside the Antithesis environment.
22+
# ---------------------------------------------------------------------------
23+
echo "offline = true" >> /etc/nix/nix.conf
24+
25+
# ---------------------------------------------------------------------------
26+
# 2. Tell regression.sh to use the pre-built binaries and Python venv that
27+
# were baked into the image at docker build time.
28+
# ---------------------------------------------------------------------------
29+
export CARDANO_PREBUILT_DIR=/opt/cardano
30+
export _VENV_DIR=/opt/tests-venv
31+
32+
# ---------------------------------------------------------------------------
33+
# 3. Emit the Antithesis setup_complete signal.
34+
# Written as JSONL to $ANTITHESIS_OUTPUT_DIR/sdk.jsonl.
35+
# Antithesis begins fault injection / test orchestration after receiving
36+
# this message.
37+
# ---------------------------------------------------------------------------
38+
_output_dir="${ANTITHESIS_OUTPUT_DIR:-/tmp/antithesis}"
39+
mkdir -p "$_output_dir"
40+
printf '{"antithesis_setup": {"status": "complete", "details": {"info": ["cardano-node-tests driver ready, node_rev=%s"]}}}\n' \
41+
"${BAKED_NODE_REV:-unknown}" >> "$_output_dir/sdk.jsonl"
42+
unset _output_dir
43+
44+
# ---------------------------------------------------------------------------
45+
# 4. Hand off to regression.sh. The shebang in that script will invoke
46+
# `nix develop .#base` which now resolves entirely from the local nix
47+
# store (offline = true).
48+
# ---------------------------------------------------------------------------
49+
exec /work/.github/regression.sh

docker/docker-compose.yaml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
# Docker Compose for Antithesis/Moog test submission.
1+
# Docker Compose for Antithesis test submission.
22
#
3-
# Submit to Moog:
4-
# moog requester create-test \
5-
# --platform github --username <you> \
6-
# --repository IntersectMBO/cardano-node-tests \
7-
# --directory ./docker \
8-
# --commit <hash> --try 1 --duration 2
3+
# The driver image must be pre-built with all cardano binaries and the Python
4+
# venv baked in (see docker/Dockerfile). No internet access is available at
5+
# runtime inside the Antithesis environment.
96
#
10-
# Validate locally before submitting:
7+
# Push images to the Antithesis registry before submitting:
8+
# docker push us-central1-docker.pkg.dev/<tenant>/antithesis/cardano-node-tests:latest
9+
# docker push us-central1-docker.pkg.dev/<tenant>/antithesis/config:latest
10+
#
11+
# Validate locally (requires internet — use an isolated netns to simulate
12+
# the Antithesis environment):
1113
# docker compose -f docker/docker-compose.yaml config
1214
# docker compose -f docker/docker-compose.yaml up --build
1315

@@ -17,9 +19,11 @@ services:
1719
build:
1820
context: ..
1921
dockerfile: docker/Dockerfile
20-
command: ["/work/.github/regression.sh"]
22+
# antithesis_run.sh sets nix offline, exports pre-built paths, emits
23+
# setup_complete, then hands off to regression.sh.
24+
command: ["/work/docker/antithesis_run.sh"]
2125
environment:
22-
- NODE_REV=${NODE_REV:-master}
26+
# NODE_REV is baked into the image at build time; do not override here.
2327
- CARDANO_CLI_REV=${CARDANO_CLI_REV:-}
2428
- DBSYNC_REV=${DBSYNC_REV:-}
2529
- RUN_TARGET=${RUN_TARGET:-tests}

0 commit comments

Comments
 (0)