#!/bin/bash set -e IFS=$'\n\t' SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" source "$SCRIPT_DIR/custom-docker.sh" function fail() { echo "$@" 1>&2 exit 1 } function print_image_args() { declare -A CUSTOM_BASE_IMAGE declare -A BUILD_OS case "$1:$2" in debian:*) CUSTOM_BASE_IMAGE="$1:$2" BUILD_OS=debian OS_VERSION=$2 ;; ubi:8.*) CUSTOM_BASE_IMAGE="registry.access.redhat.com/ubi8/ubi:$2" BUILD_OS=ubi OS_VERSION=$2 ;; *) fail "Unknown image version $1:$2" ;; esac printf -- "--build-arg CUSTOM_BASE_IMAGE=%s " "$CUSTOM_BASE_IMAGE" printf -- "--build-arg BUILD_OS=%s " "$BUILD_OS" printf -- "--build-arg OS_VERSION=%s " "$OS_VERSION" } function print_golang_args() { declare -A GOLANG_DOWNLOAD_SHA256 # NOTE: See https://gitlab.com/gitlab-org/gitlab-build-images#note-regarding-golang-and-fips # when adding a new major/minor Golang version. case "$1" in 1.21) INSTALL_GOLANG_VERSION=1.21.10 INSTALL_GOLANG_FIPS_TAG=1.21.9-1 GOLANG_DOWNLOAD_SHA256[amd64]="e330e5d977bf4f3bdc157bc46cf41afa5b13d66c914e12fd6b694ccda65fcf92" GOLANG_DOWNLOAD_SHA256[arm64]="428e0b9ecab5762b7c2be000ad1be6f432dccfcd99bb8b8aeeb757d987bfda9d" ;; 1.22) INSTALL_GOLANG_VERSION=1.22.3 INSTALL_GOLANG_FIPS_TAG=1.22.2-1 GOLANG_DOWNLOAD_SHA256[amd64]="8920ea521bad8f6b7bc377b4824982e011c19af27df88a815e3586ea895f1b36" GOLANG_DOWNLOAD_SHA256[arm64]="6c33e52a5b26e7aa021b94475587fce80043a727a54ceb0eee2f9fc160646434" ;; *) fail "Unknown golang version $1" ;; esac printf -- "--build-arg INSTALL_GOLANG_VERSION=%s " "$INSTALL_GOLANG_VERSION" printf -- "--build-arg GOLANG_DOWNLOAD_SHA256=%q " "${GOLANG_DOWNLOAD_SHA256[*]}" printf -- "--build-arg INSTALL_GOLANG_FIPS_TAG=%s " "${INSTALL_GOLANG_FIPS_TAG}" } function print_rust_args() { case "$1" in 1.65) INSTALL_RUST_VERSION="1.65.0" ;; 1.73) INSTALL_RUST_VERSION="1.73.0" ;; *) fail "Unknown rust version $1" ;; esac printf -- "--build-arg INSTALL_RUST_VERSION=%s " "$INSTALL_RUST_VERSION" } # Check https://gitlab.com/gitlab-org/gitlab-build-images/-/packages to see which versions have been cached # Chromium version can sometimes lag behind so the versions have to be defined separately function print_chrome_args() { case "$1" in 117|117.0) CHROME_VERSION=117.0.5938.92-1 CHROMIUM_VERSION=117.0.5938.62-1 ;; 119|119.0) CHROME_VERSION=119.0.6045.159-1 CHROMIUM_VERSION=119.0.6045.159-1 ;; 120|120.0) CHROME_VERSION=120.0.6099.216-1 CHROMIUM_VERSION=120.0.6099.216-1 ;; 123|123.0) CHROME_VERSION=123.0.6312.105-1 CHROMIUM_VERSION=123.0.6312.105-1 ;; *) fail "Unknown chrome version $1" ;; esac printf -- "--build-arg CHROME_VERSION=%s " "$CHROME_VERSION" printf -- "--build-arg CHROMIUM_VERSION=%s " "$CHROMIUM_VERSION" } # see https://www.kernel.org/pub/software/scm/git function print_git_args() { case "$1" in 2.33) GIT_VERSION=2.33.1 GIT_DOWNLOAD_SHA256=02047f8dc8934d57ff5e02aadd8a2fe8e0bcf94a7158da375e48086cc46fce1d ;; 2.36) GIT_VERSION=2.36.1 GIT_DOWNLOAD_SHA256=37d936fd17c81aa9ddd3dba4e56e88a45fa534ad0ba946454e8ce818760c6a2c ;; *) fail "Unknown git version $1" ;; esac case "$GIT_VERSION" in *.rc[0-9]) GIT_DOWNLOAD_URL=https://www.kernel.org/pub/software/scm/git/testing/git-${GIT_VERSION}.tar.gz;; *) GIT_DOWNLOAD_URL=https://www.kernel.org/pub/software/scm/git/git-${GIT_VERSION}.tar.gz;; esac printf -- "--build-arg GIT_VERSION=%s " "$GIT_VERSION" printf -- "--build-arg GIT_DOWNLOAD_SHA256=%s " "$GIT_DOWNLOAD_SHA256" printf -- "--build-arg GIT_DOWNLOAD_URL=%s " "$GIT_DOWNLOAD_URL" } # see https://github.com/git-lfs/git-lfs/releases function print_lfs_args() { declare -A LFS_DOWNLOAD_SHA256 case "$1" in 2.9) LFS_VERSION=2.9.1 LFS_DOWNLOAD_SHA256[amd64]=2a8e60cf51ec45aa0f4332aa0521d60ec75c76e485d13ebaeea915b9d70ea466 LFS_DOWNLOAD_SHA256[arm64]=ff2f8472a5ac0e808108bad0cc6be5ca1849eb970228b1aa3d627bcbc8228ad9 ;; *) fail "Unknown Git LFS version $1" ;; esac printf -- "--build-arg LFS_VERSION=%s " "$LFS_VERSION" printf -- "--build-arg LFS_DOWNLOAD_SHA256=%q " "${LFS_DOWNLOAD_SHA256[*]}" } function print_node_args() { case "$1" in 18|18.17) NODE_INSTALL_VERSION=18.17.1 ;; 20|20.12) NODE_INSTALL_VERSION=20.12.2 ;; *) fail "Unknown node version $1" ;; esac printf -- "--build-arg NODE_INSTALL_VERSION=%s " "$NODE_INSTALL_VERSION" } function print_yarn_args() { case "$1" in 1.22) YARN_INSTALL_VERSION=1.22.19 ;; *) fail "Unknown yarn version $1" ;; esac printf -- "--build-arg YARN_INSTALL_VERSION=%s " "$YARN_INSTALL_VERSION" } function print_postgres_args() { printf -- "--build-arg POSTGRES_VERSION=%s " "$1" } function print_docker_args() { printf -- "--build-arg DOCKER_VERSION=%s " "$1" } function print_graphicsmagick_args() { case "$1" in 1.3.29) GRAPHISMAGICK_VERSION=1.3.29 GRAPHISMAGICK_DOWNLOAD_SHA256=de820cd10597205941a7e9d02c2e679231e92e8e769c204ef09034d2279ad453 ;; 1.3.33) GRAPHISMAGICK_VERSION=1.3.33 GRAPHISMAGICK_DOWNLOAD_SHA256=00ea0df7c78c903cce325f402429bcd3924168cf39277f743a0641d47c411ee8 ;; 1.3.34) GRAPHISMAGICK_VERSION=1.3.34 GRAPHISMAGICK_DOWNLOAD_SHA256=4717f7a32d964c515d83706fd52d34e089c2ffa35f8fbf43c923ce19343cf2f4 ;; 1.3.36) GRAPHISMAGICK_VERSION=1.3.36 GRAPHISMAGICK_DOWNLOAD_SHA256=1e6723c48c4abbb31197fadf8396b2d579d97e197123edc70a4f057f0533d563 ;; *) fail "Unknown graphicsmagick version $1" ;; esac printf -- "--build-arg GRAPHISMAGICK_VERSION=%s " "$GRAPHISMAGICK_VERSION" printf -- "--build-arg GRAPHISMAGICK_DOWNLOAD_SHA256=%s " "$GRAPHISMAGICK_DOWNLOAD_SHA256" } function print_exiftool_args() { case "$1" in 12.60) EXIFTOOL_VERSION=12.60 EXIFTOOL_DOWNLOAD_SHA256=30f22c28905c7aae46986c41cf1f3635781b336c8183b62348198734ffd33366 ;; *) fail "Unknown exiftool version $1" ;; esac printf -- "--build-arg EXIFTOOL_VERSION=%s " "$EXIFTOOL_VERSION" printf -- "--build-arg EXIFTOOL_DOWNLOAD_SHA256=%s " "$EXIFTOOL_DOWNLOAD_SHA256" } function print_bazelisk_args() { case "$1" in 1.9.0) BAZELISK_VERSION=1.9.0 BAZELISK_DOWNLOAD_SHA256=b8c7f2a1b07ad64a2f27f8f19a202f90d044de7b5b6ccc387a6fe5d4a8ec4937 ;; *) fail "Unknown bazelisk version $1" ;; esac printf -- "--build-arg BAZELISK_VERSION=%s " "$BAZELISK_VERSION" printf -- "--build-arg BAZELISK_DOWNLOAD_SHA256=%s " "$BAZELISK_DOWNLOAD_SHA256" } function print_ruby_args() { case "$1" in 3.0.6) RUBY_VERSION="3.0.6" RUBY_DOWNLOAD_SHA256="6e6cbd490030d7910c0ff20edefab4294dfcd1046f0f8f47f78b597987ac683e" ;; 3.1.5) RUBY_VERSION="3.1.5" RUBY_DOWNLOAD_SHA256="3685c51eeee1352c31ea039706d71976f53d00ab6d77312de6aa1abaf5cda2c5" ;; 3.2.4) RUBY_VERSION="3.2.4" RUBY_DOWNLOAD_SHA256="c72b3c5c30482dca18b0f868c9075f3f47d8168eaf626d4e682ce5b59c858692" ;; *) fail "Unknown ruby version $1" ;; esac printf -- "--build-arg RUBY_VERSION=%s " "$RUBY_VERSION" printf -- "--build-arg RUBY_DOWNLOAD_SHA256=%s " "$RUBY_DOWNLOAD_SHA256" } function print_bundler_args() { case "$1" in 2.1) BUNDLER_VERSION=2.1.4 ;; 2.3) BUNDLER_VERSION=2.3.26 ;; 2.4) BUNDLER_VERSION=2.4.10 ;; 2.5) BUNDLER_VERSION=2.5.4 ;; *) fail "Unknown bundler version $1" ;; esac printf -- "--build-arg BUNDLER_VERSION=%s " "$BUNDLER_VERSION" } function print_rubygems_args() { case "$1" in 3.1) RUBYGEMS_VERSION=3.1.6 ;; 3.2) RUBYGEMS_VERSION=3.2.33 ;; 3.4) RUBYGEMS_VERSION=3.4.4 ;; *) fail "Unknown rubygems version $1" ;; esac printf -- "--build-arg RUBYGEMS_VERSION=%s " "$RUBYGEMS_VERSION" } function print_gcloud_args() { case "$1" in 383) GCLOUD_VERSION=383.0.1 ;; *) fail "Unknown gcloud version $1" ;; esac printf -- "--build-arg GCLOUD_VERSION=%s " "$GCLOUD_VERSION" } function print_kubectl_args() { declare -A KUBECTL_DOWNLOAD_SHA256 # Use the commands below to download the sha256, and adapt the version number in the commands. # # curl -L "https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl.sha256" # curl -L "https://dl.k8s.io/release/v1.29.0/bin/linux/arm64/kubectl.sha256" case "$1" in 1.23) KUBECTL_VERSION=1.23.0 KUBECTL_DOWNLOAD_SHA256[amd64]=2d0f5ba6faa787878b642c151ccb2c3390ce4c1e6c8e2b59568b3869ba407c4f KUBECTL_DOWNLOAD_SHA256[arm64]=1d77d6027fc8dfed772609ad9bd68f611b7e4ce73afa949f27084ad3a92b15fe ;; 1.26) KUBECTL_VERSION=1.26.0 KUBECTL_DOWNLOAD_SHA256[amd64]=b6769d8ac6a0ed0f13b307d289dc092ad86180b08f5b5044af152808c04950ae KUBECTL_DOWNLOAD_SHA256[arm64]=79b14e4ddada9e81d2989f36a89faa9e56f8abe6e0246e7bdc305c93c3731ea4 ;; 1.27) # We need to use at least 1.27.2 # # see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119916 KUBECTL_VERSION=1.27.2 KUBECTL_DOWNLOAD_SHA256[amd64]=4f38ee903f35b300d3b005a9c6bfb9a46a57f92e89ae602ef9c129b91dc6c5a5 KUBECTL_DOWNLOAD_SHA256[arm64]=1b0966692e398efe71fe59f913eaec44ffd4468cc1acd00bf91c29fa8ff8f578 ;; 1.28) KUBECTL_VERSION=1.28.0 KUBECTL_DOWNLOAD_SHA256[amd64]=4717660fd1466ec72d59000bb1d9f5cdc91fac31d491043ca62b34398e0799ce KUBECTL_DOWNLOAD_SHA256[arm64]=f5484bd9cac66b183c653abed30226b561f537d15346c605cc81d98095f1717c ;; 1.29) KUBECTL_VERSION=1.29.0 KUBECTL_DOWNLOAD_SHA256[amd64]=0e03ab096163f61ab610b33f37f55709d3af8e16e4dcc1eb682882ef80f96fd5 KUBECTL_DOWNLOAD_SHA256[arm64]=8f7a4bd6bae900a4ddab12bd1399aa652c0d59ea508f39b910e111d248893ff7 ;; 1.30) KUBECTL_VERSION=1.30.0 KUBECTL_DOWNLOAD_SHA256[amd64]=7c3807c0f5c1b30110a2ff1e55da1d112a6d0096201f1beb81b269f582b5d1c5 KUBECTL_DOWNLOAD_SHA256[arm64]=669af0cf520757298ea60a8b6eb6b719ba443a9c7d35f36d3fb2fd7513e8c7d2 ;; *) fail "Unknown kubectl version $1" ;; esac printf -- "--build-arg KUBECTL_VERSION=%s " "$KUBECTL_VERSION" printf -- "--build-arg KUBECTL_DOWNLOAD_SHA256=%q " "${KUBECTL_DOWNLOAD_SHA256[*]}" } function print_helm_args() { declare -A HELM_DOWNLOAD_SHA256 case "$1" in 3.9) HELM_VERSION=3.9.4 HELM_DOWNLOAD_SHA256[amd64]=31960ff2f76a7379d9bac526ddf889fb79241191f1dbe2a24f7864ddcb3f6560 HELM_DOWNLOAD_SHA256[arm64]=d24163e466f7884c55079d1050968e80a05b633830047116cdfd8ae28d35b0c0 ;; 3.10) HELM_VERSION=3.10.3 HELM_DOWNLOAD_SHA256[amd64]=950439759ece902157cf915b209b8d694e6f675eaab5099fb7894f30eeaee9a2 HELM_DOWNLOAD_SHA256[arm64]=dca718eb68c72c51fc7157c4c2ebc8ce7ac79b95fc9355c5427ded99e913ec4c ;; 3.14) HELM_VERSION=3.14.0 HELM_DOWNLOAD_SHA256[amd64]=f43e1c3387de24547506ab05d24e5309c0ce0b228c23bd8aa64e9ec4b8206651 HELM_DOWNLOAD_SHA256[arm64]=b29e61674731b15f6ad3d1a3118a99d3cc2ab25a911aad1b8ac8c72d5a9d2952 ;; *) fail "Unknown helm version $1" ;; esac printf -- "--build-arg HELM_VERSION=%s " "$HELM_VERSION" printf -- "--build-arg HELM_DOWNLOAD_SHA256=%q " "${HELM_DOWNLOAD_SHA256[*]}" } function print_kind_args() { declare -A KIND_DOWNLOAD_SHA256 case "$1" in 0.20) KIND_VERSION=0.20.0 KIND_DOWNLOAD_SHA256[amd64]=513a7213d6d3332dd9ef27c24dab35e5ef10a04fa27274fe1c14d8a246493ded KIND_DOWNLOAD_SHA256[arm64]=639f7808443559aa30c3642d9913b1615d611a071e34f122340afeda97b8f422 ;; *) fail "Unknown helm version $1" ;; esac printf -- "--build-arg KIND_VERSION=%s " "$KIND_VERSION" printf -- "--build-arg KIND_DOWNLOAD_SHA256=%q " "${KIND_DOWNLOAD_SHA256[*]}" } function print_vcluster_args() { declare -A VCLUSTER_DOWNLOAD_SHA256 case "$1" in 0.19) VCLUSTER_VERSION=0.19.4 VCLUSTER_DOWNLOAD_SHA256[amd64]=42e2b436c333d1b914525590d928160c56529b7351b88886322f1cca3b240f10 VCLUSTER_DOWNLOAD_SHA256[arm64]=2f138bbfb3a57a25e7635626a80b31d248d08507d6b021aaa1a40c274282ced7 ;; *) fail "Unknown vcluster version $1" ;; esac printf -- "--build-arg VCLUSTER_VERSION=%s " "$VCLUSTER_VERSION" printf -- "--build-arg VCLUSTER_DOWNLOAD_SHA256=%q " "${VCLUSTER_DOWNLOAD_SHA256[*]}" } function print_helm_kubeconform_args() { HELM_KUBECONFORM_VERSION="$1" printf -- "--build-arg HELM_KUBECONFORM_VERSION=%s " "$HELM_KUBECONFORM_VERSION" } function print_awscli_args() { AWSCLI_VERSION="$1" printf -- "--build-arg AWSCLI_VERSION=%s " "$AWSCLI_VERSION" } function parse_arguments() { printf -- "-f Dockerfile.custom " # We make use of 2 variables related to the build environment. # 1. `CUSTOM_DOCKER_IMAGE` - Defines the reference of image used as # base for building images. Follows a # valid docker image reference format # - "debian:bullseye" # - "registry.access.redhat.com/ubi8/ubi:8.6" # 2. `BUILD_OS` - Used by installation scripts of various # components to detect the OS being worked # on. Follows regular docker image:tag # format - "debian:bullseye" or "ubi:8.6". TARGETARCH=${ARCH:-amd64} for tool in "${PATH_TOOLS[@]}" "${TAG_TOOLS[@]}"; do if [ -n "${!tool}" ]; then version="${!tool}" case "$tool" in # explode debian:version into `print_image_args debian version` OS) print_image_args ${version%:*} ${version##*:} ;; DEBIAN) print_image_args debian $version ;; UBI) print_image_args ubi $version ;; RUBY) print_ruby_args $version ;; BUNDLER) print_bundler_args $version ;; RUBYGEMS) print_rubygems_args $version ;; GOLANG) print_golang_args $version ;; RUST) print_rust_args $version ;; CHROME) print_chrome_args $version ;; DOCKER) print_docker_args $version ;; GIT) print_git_args $version ;; LFS) print_lfs_args $version ;; NODE) print_node_args $version ;; YARN) print_yarn_args $version ;; POSTGRESQL) print_postgres_args $version ;; GRAPHICSMAGICK) print_graphicsmagick_args $version ;; EXIFTOOL) print_exiftool_args $version ;; BAZELISK) print_bazelisk_args $version ;; GCLOUD) print_gcloud_args $version ;; KUBECTL) print_kubectl_args $version ;; HELM) print_helm_args $version ;; KIND) print_kind_args $version ;; VCLUSTER) print_vcluster_args $version ;; AWSCLI) print_awscli_args $version ;; HELM_KUBECONFORM) print_helm_kubeconform_args $version ;; *) fail "Unknown tool $tool" ;; esac fi done printf -- "--platform=%s " "${TARGETARCH}" } function run_command() { printf "\t%s\n" "$@" eval "$@" } function build_custom_if_needed() { build_image_path=$(get_image_path) build_image_tag=$(get_image_tag) full_image_name="$build_image_path:$build_image_tag" echo "Building image $full_image_name" docker_build_command=$(parse_arguments) docker_build_command="${docker_build_command} $@" docker_build_command="${docker_build_command} --cache-from=\"$full_image_name\"" docker_build_command="${docker_build_command} --tag=\"$full_image_name\"" echo "Docker build command:" # Prefer using `docker buildx` as it is more flexible, # or use regular `docker build` if not available on older systems if docker buildx version &> /dev/null; then docker_build_command="${docker_build_command} --cache-to=type=inline" docker_build_command="${docker_build_command} --push=${PUSH_CUSTOM_IMAGE:-false}" run_command docker buildx build $docker_build_command . else docker_build_command="${docker_build_command} --build-arg TARGETARCH=${ARCH}" run_command docker build $docker_build_command . if [[ "$PUSH_CUSTOM_IMAGE" == "true" ]]; then run_command docker push "$full_image_name" fi fi echo "${CI_JOB_URL}: $full_image_name" > "${CI_JOB_ID}-${CI_JOB_NAME_SLUG}-built-image.txt" printf "\n\nSUCCESS - Successfully built:\n\t%s\n" "$full_image_name" } # If OS is specified ignore other ways to specify system # Use DEBIAN if UBI is not specified if [[ -n "$OS" ]]; then unset DEBIAN UBI elif [[ -n "$UBI" ]]; then unset DEBIAN else DEBIAN=${DEBIAN:-bookworm} fi build_custom_if_needed $@