Skip to content

Latest commit

 

History

History
194 lines (157 loc) · 7.15 KB

File metadata and controls

194 lines (157 loc) · 7.15 KB

RHEL: A Docker image used to build and test rippled

The code in this repository creates a locked-down Red Hat Enterprise Linux (RHEL) image for building and testing rippled in the GitHub CI pipelines.

Although the images will be built by a CI pipeline in this repository, if necessary a maintainer can build them manually by following the instructions below.

Building the Docker image

The same Dockerfile can be used to build an image for RHEL8, RHEL9, RHEL10 and future versions by specifying the RHEL_VERSION build argument. There is an additional argument to specify as well, namely GCC_VERSION for the GCC flavor; in the RHEL images we cannot choose the Clang version to install, so the Clang version is set to "any".

Both build images for gcc and clang support packaging.

Building the Docker image for GCC

In order to build the image for GCC, run the commands below from the root directory of the repository.

# The version of the distro to use.
RHEL_VERSION=9
# The version of GCC to use.
GCC_VERSION=12
# The versions of the tools to use.
CCACHE_VERSION=4.12.2
CMAKE_VERSION=4.2.1
CONAN_VERSION=2.24.0
GCOVR_VERSION=8.3
MOLD_VERSION=2.40.4
RUST_VERSION=1.91.1
CONTAINER_IMAGE=ghcr.io/xrplf/ci/rhel-${RHEL_VERSION}:gcc-${GCC_VERSION}

docker buildx build . \
  --file docker/rhel/Dockerfile \
  --target gcc \
  --build-arg BUILDKIT_DOCKERFILE_CHECK=skip=InvalidDefaultArgInFrom \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  --build-arg RHEL_VERSION=${RHEL_VERSION} \
  --build-arg GCC_VERSION=${GCC_VERSION} \
  --build-arg CCACHE_VERSION=${CCACHE_VERSION} \
  --build-arg CMAKE_VERSION=${CMAKE_VERSION} \
  --build-arg CONAN_VERSION=${CONAN_VERSION} \
  --build-arg GCOVR_VERSION=${GCOVR_VERSION} \
  --build-arg MOLD_VERSION=${MOLD_VERSION} \
  --build-arg RUST_VERSION=${RUST_VERSION} \
  --tag ${CONTAINER_IMAGE}

Building the Docker image for Clang

In order to build the image for Clang, run the commands below from the root directory of the repository.

# The version of the distro to use.
RHEL_VERSION=10
# The versions of the tools to use.
CCACHE_VERSION=4.12.2
CMAKE_VERSION=4.2.1
CONAN_VERSION=2.24.0
GCOVR_VERSION=8.3
MOLD_VERSION=2.40.4
RUST_VERSION=1.91.1
CONTAINER_IMAGE=ghcr.io/xrplf/ci/rhel-${RHEL_VERSION}:clang-any

docker buildx build . \
  --file docker/rhel/Dockerfile \
  --target clang \
  --build-arg BUILDKIT_DOCKERFILE_CHECK=skip=InvalidDefaultArgInFrom \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  --build-arg RHEL_VERSION=${RHEL_VERSION} \
  --build-arg CCACHE_VERSION=${CCACHE_VERSION} \
  --build-arg CMAKE_VERSION=${CMAKE_VERSION} \
  --build-arg CONAN_VERSION=${CONAN_VERSION} \
  --build-arg GCOVR_VERSION=${GCOVR_VERSION} \
  --build-arg MOLD_VERSION=${MOLD_VERSION} \
  --build-arg RUST_VERSION=${RUST_VERSION} \
  --tag ${CONTAINER_IMAGE}

Running the Docker image

If you want to run the image locally using a cloned rippled repository, you can do so with the following command:

CODEBASE=<path to the rippled repository>
docker run --user $(id -u):$(id -g) --rm -it \
  --mount type=bind,source=${CODEBASE},target=/rippled \
  ${CONTAINER_IMAGE}

Note, the above command will assume the identity of the current user in the newly created Docker container. This might be exploited by other users with access to the same host (docker instance).

The recommended practice is to run Docker in rootless mode, or use alternative container runtime such as podman which support rootless environment. This will have similar effect as --user $(id -u):$(id -g) (making this option redundant and invalid), while also securing the container from other users on the same host.

If you see an error such as bash: /root/.bashrc: Permission denied and the prompt shows I have no name!, then exit the container and run it again without the --user $(id -u):$(id -g) option, or run it in rootless mode.

Caching Conan dependencies

You can further customize the docker run command by adding a volume mount for holding the Conan cache (the "p" directory), e.g.:

docker run --user $(id -u):$(id -g) --rm -it \
  --mount type=bind,source=${CODEBASE},target=/rippled \
  --mount type=volume,source=conan,target=/root/.conan2/p \
  ${CONTAINER_IMAGE}

This avoids the need to build the dependencies each time you run the image.

Building the binary

Once inside the container you can run the following commands to build rippled:

BUILD_TYPE=Debug
cd /rippled
# Remove any existing data from previous builds on the host machine.
rm -rf CMakeCache.txt CMakeFiles build || true
# Install dependencies via Conan.
conan remote add --force --index 0 xrplf https://conan.ripplex.io
conan install . --build missing --settings:all build_type=${BUILD_TYPE} \
  --options:host '&:tests=True' --options:host '&:xrpld=True'
# Configure the build with CMake.
cd build
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
      -DCMAKE_BUILD_TYPE=${BUILD_TYPE} ..
# Build and test rippled. Setting the parallelism too high, e.g. to $(nproc),
# can result in an error like "gmake[2]: ...... Killed".
PARALLELISM=2
cmake --build . -j ${PARALLELISM}
./rippled --unittest --unittest-jobs ${PARALLELISM}

Pushing the Docker image

Logging into the GitHub registry

To be able to push a Docker image to the GitHub registry, a personal access token is needed, see instructions here. In summary, if you do not have a suitable personal access token, generate one here.

GITHUB_USER=<your-github-username>
GITHUB_TOKEN=<your-github-personal-access-token>
echo ${GITHUB_TOKEN} | docker login ghcr.io -u "${GITHUB_USER}" --password-stdin

Pushing to the GitHub registry

To push the image to the GitHub registry, you can do so with the following command, whereby we append your username to not overwrite existing images:

docker tag ${CONTAINER_IMAGE} ${CONTAINER_IMAGE}-sha-${GITHUB_USER}
docker push ${CONTAINER_IMAGE}-sha-${GITHUB_USER}

This way you can test the image in the rippled repository by modifying the image_sha entry in .github/scripts/strategy-matrix/linux.json for the relevant configuration, and then creating a pull request.

Note, if you or the CI pipeline are pushing an image for the first time, it will be private by default. You will need to go to the packages page, select the relevant package, then "Package settings", and after clicking the "Change visibility" button make it "Public". In addition, on that same page, under "Manage Actions access" click the "Add repository" button, select the ci repository, and grant it "Admin" access.

Note on macOS

If you are using macOS and wish to push an image to the GitHub registry for use in GitHub Actions, you will need to append --platform linux/amd64 to the docker buildx build commands above.