diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..7ad07e60d491d315ad614e51fbf06258baaa03c0 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,251 @@ +stages: + - prepare + - frontend + - buildnode + + +variables: + GITLAB_BUILD_ENV_DOCKER_IMAGE: docker-registry.ebrains.eu/tc/ebrains-spack-build-env/gitlab_runners_nfs:gitlab_runners_nfs_23.06 + YASHCHIKI_HOME: ${CI_PROJECT_DIR}/.yashchiki + http_proxy: "http://proxy.kip.uni-heidelberg.de:8080" + https_proxy: "http://proxy.kip.uni-heidelberg.de:8080" + HTTP_PROXY: "http://proxy.kip.uni-heidelberg.de:8080" + HTTPS_PROXY: "http://proxy.kip.uni-heidelberg.de:8080" + ALL_PROXY: "http://proxy.kip.uni-heidelberg.de:8080" + SYSTEMNAME: "image_laptop" + SPACK_ENVIRONMENT_REPO: "${CI_PROJECT_DIR}/esd_spack/var/spack/repos/ebrains-spack-builds" + SPACK_ENVIRONMENT_PATH: "${CI_PROJECT_DIR}/esd_spack/var/spack/environments/default" + TMPDIR: "/tmp" + +# the image build tool needs Python `yaml` and `apptainer` — we build it via spack +buildenv: + stage: prepare + tags: + - esd_image + image: $GITLAB_BUILD_ENV_DOCKER_IMAGE + variables: + SPACK_DEV_ENV: ebrains-dev + script: + # FIXME: that's probably not what we want → we should always clone and install from buildcache! + - env + - date + - ls -lisa + - test -d esd_spack_buildenv || git clone -b eric_testing https://gitlab.ebrains.eu/ri/tech-hub/platform/esd/spack esd_spack_buildenv + - pushd esd_spack_buildenv; git fetch origin HEAD && git reset --hard FETCH_HEAD; popd + - test -d esd_spack_buildenv/var/spack/repos/ebrains-spack-builds || git clone -b image_build https://gitlab.ebrains.eu/ri/tech-hub/platform/esd/ebrains-spack-builds esd_spack_buildenv/var/spack/repos/ebrains-spack-builds + - pushd esd_spack_buildenv/var/spack/repos/ebrains-spack-builds; git fetch origin image_build && git reset --hard FETCH_HEAD; popd + - esd_spack_buildenv/bin/spack repo add --scope=site esd_spack_buildenv/var/spack/repos/ebrains-spack-builds || true + - . esd_spack_buildenv/share/spack/setup-env.sh + - spack compiler find --scope=site /usr/bin + - spack external find --scope=site python + - spack bootstrap root esd_spack_buildenv/opt/spack/bootstrap + - spack bootstrap now + - date + - (nohup spack install -j $(( ($(nproc) * 2 - 4) / 4 + 1)) py-pyyaml 2>&1 | sed -e "s:^:[py-pyyaml] :g") & + - (nohup spack install -j $(( ($(nproc) * 2 - 4) / 4 + 1)) rsync 2>&1 | sed -e "s:^:[rsync] :g") & + - (nohup spack install -j $(( ($(nproc) * 2 - 4) / 4 + 1)) proot 2>&1 | sed -e "s:^:[proot-0] :g") & + - (nohup spack install -j $(( ($(nproc) * 2 - 4) / 4 + 1)) proot 2>&1 | sed -e "s:^:[proot-1] :g") & + - wait + - date + - (nohup spack install -v -j $(( ($(nproc) * 2 - 2) / 2 + 1)) fakeroot 2>&1 | sed -e "s:^:[fakeroot-0] :g") & + - (nohup spack install -v -j $(( ($(nproc) * 2 - 2) / 2 + 1)) fakeroot 2>&1 | sed -e "s:^:[fakeroot-1] :g") & + - wait + - date + # some more parallelism for apptainer (and oversubscribe!) + - (nohup spack install -j $(( ($(nproc) * 2 - 3) / 3 + 1)) apptainer~suid 2>&1 | sed -e "s:^:[apptainer-0] :g") & + - (nohup spack install -j $(( ($(nproc) * 2 - 3) / 3 + 1)) apptainer~suid 2>&1 | sed -e "s:^:[apptainer-1] :g") & + - (nohup spack install -j $(( ($(nproc) * 2 - 3) / 3 + 1)) apptainer~suid 2>&1 | sed -e "s:^:[apptainer-2] :g") & + - wait + - date + - (nohup spack install -j $(( $(nproc) * 2 )) "skopeo@1.6:" 2>&1 | sed -e "s:^:[skopeo] :g") & + - wait + - date + - (nohup spack install -j $(( $(nproc) * 2 )) "oras" 2>&1 | sed -e "s:^:[oras] :g") & + - wait + - date + - (nohup spack install -j $(( $(nproc) * 2 )) "fakechroot" 2>&1 | sed -e "s:^:[fakechroot] :g") & + - wait + - date + - spack load "oras@1.1:" + cache: + key: buildenv-$CI_COMMIT_REF_SLUG + policy: pull-push + when: always + paths: + - esd_spack_buildenv/ + timeout: 2 days + + +# fetch all sources for later build stages on some internet-connected CI runner +fetch: + stage: frontend + dependencies: + - buildenv + tags: + - esd_image + image: $GITLAB_BUILD_ENV_DOCKER_IMAGE + variables: + SPACK_DEV_ENV: ebrains-dev + script: + - date + - ls -lisa + - . esd_spack_buildenv/share/spack/setup-env.sh + - spack load py-pyyaml rsync "oras@1.1:" proot + - rm -rf esd_spack + - test -d esd_spack || git clone -b eric_testing https://gitlab.ebrains.eu/ri/tech-hub/platform/esd/spack esd_spack + - pushd esd_spack; git fetch origin eric_testing && git reset --hard FETCH_HEAD; popd + - test -d esd_spack/var/spack/repos/ebrains-spack-builds || git clone -b image_build https://gitlab.ebrains.eu/ri/tech-hub/platform/esd/ebrains-spack-builds esd_spack/var/spack/repos/ebrains-spack-builds + - pushd esd_spack/var/spack/repos/ebrains-spack-builds; git fetch origin image_build && git reset --hard FETCH_HEAD; popd + - echo "repos:" > esd_spack/etc/spack/repos.yaml + - echo " - \$spack/var/spack/repos/ebrains-spack-builds" >> esd_spack/etc/spack/repos.yaml + - cat esd_spack/etc/spack/repos.yaml + - esd_spack/bin/spack repo list + - esd_spack/bin/spack repo list --scope=site + - proot -b share/yashchiki/styles/esd/fetch_os-release:/etc/os-release python3 bin/yashchiki --debug --stages fetch -- esd esd_spack esd_output + - date + cache: + - key: buildenv-$CI_COMMIT_REF_SLUG + policy: pull + paths: + - esd_spack_buildenv/ + - key: fetch-$CI_COMMIT_REF_SLUG + policy: pull-push + when: always + paths: + - esd_spack/ + - .yashchiki/download_cache + artifacts: + when: always + paths: + - errors_concretization.log + - ${YASHCHIKI_HOME}/sandboxes/esd/opt/spack_specs + - ${YASHCHIKI_HOME}/log + - /tmp/tmp.*/spec_*.yaml* + timeout: 2 days + + +# create the base image for the spack build +build-base-image: + stage: frontend + dependencies: + - buildenv + tags: + - esd_image + image: $GITLAB_BUILD_ENV_DOCKER_IMAGE + variables: + SPACK_DEV_ENV: ebrains-dev + script: + - date + - ls -lisa + - . esd_spack_buildenv/share/spack/setup-env.sh + - spack load py-pyyaml rsync apptainer~suid proot fakeroot "skopeo@1.6:" "oras@1.1:" + # * inspect underlying base image → determine identifier for specific version + - HASH_BASE_DISTRO=$(skopeo inspect docker://debian:bookworm | sha256sum) + # * hash build base image-related things (FIXME: this should be done differently ;)) + - HASH_BUILD_BASE_IMAGE=$(sha256sum lib/yashchiki/build_base_sandbox.sh) + - HASH_BUILD_BASE_IMAGE_CONTENT=$(sha256sum share/yashchiki/styles/esd/install_prerequisites.sh) + # * combine all hashes into one hash → use as lookup into gitlab package registry + - ESD_BASE_HASH=$(echo ${HASH_BASE_DISTRO}${HASH_BUILD_BASE_IMAGE}${HASH_BUILD_BASE_IMAGE_CONTENT} | sha256sum | cut -d\ -f 1) + - echo ${ESD_BASE_HASH} | tee esd_base_hash + # * try to download base build image, else build image and upload image into package registry + - set -x + - skopeo inspect docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_base_${ESD_BASE_HASH} && ret=$? || ret=$? + - date + - | + if [ "$ret" -ne 0 ]; then + python3 bin/yashchiki --stages build-base-image -- esd esd_spack esd_output; + date + skopeo copy --dest-username="$HARBOR_USERNAME" --dest-password="$HARBOR_PASSWORD" sif:esd_output_base docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_base_${ESD_BASE_HASH} || true + date + # replace symbolic tag + skopeo copy --dest-username="$HARBOR_USERNAME" --dest-password="$HARBOR_PASSWORD" docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_base_${ESD_BASE_HASH} docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_base || true + else + # needs to be an artifact => provide to build node via gitlab mechanisms + apptainer build esd_output_base docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_base_${ESD_BASE_HASH} + fi + - apptainer -d exec --fakeroot --no-pid esd_output_base bash -c "hostname" || true + - date + cache: + - key: buildenv-$CI_COMMIT_REF_SLUG + policy: pull + paths: + - esd_spack_buildenv/ + artifacts: + when: always + paths: + - ${YASHCHIKI_HOME}/log + - esd_base_hash + # requires for downstream job… + - esd_output_base + timeout: 2 days + + +# use the base image and build software in there using spack +buildnode-stuff: + stage: buildnode + dependencies: + - fetch + - build-base-image + tags: + - esd_image + image: $GITLAB_BUILD_ENV_DOCKER_IMAGE + variables: + SPACK_DEV_ENV: ebrains-dev + script: + - date + - du -sh esd_spack_buildenv/ + - date + - ls -lisa + - . esd_spack_buildenv/share/spack/setup-env.sh + - spack load py-pyyaml rsync apptainer~suid proot fakeroot fakechroot "skopeo@1.6:" "oras@1.1:" + - HASH_ESD_BASE_IMAGE=$(cat esd_base_hash) + - git config --global --add safe.directory $PWD + - HASH_ESD_CONFIG=$(git ls-files -s share/yashchiki/styles/esd | git hash-object --stdin) + - HASH_ESD_SPACK=$(GIT_DIR=esd_spack/.git git rev-parse HEAD) + - HASH_ESD_REPO=$(GIT_DIR=esd_spack/var/spack/repos/ebrains-spack-builds/.git git rev-parse HEAD) + - echo ${HASH_ESD_BASE_IMAGE} ${HASH_ESD_CONFIG} ${HASH_ESD_SPACK} ${HASH_ESD_REPO} + - echo ${HASH_ESD_BASE_IMAGE}${HASH_ESD_CONFIG}${HASH_ESD_SPACK}${HASH_ESD_REPO} | git hash-object --stdin + - ESD_HASH=$(echo ${HASH_ESD_BASE_IMAGE}${HASH_ESD_CONFIG}${HASH_ESD_SPACK}${HASH_ESD_REPO} | git hash-object --stdin) + - set -x + - skopeo inspect docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_${ESD_HASH} && ret=$? || ret=$? + - date + - | + if [ "$ret" -ne 0 ]; then + python3 bin/yashchiki --debug --jobs $(nproc) --update-build-cache --stages build-base build-spack image -- esd esd_spack esd_output + date + find /tmp -name "spack-build-out.txt" -exec || true + find /tmp -name "spack-build-out.txt" -print0 | tar -cvzf spack-build-outs.tar.gz --null --files-from - + find "${YASHCHIKI_HOME}/sandboxes/esd/opt/spack/opt/spack" -maxdepth 2 -exec ls -l {} \; || true + du -sh "${YASHCHIKI_HOME}/sandboxes/esd/opt/spack/opt/spack" || true + # upload ESD image + skopeo copy --dest-username="$HARBOR_USERNAME" --dest-password="$HARBOR_PASSWORD" sif:esd_output docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_${ESD_HASH} || true + date + # add a second tag (symbolic tag, potentially replacing an old one) + skopeo copy --dest-username="$HARBOR_USERNAME" --dest-password="$HARBOR_PASSWORD" docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output_${ESD_HASH} docker://${HARBOR_HOST}/${HARBOR_PROJECT}/esd:output || true + fi + - date + cache: + - key: buildenv-$CI_COMMIT_REF_SLUG + policy: pull + paths: + - esd_spack_buildenv/ + - key: fetch-$CI_COMMIT_REF_SLUG + policy: pull + paths: + - esd_spack/ + - .yashchiki/ + - key: buildnode-stuff-$CI_COMMIT_REF_SLUG + policy: pull-push + when: always + paths: + - .yashchiki/build_caches + - .yashchiki/preserved_packages + - .yashchiki/spack_ccache + artifacts: + when: always + paths: + - errors_concretization.log + - ${YASHCHIKI_HOME}/sandboxes/esd/opt/spack_specs + - ${YASHCHIKI_HOME}/log + - spack-build-outs.tar.gz + timeout: 5 days diff --git a/lib/yashchiki/build_sandbox.sh b/lib/yashchiki/build_sandbox.sh index 14723b1e5b237c1dab76a815d0382ea7dd299912..63e82755bce976a48b4b9708058d0d3f1e1314d8 100755 --- a/lib/yashchiki/build_sandbox.sh +++ b/lib/yashchiki/build_sandbox.sh @@ -102,6 +102,10 @@ export CONTAINER_STYLE="${CONTAINER_STYLE}" "${SPACK_INSTALL_SCRIPTS}/complete_spack_install_routine_called_in_post.sh" EOF +# test +echo apptainer -d exec --fakeroot ${TARGET_FOLDER} bash -c "hostname" +apptainer -d exec --fakeroot ${TARGET_FOLDER} bash -c "hostname" || true + PROOT_NO_SECCOMP=1 proot -w / -S ${TARGET_FOLDER} \ --bind=${YASHCHIKI_CACHES_ROOT}/download_cache:/opt/spack/var/spack/cache \ --bind=${YASHCHIKI_CACHES_ROOT}/spack_ccache:/opt/ccache \