diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json index 9b069f0ce3..0a935da8c8 100644 --- a/.github/scripts/strategy-matrix/linux.json +++ b/.github/scripts/strategy-matrix/linux.json @@ -74,7 +74,7 @@ "extra_cmake_args": "-Dvalidator_keys=ON", "package": { "type": "deb", - "image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10" + "image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-3a2d19f" } }, { @@ -86,7 +86,7 @@ "extra_cmake_args": "-Dvalidator_keys=ON -Dassert=ON", "package": { "type": "deb", - "image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10", + "image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-3a2d19f", "variant": "assert" } } @@ -101,7 +101,7 @@ "extra_cmake_args": "-Dvalidator_keys=ON", "package": { "type": "rpm", - "image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-49cdc10" + "image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-3a2d19f" } } ] diff --git a/.github/workflows/build-packaging-images.yml b/.github/workflows/build-packaging-images.yml index d3cbdd00f0..427d3b0fbf 100644 --- a/.github/workflows/build-packaging-images.yml +++ b/.github/workflows/build-packaging-images.yml @@ -7,12 +7,12 @@ on: paths: - ".github/workflows/build-packaging-images.yml" - "bin/install-packaging-tools.sh" - - "package/docker/**" + - "package/images/packaging/**" pull_request: paths: - ".github/workflows/build-packaging-images.yml" - "bin/install-packaging-tools.sh" - - "package/docker/**" + - "package/images/packaging/**" workflow_dispatch: concurrency: @@ -44,6 +44,6 @@ jobs: uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@696384b292577293292daed06af0306d1b83bd7d with: image_name: xrpld/packaging-${{ matrix.distro.name }} - dockerfile: package/docker/Dockerfile + dockerfile: package/images/packaging/Dockerfile base_image: ${{ matrix.distro.base_image }} push: ${{ github.event_name == 'push' }} diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml index be079855e4..1c0871f877 100644 --- a/.github/workflows/on-tag.yml +++ b/.github/workflows/on-tag.yml @@ -51,3 +51,6 @@ jobs: remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }} signing_key: ${{ secrets.NEXUS_PACKAGES_PRIVATE_KEY }} dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }} + antithesis_docker_host: ${{ secrets.ANTITHESIS_DOCKER_HOST }} + antithesis_docker_path: ${{ secrets.ANTITHESIS_DOCKER_PATH }} + antithesis_docker_credentials: ${{ secrets.ANTITHESIS_DOCKER_CREDENTIALS }} diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml index bbc289c3dd..062f735d57 100644 --- a/.github/workflows/on-trigger.yml +++ b/.github/workflows/on-trigger.yml @@ -130,3 +130,6 @@ jobs: remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }} signing_key: ${{ secrets.NEXUS_PACKAGES_PRIVATE_KEY }} dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }} + antithesis_docker_host: ${{ secrets.ANTITHESIS_DOCKER_HOST }} + antithesis_docker_path: ${{ secrets.ANTITHESIS_DOCKER_PATH }} + antithesis_docker_credentials: ${{ secrets.ANTITHESIS_DOCKER_CREDENTIALS }} diff --git a/.github/workflows/reusable-package.yml b/.github/workflows/reusable-package.yml index 9dd18598b5..13181978d5 100644 --- a/.github/workflows/reusable-package.yml +++ b/.github/workflows/reusable-package.yml @@ -9,8 +9,9 @@ # never reaches Nexus # - 'publish' uploads with the image's publish_pkg.py, doing a --dry-run # unless 'publish: true' -# - 'docker' builds an Ubuntu image from the tested DEB, pushing it to Docker -# Hub only with 'publish: true' +# - 'docker' builds an Ubuntu image from the tested DEB, and one with the +# voidstar binary for Antithesis, pushing them to Docker Hub and to the +# Antithesis registry only with 'publish: true' # # Only linux/amd64 is supported; the runner is hardcoded in the jobs below. name: Package @@ -37,10 +38,19 @@ on: description: "The password or token for that Nexus account." required: false signing_key: - description: "Armoured PGP private key used to sign the RPMs. Required when publishing." + description: "Armoured PGP private key used to sign the RPMs." required: false dockerhub_token: - description: "A Docker Hub organization access token for xrplf, with push access to xrplf/xrpld. Required when publishing." + description: "A Docker Hub organization access token for xrplf, with push access to xrplf/xrpld." + required: false + antithesis_docker_host: + description: "The host of the Antithesis container registry, e.g. us-central1-docker.pkg.dev." + required: false + antithesis_docker_path: + description: "The repository path in that registry, the image name excluded." + required: false + antithesis_docker_credentials: + description: "The JSON key of a service account with push access to that repository." required: false defaults: @@ -247,13 +257,21 @@ jobs: docker: needs: [test-install-deb, test-install-rpm] - name: "docker${{ !inputs.publish && ' (dry run)' || '' }}" + strategy: + fail-fast: false + matrix: + target: [xrpld, voidstar] + name: "docker ${{ matrix.target }}${{ !inputs.publish && ' (dry run)' || '' }}" permissions: contents: read runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 15 env: - IMAGE: xrplf/xrpld:${{ github.ref_type == 'tag' && github.ref_name || 'develop' }} + CONTEXT: image-context + IMAGE: ${{ matrix.target == 'voidstar' && 'xrpld-voidstar' || 'xrplf/xrpld' }}:${{ github.ref_type == 'tag' && github.ref_name || 'develop' }} + # Docker Hub is public, so a private build never reaches it; + # the Antithesis registry is not. + PUSH: ${{ inputs.publish && (matrix.target == 'voidstar' || github.event.repository.visibility == 'public') }} steps: - name: Checkout repository @@ -266,13 +284,20 @@ jobs: merge-multiple: true path: ${{ env.PACKAGE_DIR }} + - name: Download voidstar binary + if: ${{ matrix.target == 'voidstar' }} + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: xrpld-ubuntu-clang-debug-amd64-voidstar + path: ${{ env.CONTEXT }} + - name: Build image env: - CONTEXT: image-context + TARGET: ${{ matrix.target }} run: | mkdir -p "${CONTEXT}" find "${PACKAGE_DIR}" -type f -name 'xrpld_[0-9]*.deb' -exec cp {} "${CONTEXT}/" \; - docker build --pull --file package/image/Dockerfile --tag "${IMAGE}" "${CONTEXT}" + docker build --pull --file package/images/xrpld/Dockerfile --target "${TARGET}" --tag "${IMAGE}" "${CONTEXT}" - name: Start the server run: | @@ -290,14 +315,25 @@ jobs: docker logs "${container}" exit 1 - # Docker Hub is public, so a private build never reaches it. - name: Log in to Docker Hub - if: ${{ inputs.publish && github.event.repository.visibility == 'public' }} + if: ${{ env.PUSH == 'true' && matrix.target == 'xrpld' }} uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: xrplf password: ${{ secrets.dockerhub_token }} + - name: Log in to the Antithesis registry + if: ${{ env.PUSH == 'true' && matrix.target == 'voidstar' }} + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: ${{ secrets.antithesis_docker_host }} + username: _json_key + password: ${{ secrets.antithesis_docker_credentials }} + - name: Push image - if: ${{ inputs.publish && github.event.repository.visibility == 'public' }} - run: docker push "${IMAGE}" + if: ${{ env.PUSH == 'true' }} + env: + REGISTRY: ${{ matrix.target == 'voidstar' && format('{0}/{1}/', secrets.antithesis_docker_host, secrets.antithesis_docker_path) || '' }} + run: | + docker tag "${IMAGE}" "${REGISTRY}${IMAGE}" + docker push "${REGISTRY}${IMAGE}" diff --git a/docs/Docker.md b/docs/Docker.md index f478bc985a..1057719307 100644 --- a/docs/Docker.md +++ b/docs/Docker.md @@ -4,7 +4,7 @@ the `xrpld` DEB package installed on Ubuntu 26.04, running as the `xrpld` user. Each release is tagged with its version, `xrplf/xrpld:`, and `xrplf/xrpld:develop` follows the `develop` branch. -See [`package/README.md`](../package/README.md#docker-image) for how it is built +See [`package/README.md`](../package/README.md#docker-images) for how it is built and tagged. ```bash diff --git a/package/README.md b/package/README.md index da55eb55fd..e0759d42c6 100644 --- a/package/README.md +++ b/package/README.md @@ -10,11 +10,12 @@ a build configured with `-Dvalidator_keys=ON`. package/ build_pkg.py Staging and build script (called by the CMake `package` target and CI) sign_rpm.py Signs the built RPMs (called by CI when publishing) - docker/ - Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install-packaging-tools.sh` - publish_pkg.py Uploads built packages to the XRPLF Nexus repositories (called by CI, and shipped in that image) - image/ - Dockerfile The xrpld Docker image, installing the built DEB on Ubuntu (see "Docker image") + images/ + packaging/ + Dockerfile Packaging image, built by `build-packaging-images.yml`; installs its tooling with `bin/install-packaging-tools.sh` + publish_pkg.py Uploads built packages to the XRPLF Nexus repositories (called by CI, and shipped in that image) + xrpld/ + Dockerfile The xrpld Docker images, installing the built DEB on Ubuntu (see "Docker images") rpm/ xrpld.spec RPM spec debian/ Debian control files (control.in, lintian-overrides.in, rules, copyright, docs, links, source/format). @@ -119,8 +120,8 @@ Caller workflows (`on-pr.yml`, `on-tag.yml`, `on-trigger.yml`) call in the container of every distro that format targets and running the binaries there, so one that cannot be installed never reaches Nexus. 3. `publish` uploads both artifacts, or lists what it would upload. -4. `docker` builds the [Docker image](#docker-image) from the tested DEB, and - pushes it when publishing. +4. `docker` builds the [Docker images](#docker-images) from the tested DEB, and + pushes them when publishing. The packaging script derives the package version from the downloaded binary's `xrpld --version` output; no CMake configure or build step is needed inside the @@ -271,14 +272,22 @@ Nexus owns the repository metadata; nothing here indexes anything. Worth knowing installs it at `/usr/local/bin/publish_pkg.py` for other XRPLF repositories that build their packages elsewhere. -## Docker image +## Docker images The `docker` job installs the tested `xrpld` DEB on `ubuntu:26.04` using -[`image/Dockerfile`](image/Dockerfile), checks that the server starts, and, -with `publish: true`, pushes it to `xrplf/xrpld` on Docker Hub using the -`DOCKERHUB_TOKEN` secret, an organization access token for `xrplf`. A tag's -image is tagged with the tag name, `xrplf/xrpld:`, and a develop image -as `xrplf/xrpld:develop`. Private builds are never pushed. +[`images/xrpld/Dockerfile`](images/xrpld/Dockerfile), once per target, and +checks that the server starts in each image. A tag's images are tagged with the +tag name, a develop image as `develop`. With `publish: true`: + +- `xrpld` is pushed to `xrplf/xrpld` on Docker Hub using the `DOCKERHUB_TOKEN` + secret, an organization access token for `xrplf`. Private builds are never + pushed there. +- `voidstar` replaces `/usr/bin/xrpld` with the binary of the `voidstar` build + config, adds `libvoidstar.so` and links the binary into `/symbols`, as + Antithesis expects. It is pushed as `xrpld-voidstar` to the Antithesis + registry, `${ANTITHESIS_DOCKER_HOST}/${ANTITHESIS_DOCKER_PATH}`, logging in + with the `ANTITHESIS_DOCKER_CREDENTIALS` service account key. The registry is + private, so private builds are pushed too. ## How `build_pkg.py` works diff --git a/package/docker/Dockerfile b/package/docker/Dockerfile deleted file mode 100644 index adf372b6fa..0000000000 --- a/package/docker/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -ARG BASE_IMAGE=debian:trixie - -FROM ${BASE_IMAGE} - -# Bind-mounted rather than copied in, so the installer never lands in a layer. -RUN --mount=type=bind,source=bin/install-packaging-tools.sh,target=/install-packaging-tools.sh \ - /install-packaging-tools.sh - -# See ../README.md, "Publishing from other repositories". -COPY package/docker/publish_pkg.py /usr/local/bin/publish_pkg.py diff --git a/package/image/Dockerfile b/package/image/Dockerfile deleted file mode 100644 index b00fcebfcf..0000000000 --- a/package/image/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM ubuntu:26.04 - -RUN --mount=type=bind,target=/tmp/package \ - apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends /tmp/package/*.deb \ - && rm -rf /var/lib/apt/lists/* \ - && ln -sf /dev/stdout /var/log/xrpld/debug.log - -USER xrpld -WORKDIR /var/lib/xrpld - -EXPOSE 2459 5005 6006 50051 - -ENTRYPOINT ["/usr/bin/xrpld"] -CMD ["--net", "--silent", "--conf", "/etc/xrpld/xrpld.cfg"] diff --git a/package/images/packaging/Dockerfile b/package/images/packaging/Dockerfile new file mode 100644 index 0000000000..7d33993db9 --- /dev/null +++ b/package/images/packaging/Dockerfile @@ -0,0 +1,9 @@ +ARG BASE_IMAGE=debian:trixie + +FROM ${BASE_IMAGE} + +RUN --mount=type=bind,source=bin/install-packaging-tools.sh,target=/install-packaging-tools.sh \ + /install-packaging-tools.sh + +# See package/README.md, "Publishing from other repositories". +COPY package/images/packaging/publish_pkg.py /usr/local/bin/publish_pkg.py diff --git a/package/docker/publish_pkg.py b/package/images/packaging/publish_pkg.py similarity index 100% rename from package/docker/publish_pkg.py rename to package/images/packaging/publish_pkg.py diff --git a/package/images/xrpld/Dockerfile b/package/images/xrpld/Dockerfile new file mode 100644 index 0000000000..1cce6d628e --- /dev/null +++ b/package/images/xrpld/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:26.04 AS xrpld + +RUN --mount=type=bind,target=/tmp/package \ + apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends /tmp/package/*.deb \ + && rm -rf /var/lib/apt/lists/* \ + && ln -sf /dev/stdout /var/log/xrpld/debug.log + +USER xrpld +WORKDIR /var/lib/xrpld + +EXPOSE 2459 5005 6006 50051 + +ENTRYPOINT ["/usr/bin/xrpld"] +CMD ["--net", "--silent", "--conf", "/etc/xrpld/xrpld.cfg"] + +# The same image with the Antithesis-instrumented binary, which loads +# libvoidstar.so; Antithesis reads the debug symbols from /symbols. +FROM xrpld AS voidstar + +USER root + +ADD --chmod=644 --checksum=sha256:d080cc85f1d8d96452bdaf0021a10fa3e4cc3c319840f1fadd2d33904e607095 \ + https://antithesis.com/assets/instrumentation/libvoidstar.so /usr/lib/libvoidstar.so + +RUN --mount=type=bind,source=xrpld,target=/tmp/xrpld \ + install -m 755 /tmp/xrpld /usr/bin/xrpld \ + && mkdir /symbols \ + && ln -s /usr/bin/xrpld /symbols/xrpld + +USER xrpld