diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0109963cc6b335f38f3d4c63bed4f7b889ec85ea..29b0595736e9d7edb79b337bfad7fe90b7f9d1d7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -282,6 +282,16 @@ base: --platform ${PLATFORM} --build-arg BASE_IMAGE=${BASE_IMAGE} --build-arg BUILD_IMAGE=${BUILD_IMAGE} + --build-arg SPACK_ORGREPO=${SPACK_ORGREPO} + --build-arg SPACK_VERSION=${SPACK_VERSION} + --build-arg SPACK_CHERRYPICKS="${SPACK_CHERRYPICKS}" + --build-arg SPACK_CHERRYPICKS_FILES="${SPACK_CHERRYPICKS_FILES}" + --build-arg KEY4HEPSPACK_ORGREPO=${KEY4HEPSPACK_ORGREPO} + --build-arg KEY4HEPSPACK_VERSION=${KEY4HEPSPACK_VERSION} + --build-arg EICSPACK_ORGREPO=${EICSPACK_ORGREPO} + --build-arg EICSPACK_VERSION=${EICSPACK_VERSION} + --build-arg S3_ACCESS_KEY=${S3_ACCESS_KEY} + --build-arg S3_SECRET_KEY=${S3_SECRET_KEY} --provenance false containers/debian 2>&1 | tee build.log @@ -417,16 +427,6 @@ eic: --build-arg BUILDER_IMAGE=${BUILDER_IMAGE} --build-arg RUNTIME_IMAGE=${RUNTIME_IMAGE} --build-arg INTERNAL_TAG=${INTERNAL_TAG} - --build-arg SPACK_ORGREPO=${SPACK_ORGREPO} - --build-arg SPACK_VERSION=${SPACK_VERSION} - --build-arg SPACK_CHERRYPICKS="${SPACK_CHERRYPICKS}" - --build-arg SPACK_CHERRYPICKS_FILES="${SPACK_CHERRYPICKS_FILES}" - --build-arg KEY4HEPSPACK_ORGREPO=${KEY4HEPSPACK_ORGREPO} - --build-arg KEY4HEPSPACK_VERSION=${KEY4HEPSPACK_VERSION} - --build-arg EICSPACK_ORGREPO=${EICSPACK_ORGREPO} - --build-arg EICSPACK_VERSION=${EICSPACK_VERSION} - --build-arg S3_ACCESS_KEY=${S3_ACCESS_KEY} - --build-arg S3_SECRET_KEY=${S3_SECRET_KEY} --build-arg JUG_VERSION=${EXPORT_TAG}-${BUILD_TYPE}-$(git rev-parse HEAD) ${IF_BUILD_DEFAULT+ ${EDM4EIC_VERSION:+--build-arg EDM4EIC_VERSION=${EDM4EIC_VERSION}} diff --git a/containers/debian/base.Dockerfile b/containers/debian/base.Dockerfile index 72daa2408daa00fd166e483cffe620c099b93f0f..b4ee8aaefbc5d7b0b781414c9f5ca17c6da51558 100644 --- a/containers/debian/base.Dockerfile +++ b/containers/debian/base.Dockerfile @@ -125,3 +125,118 @@ update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100 gcc --version clang --version EOF + +## Install some extra spack dependencies +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${TARGETPLATFORM} \ + --mount=type=cache,target=/var/lib/apt/lists,sharing=locked,id=${TARGETPLATFORM} <<EOF +rm -f /etc/apt/apt.conf.d/docker-clean +apt-get -yqq update +apt-get -yqq install --no-install-recommends \ + jq \ + python3 \ + python3-dev \ + python3-distutils \ + python3-boto3 \ + python-is-python3 +EOF + +## Setup spack +ENV SPACK_ROOT=/opt/spack +ARG SPACK_ORGREPO="spack/spack" +ARG SPACK_VERSION="releases/v0.20" +ENV SPACK_PYTHON=/usr/bin/python3 +ARG SPACK_CHERRYPICKS="" +ARG SPACK_CHERRYPICKS_FILES="" +ADD https://api.github.com/repos/${SPACK_ORGREPO}/commits/${SPACK_VERSION} /tmp/spack.json +RUN <<EOF +git config --global user.email "gitlab@eicweb.phy.anl.gov" +git config --global user.name "EIC Container Build Service" +git config --global advice.detachedHead false +git clone --filter=tree:0 https://github.com/${SPACK_ORGREPO}.git ${SPACK_ROOT} +git -C ${SPACK_ROOT} checkout ${SPACK_VERSION} +if [ -n "${SPACK_CHERRYPICKS}" ] ; then + SPACK_CHERRYPICKS=$(git -C ${SPACK_ROOT} rev-list --topo-order ${SPACK_CHERRYPICKS} | grep -m $(echo ${SPACK_CHERRYPICKS} | wc -w) "${SPACK_CHERRYPICKS}" | tac) + eval "declare -A SPACK_CHERRYPICKS_FILES_ARRAY=(${SPACK_CHERRYPICKS_FILES})" + for hash in ${SPACK_CHERRYPICKS} ; do + if [ -n "${SPACK_CHERRYPICKS_FILES_ARRAY[${hash}]+found}" ] ; then + git -C ${SPACK_ROOT} show ${hash} -- ${SPACK_CHERRYPICKS_FILES_ARRAY[${hash}]//,/ } | patch -p1 -d ${SPACK_ROOT} + git -C ${SPACK_ROOT} commit --all --message "$(git -C ${SPACK_ROOT} show --no-patch --pretty=format:%s ${hash})" + else + git -C ${SPACK_ROOT} cherry-pick ${hash} + fi + done +fi +git -C $SPACK_ROOT gc --prune=all --aggressive +sed -i 's/timeout=60/timeout=None/' $SPACK_ROOT/lib/spack/spack/stage.py +ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/docker-shell +ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/interactive-shell +ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/spack-env +EOF + +## Use spack entrypoint. NOTE: Requires `set -ex` in all multi-line scripts! +SHELL ["docker-shell"] + +## Setup build configuration +ARG jobs=1 +RUN <<EOF +set -e +declare -A target=(["linux/amd64"]="x86_64_v2" ["linux/arm64"]="aarch64") +target=${target[${TARGETPLATFORM}]} +spack config --scope site add "packages:all:require:[target=${target}]" +spack config --scope site add "packages:all:target:[${target}]" +spack external find --not-buildable --scope site --path /usr/local/cuda/bin cuda +spack external find --not-buildable --scope site llvm +spack config blame packages +spack config --scope user add "config:suppress_gpg_warnings:true" +spack config --scope user add "config:build_jobs:${jobs}" +spack config --scope user add "config:db_lock_timeout:${jobs}00" +spack config --scope user add "config:source_cache:/var/cache/spack" +spack config --scope user add "config:install_tree:root:/opt/software" +spack config --scope user add "config:ccache:true" +spack config blame config +spack compiler find --scope site +spack config blame compilers +EOF + +## Setup buildcache mirrors +## - this always adds the read-only mirror to the container +## - the write-enabled mirror is provided later as a secret mount +ARG S3_ACCESS_KEY="" +ARG S3_SECRET_KEY="" +RUN --mount=type=cache,target=/var/cache/spack <<EOF +set -e +if [ -n "${S3_ACCESS_KEY}" ] ; then + spack mirror add --scope site --unsigned \ + --s3-endpoint-url https://eics3.sdcc.bnl.gov:9000 \ + --s3-access-key-id "${S3_ACCESS_KEY}" \ + --s3-access-key-secret "${S3_SECRET_KEY}" \ + eics3 s3://eictest/EPIC/spack/${SPACK_VERSION} +fi +spack mirror add --scope site --signed spack-${SPACK_VERSION} https://binaries.spack.io/${SPACK_VERSION} +spack mirror add --scope site --unsigned ghcr-${SPACK_VERSION} oci://ghcr.io/eic/spack-${SPACK_VERSION} +spack mirror list +EOF + +## Setup eic-spack +ENV EICSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/eic-spack +ARG EICSPACK_ORGREPO="eic/eic-spack" +ARG EICSPACK_VERSION="$SPACK_VERSION" +ADD https://api.github.com/repos/${EICSPACK_ORGREPO}/commits/${EICSPACK_VERSION} /tmp/eic-spack.json +RUN <<EOF +set -e +git clone --filter=tree:0 https://github.com/${EICSPACK_ORGREPO}.git ${EICSPACK_ROOT} +git -C ${EICSPACK_ROOT} checkout ${EICSPACK_VERSION} +spack repo add --scope site "${EICSPACK_ROOT}" +EOF + +## Setup key4hep-spack +ENV KEY4HEPSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/key4hep-spack +ARG KEY4HEPSPACK_ORGREPO="key4hep/key4hep-spack" +ARG KEY4HEPSPACK_VERSION="main" +ADD https://api.github.com/repos/${KEY4HEPSPACK_ORGREPO}/commits/${KEY4HEPSPACK_VERSION} /tmp/key4hep-spack.json +RUN <<EOF +set -e +git clone --filter=tree:0 https://github.com/${KEY4HEPSPACK_ORGREPO}.git ${KEY4HEPSPACK_ROOT} +git -C ${KEY4HEPSPACK_ROOT} checkout ${KEY4HEPSPACK_VERSION} +spack repo add --scope site "${KEY4HEPSPACK_ROOT}" +EOF diff --git a/containers/jug/dev.Dockerfile b/containers/jug/dev.Dockerfile index 1ba626777ea0c99e0de567423393416f8804c71d..6e226f91085222b6dbcaef94b0f6c75f78ee01c8 100644 --- a/containers/jug/dev.Dockerfile +++ b/containers/jug/dev.Dockerfile @@ -6,138 +6,16 @@ ARG RUNTIME_IMAGE="debian_stable_base" ARG INTERNAL_TAG="testing" ## ======================================================================================== -## STAGE 0: spack image -## EIC spack image with spack and eic-spack repositories +## STAGE 1: builder +## EIC builder image with spack environment ## ======================================================================================== -FROM ${DOCKER_REGISTRY}${BUILDER_IMAGE}:${INTERNAL_TAG} as spack +FROM ${DOCKER_REGISTRY}${BUILDER_IMAGE}:${INTERNAL_TAG} as builder ARG TARGETPLATFORM ## With heredocs for multi-line scripts, we want to fail on error and the print failing line. ## Ref: https://docs.docker.com/engine/reference/builder/#example-running-a-multi-line-script SHELL ["bash", "-ex", "-c"] -## install some extra spack dependencies -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${TARGETPLATFORM} \ - --mount=type=cache,target=/var/lib/apt/lists,sharing=locked,id=${TARGETPLATFORM} <<EOF -rm -f /etc/apt/apt.conf.d/docker-clean -apt-get -yqq update -apt-get -yqq install --no-install-recommends \ - jq \ - python3 \ - python3-dev \ - python3-distutils \ - python3-boto3 \ - python-is-python3 -EOF - -## Setup spack -ENV SPACK_ROOT=/opt/spack -ARG SPACK_ORGREPO="spack/spack" -ARG SPACK_VERSION="releases/v0.20" -ENV SPACK_PYTHON=/usr/bin/python3 -ARG SPACK_CHERRYPICKS="" -ARG SPACK_CHERRYPICKS_FILES="" -ADD https://api.github.com/repos/${SPACK_ORGREPO}/commits/${SPACK_VERSION} /tmp/spack.json -RUN <<EOF -git config --global user.email "gitlab@eicweb.phy.anl.gov" -git config --global user.name "EIC Container Build Service" -git config --global advice.detachedHead false -git clone --filter=tree:0 https://github.com/${SPACK_ORGREPO}.git ${SPACK_ROOT} -git -C ${SPACK_ROOT} checkout ${SPACK_VERSION} -if [ -n "${SPACK_CHERRYPICKS}" ] ; then - SPACK_CHERRYPICKS=$(git -C ${SPACK_ROOT} rev-list --topo-order ${SPACK_CHERRYPICKS} | grep -m $(echo ${SPACK_CHERRYPICKS} | wc -w) "${SPACK_CHERRYPICKS}" | tac) - eval "declare -A SPACK_CHERRYPICKS_FILES_ARRAY=(${SPACK_CHERRYPICKS_FILES})" - for hash in ${SPACK_CHERRYPICKS} ; do - if [ -n "${SPACK_CHERRYPICKS_FILES_ARRAY[${hash}]+found}" ] ; then - git -C ${SPACK_ROOT} show ${hash} -- ${SPACK_CHERRYPICKS_FILES_ARRAY[${hash}]//,/ } | patch -p1 -d ${SPACK_ROOT} - git -C ${SPACK_ROOT} commit --all --message "$(git -C ${SPACK_ROOT} show --no-patch --pretty=format:%s ${hash})" - else - git -C ${SPACK_ROOT} cherry-pick ${hash} - fi - done -fi -git -C $SPACK_ROOT gc --prune=all --aggressive -sed -i 's/timeout=60/timeout=None/' $SPACK_ROOT/lib/spack/spack/stage.py -ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/docker-shell -ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/interactive-shell -ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/spack-env -EOF - -## Use spack entrypoint. NOTE: Requires `set -ex` in all multi-line scripts! -SHELL ["docker-shell"] - -## Setup build configuration -ARG jobs=1 -RUN <<EOF -set -e -declare -A target=(["linux/amd64"]="x86_64_v2" ["linux/arm64"]="aarch64") -target=${target[${TARGETPLATFORM}]} -spack config --scope site add "packages:all:require:[target=${target}]" -spack config --scope site add "packages:all:target:[${target}]" -spack external find --not-buildable --scope site --path /usr/local/cuda/bin cuda -spack external find --not-buildable --scope site llvm -spack config blame packages -spack config --scope user add "config:suppress_gpg_warnings:true" -spack config --scope user add "config:build_jobs:${jobs}" -spack config --scope user add "config:db_lock_timeout:${jobs}00" -spack config --scope user add "config:source_cache:/var/cache/spack" -spack config --scope user add "config:install_tree:root:/opt/software" -spack config --scope user add "config:ccache:true" -spack config blame config -spack compiler find --scope site -spack config blame compilers -EOF - -## Setup buildcache mirrors -## - this always adds the read-only mirror to the container -## - the write-enabled mirror is provided later as a secret mount -ARG S3_ACCESS_KEY="" -ARG S3_SECRET_KEY="" -RUN --mount=type=cache,target=/var/cache/spack <<EOF -set -e -if [ -n "${S3_ACCESS_KEY}" ] ; then - spack mirror add --scope site --unsigned \ - --s3-endpoint-url https://eics3.sdcc.bnl.gov:9000 \ - --s3-access-key-id "${S3_ACCESS_KEY}" \ - --s3-access-key-secret "${S3_SECRET_KEY}" \ - eics3 s3://eictest/EPIC/spack/${SPACK_VERSION} -fi -spack mirror add --scope site --signed spack-${SPACK_VERSION} https://binaries.spack.io/${SPACK_VERSION} -spack mirror add --scope site --unsigned ghcr-${SPACK_VERSION} oci://ghcr.io/eic/spack-${SPACK_VERSION} -spack mirror list -EOF - -## Setup eic-spack -ENV EICSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/eic-spack -ARG EICSPACK_ORGREPO="eic/eic-spack" -ARG EICSPACK_VERSION="$SPACK_VERSION" -ADD https://api.github.com/repos/${EICSPACK_ORGREPO}/commits/${EICSPACK_VERSION} /tmp/eic-spack.json -RUN <<EOF -set -e -git clone --filter=tree:0 https://github.com/${EICSPACK_ORGREPO}.git ${EICSPACK_ROOT} -git -C ${EICSPACK_ROOT} checkout ${EICSPACK_VERSION} -spack repo add --scope site "${EICSPACK_ROOT}" -EOF - -## Setup key4hep-spack -ENV KEY4HEPSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/key4hep-spack -ARG KEY4HEPSPACK_ORGREPO="key4hep/key4hep-spack" -ARG KEY4HEPSPACK_VERSION="main" -ADD https://api.github.com/repos/${KEY4HEPSPACK_ORGREPO}/commits/${KEY4HEPSPACK_VERSION} /tmp/key4hep-spack.json -RUN <<EOF -set -e -git clone --filter=tree:0 https://github.com/${KEY4HEPSPACK_ORGREPO}.git ${KEY4HEPSPACK_ROOT} -git -C ${KEY4HEPSPACK_ROOT} checkout ${KEY4HEPSPACK_VERSION} -spack repo add --scope site "${KEY4HEPSPACK_ROOT}" -EOF - - -## ======================================================================================== -## STAGE 1: builder -## EIC builder image with spack environment -## ======================================================================================== -FROM spack as builder - ## 1. Setup our default environment (secret mount for write-enabled mirror) COPY --from=spack-environment . /opt/spack-environment/ ARG ENV=dev