diff --git a/Dockerfile.custom b/Dockerfile.custom index 6c9e01b..446ec83 100644 --- a/Dockerfile.custom +++ b/Dockerfile.custom @@ -32,7 +32,7 @@ RUN if [ -n "$GIT_VERSION" ]; then /scripts/install-git && git --version; fi ARG CHROME_VERSION ARG CHROME_DRIVER_VERSION -RUN if [ -n "$CHROME_VERSION" ]; then /scripts/install-chrome $CHROME_VERSION $CHROME_DRIVER_VERSION && google-chrome --version; fi +RUN if [ -n "$CHROME_VERSION" ]; then /scripts/install-chrome $CHROME_VERSION $CHROME_DRIVER_VERSION && ( google-chrome --version || chromium --version ); fi # NodeJS and Yarn ARG NODE_INSTALL_VERSION @@ -48,7 +48,6 @@ RUN if [ -n "$INSTALL_GOLANG_VERSION" ] ; then /scripts/install-golang "${INSTAL # Git LFS (https://git-lfs.github.com/) ARG LFS_VERSION -ARG LFS_DOWNLOAD_URL=https://github.com/git-lfs/git-lfs/releases/download/v${LFS_VERSION}/git-lfs-linux-amd64-v${LFS_VERSION}.tar.gz ARG LFS_DOWNLOAD_SHA256 RUN if [ -n "$LFS_VERSION" ]; then /scripts/install-lfs && git lfs --version; fi @@ -100,6 +99,8 @@ ENV LANG=C.UTF-8 \ LANGUAGE=C \ LC_ALL=C.UTF-8 +RUN /scripts/validate-binaries-architecture + # Set as env variables all versions configured ENV RUBY_VERSION=${RUBY_VERSION} \ GIT_VERSION=${GIT_VERSION} \ diff --git a/scripts/cache-google-chrome b/scripts/cache-google-chrome index 06b0489..a148ba8 100755 --- a/scripts/cache-google-chrome +++ b/scripts/cache-google-chrome @@ -12,7 +12,7 @@ apt-get -y update apt-get -y install apt-utils curl bash gnupg2 curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add - -echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list +echo "deb [arch=$(dpkg --print-architecture)] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list echo "Updating apt to get Google Chrome packages..." @@ -21,7 +21,7 @@ apt-get -y -q update echo "Checking for latest Chrome version in apt repository..." LATEST_VERSION=$(apt-cache show $PKG | grep Version | sort | tail -1 | sed -e "s/Version: //") -CHROME_DEB="google-chrome-stable_${LATEST_VERSION}_amd64.deb" +CHROME_DEB="google-chrome-stable_${LATEST_VERSION}_$(dpkg --print-architecture).deb" CHROME_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG}/${LATEST_VERSION}/${CHROME_DEB}" echo "Checking if cache has $CHROME_DEB" diff --git a/scripts/custom-docker-build b/scripts/custom-docker-build index 70fc86e..349c719 100755 --- a/scripts/custom-docker-build +++ b/scripts/custom-docker-build @@ -6,28 +6,34 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) source "$SCRIPT_DIR/lib/custom-docker.sh" function print_golang_args() { + declare -A GOLANG_DOWNLOAD_SHA256 + case "$1" in 1.14) INSTALL_GOLANG_VERSION=1.14.15 - GOLANG_DOWNLOAD_SHA256=c64a57b374a81f7cf1408d2c410a28c6f142414f1ffa9d1062de1d653b0ae0d6 + GOLANG_DOWNLOAD_SHA256[amd64]=c64a57b374a81f7cf1408d2c410a28c6f142414f1ffa9d1062de1d653b0ae0d6 + GOLANG_DOWNLOAD_SHA256[arm64v8]=4d964166a189c22032521c63935437c304bb7f01673b196898cff525897a1c27 ;; 1.15) INSTALL_GOLANG_VERSION=1.15.10 - GOLANG_DOWNLOAD_SHA256=4aa1267517df32f2bf1cc3d55dfc27d0c6b2c2b0989449c96dd19273ccca051d + GOLANG_DOWNLOAD_SHA256[amd64]=4aa1267517df32f2bf1cc3d55dfc27d0c6b2c2b0989449c96dd19273ccca051d + GOLANG_DOWNLOAD_SHA256[arm64v8]=ca3f3e84d863d8e758bfaab65430b12b6cff8f5a5648139245321d3401da64a7 ;; 1.16) INSTALL_GOLANG_VERSION=1.16.12 - GOLANG_DOWNLOAD_SHA256=7d657e86493ac1d5892f340a7d88b862b12edb5ac6e73c099e8e0668a6c916b7 + GOLANG_DOWNLOAD_SHA256[amd64]=7d657e86493ac1d5892f340a7d88b862b12edb5ac6e73c099e8e0668a6c916b7 + GOLANG_DOWNLOAD_SHA256[arm64v8]=7dbf50ab2e665ecd6c86a3f1ce8c04f7167f9895b91921e25cf1bdc1cb9b5fd7 ;; 1.17) INSTALL_GOLANG_VERSION=1.17.9 - GOLANG_DOWNLOAD_SHA256=9dacf782028fdfc79120576c872dee488b81257b1c48e9032d122cfdb379cca6 + GOLANG_DOWNLOAD_SHA256[amd64]=9dacf782028fdfc79120576c872dee488b81257b1c48e9032d122cfdb379cca6 + GOLANG_DOWNLOAD_SHA256[arm64v8]=44dcdcd4f0fa6f83c15ef70b31580f1e3f95895c2f11a00e36c440c3554b6ad5 ;; *) echo "Unknown golang version $1"; exit 1; esac printf -- "--build-arg INSTALL_GOLANG_VERSION=%s " "$INSTALL_GOLANG_VERSION" - printf -- "--build-arg GOLANG_DOWNLOAD_SHA256=%s " "$GOLANG_DOWNLOAD_SHA256" + printf -- "--build-arg GOLANG_DOWNLOAD_SHA256=%s " "${GOLANG_DOWNLOAD_SHA256[$CUSTOM_DOCKER_ARCH]}" } # If you add a new minor version here, be sure to check that the @@ -91,16 +97,19 @@ function print_git_args() { # 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=2a8e60cf51ec45aa0f4332aa0521d60ec75c76e485d13ebaeea915b9d70ea466 + LFS_DOWNLOAD_SHA256[amd64]=2a8e60cf51ec45aa0f4332aa0521d60ec75c76e485d13ebaeea915b9d70ea466 + LFS_DOWNLOAD_SHA256[arm64v8]=ff2f8472a5ac0e808108bad0cc6be5ca1849eb970228b1aa3d627bcbc8228ad9 ;; *) echo "Unknown Git LFS version $1"; exit 1; esac printf -- "--build-arg LFS_VERSION=%s " "$LFS_VERSION" - printf -- "--build-arg LFS_DOWNLOAD_SHA256=%s " "$LFS_DOWNLOAD_SHA256" + printf -- "--build-arg LFS_DOWNLOAD_SHA256=%s " "${LFS_DOWNLOAD_SHA256[$CUSTOM_DOCKER_ARCH]}" } function print_node_args() { @@ -241,22 +250,43 @@ function print_gcloud_args() { } function print_kubectl_args() { + declare -A KUBECTL_DOWNLOAD_SHA256 + case "$1" in 1.23) KUBECTL_VERSION=1.23.0 - KUBECTL_DOWNLOAD_SHA256=2d0f5ba6faa787878b642c151ccb2c3390ce4c1e6c8e2b59568b3869ba407c4f + KUBECTL_DOWNLOAD_SHA256[amd64]=2d0f5ba6faa787878b642c151ccb2c3390ce4c1e6c8e2b59568b3869ba407c4f + KUBECTL_DOWNLOAD_SHA256[arm64]=1d77d6027fc8dfed772609ad9bd68f611b7e4ce73afa949f27084ad3a92b15fe ;; *) echo "Unknown kubectl version $1"; exit 1; esac printf -- "--build-arg KUBECTL_VERSION=%s " "$KUBECTL_VERSION" - printf -- "--build-arg KUBECTL_DOWNLOAD_SHA256=%s " "$KUBECTL_DOWNLOAD_SHA256" + printf -- "--build-arg KUBECTL_DOWNLOAD_SHA256=%s " "${KUBECTL_DOWNLOAD_SHA256[$CUSTOM_DOCKER_ARCH]}" } function parse_arguments() { printf -- "-f Dockerfile.custom " + + # Mapping between sources of architectures + # - arch: a current image architecture (or uname -m if matching host, but can be different) + # - apk --print-arch: a alpine architecture for installed packages + # - dpkg --print-architecture: a debian architecture for installed packages + # - docker arch: a Docker Hub architecture for images + # + # arch | apk --print-arch | dpkg --print-architecture | docker arch + # x86_64 | x86_64 | amd64 | amd64 + # armhf | armhf | armhf | arm32v7 + # aarch64 | aarch64 | arm64 | arm64v8 + # defaults + case $(arch) in + x86_64) CUSTOM_DOCKER_ARCH=amd64 ;; + aarch64) CUSTOM_DOCKER_ARCH=arm64v8 ;; + *) echo "unknown architecture $(arch)"; exit 1;; + esac + CUSTOM_IMAGE_NAME=debian CUSTOM_IMAGE_VERSION=buster @@ -264,6 +294,7 @@ function parse_arguments() { if [ -n "${!tool}" ]; then version="${!tool}" case "$tool" in + ARCH) CUSTOM_DOCKER_ARCH=$version ;; DEBIAN) CUSTOM_IMAGE_VERSION=$version ;; RUBY) print_ruby_args $version ;; BUNDLER) print_bundler_args $version ;; @@ -285,6 +316,8 @@ function parse_arguments() { fi done + CUSTOM_IMAGE_NAME=$CUSTOM_DOCKER_ARCH/$CUSTOM_IMAGE_NAME # ex. https://hub.docker.com/r/amd64/debian/ + printf -- "--build-arg CUSTOM_IMAGE_NAME=%s " "$CUSTOM_IMAGE_NAME" printf -- "--build-arg CUSTOM_IMAGE_VERSION=%s " "$CUSTOM_IMAGE_VERSION" printf -- "--build-arg DEBIAN_VERSION=%s " "$CUSTOM_IMAGE_VERSION" diff --git a/scripts/install-chrome b/scripts/install-chrome index 641d445..d8a5e59 100755 --- a/scripts/install-chrome +++ b/scripts/install-chrome @@ -3,6 +3,16 @@ set -xeuo pipefail IFS=$'\n\t' +if [[ $(dpkg --print-architecture) == arm64 ]]; then + echo "The arm64 does not have prebuilt chrome. Using chromium instead." + apt-get update -q -y + apt-get install -y chromium chromium-driver + apt-get autoremove -yq + apt-get clean -yqq + rm -rf /var/lib/apt/lists/* + exit 0 +fi + CHROME_VERSION=${1:-99.0.4844.74-1} CHROME_DRIVER_VERSION=${2:-99.0.4844.51} # We hard code the URL rather than using $CI_API_V4_URL $CI_PROJECT_ID, @@ -11,7 +21,7 @@ CHROME_DOWNLOAD_URL_BASE="https://gitlab.com/api/v4/projects/1075790/packages/ge export DEBIAN_FRONTEND=noninteractive curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add - -echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list +echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list apt-get update -q -y @@ -19,8 +29,10 @@ apt-get update -q -y echo "Searching for $CHROME_VERSION in apt repository" CHECK_VERSION=$(apt-cache show google-chrome-stable | grep Version | grep "$CHROME_VERSION") || true +apt-cache policy google-chrome-stable + if [[ -z $CHECK_VERSION ]]; then - CHROME_DEB="google-chrome-stable_${CHROME_VERSION}_amd64.deb" + CHROME_DEB="google-chrome-stable_${CHROME_VERSION}_$(dpkg --print-architecture).deb" CHROME_URL="${CHROME_DOWNLOAD_URL_BASE}/${CHROME_VERSION}/${CHROME_DEB}" echo "Downloading from our Package registry: $CHROME_URL" curl --silent --show-error --fail -O $CHROME_URL diff --git a/scripts/install-golang b/scripts/install-golang index 25532b8..0ce4e4a 100755 --- a/scripts/install-golang +++ b/scripts/install-golang @@ -5,7 +5,7 @@ set -xeou pipefail INSTALL_GOLANG_VERSION=${1} GOLANG_DOWNLOAD_SHA256=${2} -GOLANG_DOWNLOAD_URL="https://golang.org/dl/go${INSTALL_GOLANG_VERSION}.linux-amd64.tar.gz" +GOLANG_DOWNLOAD_URL="https://golang.org/dl/go${INSTALL_GOLANG_VERSION}.linux-$(dpkg --print-architecture).tar.gz" curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz echo "${GOLANG_DOWNLOAD_SHA256} golang.tar.gz" | sha256sum -c - diff --git a/scripts/install-kubectl b/scripts/install-kubectl index db95a52..ad6b5c8 100755 --- a/scripts/install-kubectl +++ b/scripts/install-kubectl @@ -4,9 +4,9 @@ set -xeou pipefail KUBECTL_VERSION=${1} KUBECTL_DOWNLOAD_SHA256=${2} -KUBECTL_DOWNLOAD_URL="https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/amd64" +KUBECTL_DOWNLOAD_URL="https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/$(dpkg --print-architecture)/kubectl" -curl -fsSL "${KUBECTL_DOWNLOAD_URL}/kubectl" -o kubectl +curl -fsSL "${KUBECTL_DOWNLOAD_URL}" -o kubectl echo "${KUBECTL_DOWNLOAD_SHA256} kubectl" | sha256sum -c - chmod +x kubectl diff --git a/scripts/install-lfs b/scripts/install-lfs index 93ba1e9..244443a 100755 --- a/scripts/install-lfs +++ b/scripts/install-lfs @@ -3,6 +3,8 @@ set -xeuo pipefail IFS=$'\n\t' +LFS_DOWNLOAD_URL="https://github.com/git-lfs/git-lfs/releases/download/v${LFS_VERSION}/git-lfs-linux-$(dpkg --print-architecture)-v${LFS_VERSION}.tar.gz" + mkdir build \ && curl -fsSL "$LFS_DOWNLOAD_URL" -o git-lfs.tar.gz \ && echo "$LFS_DOWNLOAD_SHA256 git-lfs.tar.gz" | sha256sum -c - \ diff --git a/scripts/install-node b/scripts/install-node index f0086e3..9d60e69 100755 --- a/scripts/install-node +++ b/scripts/install-node @@ -13,7 +13,7 @@ curl -sS -L https://deb.nodesource.com/setup_${NODE_MAJOR} | bash - apt-get update -NODE_FILE_NAME="nodejs_$NODE_INSTALL_VERSION-deb-1nodesource1_amd64.deb" +NODE_FILE_NAME="nodejs_$NODE_INSTALL_VERSION-deb-1nodesource1_$(dpkg --print-architecture).deb" curl -s -O "https://deb.nodesource.com/node_$NODE_MAJOR/pool/main/n/nodejs/$NODE_FILE_NAME" dpkg -i "$NODE_FILE_NAME" rm -f "$NODE_FILE_NAME" diff --git a/scripts/validate-binaries-architecture b/scripts/validate-binaries-architecture new file mode 100755 index 0000000..a3f1794 --- /dev/null +++ b/scripts/validate-binaries-architecture @@ -0,0 +1,24 @@ +#!/bin/bash + +set -eo pipefail + +# convert architecture of a system into +# - use `arch` to show current system architecture +# - do not use `uname -m` as this shows kernel architecture +# - the `arch != uname -m` will be different when doing cross-compilation using `qemu-user` +# x86_64 -> x86-64 +# aarch64 -> aarch64 +ARCH=$(arch | tr '_' '-') + +# find all executables in $PATH +CMDs=$(compgen -c) +CMD_PATHs=$(which $CMDs || true) # some CMDs might be missing + +if files=$(file $CMD_PATHs | grep "ELF " | grep -v "$ARCH") +then + echo "Found files of different architecture than $(ARCH):" + echo "$files" + exit 1 +fi + +echo "Validated $(echo $CMD_PATHs | wc -w) binaries."