diff --git a/.github/actions/build-and-push-image/action.yaml b/.github/actions/build-and-push-image/action.yaml index 7c31d33f..81831735 100644 --- a/.github/actions/build-and-push-image/action.yaml +++ b/.github/actions/build-and-push-image/action.yaml @@ -4,6 +4,10 @@ inputs: image-flavor: description: A flavor used to tag the apollo-ci image. required: true + arch: + description: Target architecture with default to amd64. + required: false + default: amd64 outputs: image-tag: description: The full image tag that was built and pushed @@ -15,5 +19,6 @@ runs: id: build-and-push run: | .github/actions/build-and-push-image/build-and-push-image.sh \ - "${{ inputs.image-flavor }}" + "${{ inputs.image-flavor }}" \ + "${{ inputs.arch }}" shell: bash diff --git a/.github/actions/build-and-push-image/build-and-push-image.sh b/.github/actions/build-and-push-image/build-and-push-image.sh index 30f48f07..8a9e222f 100755 --- a/.github/actions/build-and-push-image/build-and-push-image.sh +++ b/.github/actions/build-and-push-image/build-and-push-image.sh @@ -4,14 +4,19 @@ set -euo pipefail build_and_push_image() { local image_flavor="$1" + local arch="${2:-amd64}" docker login -u "$QUAY_STACKROX_IO_RW_USERNAME" --password-stdin <<<"$QUAY_STACKROX_IO_RW_PASSWORD" quay.io TAG="$(scripts/get_tag.sh "${image_flavor}")" + if [[ "${arch}" == "arm64" ]]; then + TAG="${TAG}-arm64" + make "${image_flavor}-image-arm64" + else + make "${image_flavor}-image" + fi IMAGE="quay.io/stackrox-io/apollo-ci:${TAG}" - make "${image_flavor}-image" - retry 5 true docker push "${IMAGE}" echo "image-tag=${IMAGE}" >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 25472a3f..08972e16 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -76,6 +76,69 @@ jobs: path: image-info/${{ matrix.image-flavor }}.txt retention-days: 1 + build-and-push-builder-images-arm64: + runs-on: ubuntu-latest + strategy: + matrix: + image-flavor: + - stackrox-build + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - uses: ./.github/actions/build-and-push-image + id: build-and-push-image + with: + image-flavor: "${{ matrix.image-flavor }}" + arch: arm64 + - name: Save image info + run: | + mkdir -p image-info + echo "${{ steps.build-and-push-image.outputs.image-tag }}" > "image-info/${{ matrix.image-flavor }}-arm64.txt" + - name: Upload image info + uses: actions/upload-artifact@v4 + with: + name: image-info-${{ matrix.image-flavor }}-arm64 + path: image-info/${{ matrix.image-flavor }}-arm64.txt + retention-days: 1 + + build-and-push-test-images-arm64: + needs: build-and-push-builder-images-arm64 + runs-on: ubuntu-latest + strategy: + matrix: + image-flavor: + - stackrox-test + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - uses: ./.github/actions/build-and-push-image + id: build-and-push-image + with: + image-flavor: "${{ matrix.image-flavor }}" + arch: arm64 + - name: Save image info + run: | + mkdir -p image-info + echo "${{ steps.build-and-push-image.outputs.image-tag }}" > "image-info/${{ matrix.image-flavor }}-arm64.txt" + - name: Upload image info + uses: actions/upload-artifact@v4 + with: + name: image-info-${{ matrix.image-flavor }}-arm64 + path: image-info/${{ matrix.image-flavor }}-arm64.txt + retention-days: 1 + test-cci-export: runs-on: ubuntu-latest needs: @@ -97,6 +160,8 @@ jobs: needs: - build-and-push-builder-images - build-and-push-test-images + - build-and-push-builder-images-arm64 + - build-and-push-test-images-arm64 steps: - name: Download all image info artifacts uses: actions/download-artifact@v4 diff --git a/Makefile b/Makefile index e101256c..2d97e18b 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,14 @@ stackrox-build-image: -f images/stackrox-build.Dockerfile \ images/ +.PHONY: stackrox-build-image-arm64 +stackrox-build-image-arm64: + $(DOCKER) build \ + --platform linux/arm64 \ + -t quay.io/$(QUAY_REPO)/apollo-ci:$(STACKROX_BUILD_TAG)-arm64 \ + -f images/stackrox-build.Dockerfile \ + images/ + STACKROX_TEST_TAG=$(shell scripts/get_tag.sh "stackrox-test") .PHONY: stackrox-test-image @@ -24,6 +32,15 @@ stackrox-test-image: -f images/stackrox-test.Dockerfile \ images/ +.PHONY: stackrox-test-image-arm64 +stackrox-test-image-arm64: + $(DOCKER) build \ + --platform linux/arm64 \ + -t quay.io/$(QUAY_REPO)/apollo-ci:$(STACKROX_TEST_TAG)-arm64 \ + --build-arg BASE_TAG=$(STACKROX_BUILD_TAG)-arm64 \ + -f images/stackrox-test.Dockerfile \ + images/ + STACKROX_UI_TEST_TAG=$(shell scripts/get_tag.sh "stackrox-ui-test") .PHONY: stackrox-ui-test-image diff --git a/images/stackrox-build.Dockerfile b/images/stackrox-build.Dockerfile index 1997df86..08012df3 100644 --- a/images/stackrox-build.Dockerfile +++ b/images/stackrox-build.Dockerfile @@ -2,6 +2,8 @@ FROM registry.access.redhat.com/ubi8:latest +ARG TARGETARCH + SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN touch /i-am-rox-ci-image @@ -57,11 +59,19 @@ RUN dnf update -y && \ ARG GOLANG_VERSION=1.25.3 ARG GOLANG_SHA256=0335f314b6e7bfe08c3d0cfaa7c19db961b7b99fb20be62b0a826c992ad14e0f +ARG GOLANG_SHA256_ARM64=1d42ebc84999b5e2069f5e31b67d6fc5d67308adad3e178d5a2ee2c9ff2001f5 ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH -RUN url="https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz" && \ +RUN set -ex && \ + if [ "$TARGETARCH" = "arm64" ]; then \ + url="https://dl.google.com/go/go${GOLANG_VERSION}.linux-arm64.tar.gz"; \ + sha="${GOLANG_SHA256_ARM64}"; \ + else \ + url="https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz"; \ + sha="${GOLANG_SHA256}"; \ + fi && \ wget --no-verbose -O go.tgz "$url" && \ - echo "${GOLANG_SHA256} *go.tgz" | sha256sum -c - && \ + echo "${sha} go.tgz" | sha256sum -c - && \ tar -C /usr/local -xzf go.tgz && \ rm go.tgz && \ mkdir -p "$GOPATH/src" "$GOPATH/bin" && \ @@ -69,17 +79,24 @@ RUN url="https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz" && \ ARG FETCH_VERSION=0.3.5 ARG FETCH_SHA256=8d4d99e903b30dbd24290e9a056a982ea2326a05ded24c63be64df16e7e0d9f0 -RUN wget --no-verbose -O fetch https://github.com/gruntwork-io/fetch/releases/download/v${FETCH_VERSION}/fetch_linux_amd64 && \ - echo "${FETCH_SHA256} fetch" | sha256sum -c - && \ - install fetch /usr/bin && \ - rm fetch +RUN set -ex && \ + if [ "$TARGETARCH" = "amd64" ]; then \ + wget --no-verbose -O fetch "https://github.com/gruntwork-io/fetch/releases/download/v${FETCH_VERSION}/fetch_linux_amd64" && \ + echo "${FETCH_SHA256} fetch" | sha256sum -c - && \ + install fetch /usr/bin && rm fetch; \ + fi ARG OSSLS_VERSION=0.11.1 ARG OSSLS_SHA256=f1bf3012961c1d90ba307a46263f29025028d35c209b9a65e5c7d502c470c95f -RUN fetch --repo="https://github.com/stackrox/ossls" --tag="${OSSLS_VERSION}" --release-asset="ossls_linux_amd64" . && \ - echo "${OSSLS_SHA256} *ossls_linux_amd64" | sha256sum -c - && \ - install ossls_linux_amd64 /usr/bin/ossls && \ - rm ossls_linux_amd64 && \ +RUN set -ex && \ + if [ "$TARGETARCH" = "arm64" ]; then \ + wget --no-verbose -O ossls_linux_arm64 "https://github.com/stackrox/ossls/releases/download/v${OSSLS_VERSION}/ossls_linux_arm64" && \ + install ossls_linux_arm64 /usr/bin/ossls && rm -f ossls_linux_arm64; \ + else \ + fetch --repo="https://github.com/stackrox/ossls" --tag="${OSSLS_VERSION}" --release-asset="ossls_linux_amd64" . && \ + echo "${OSSLS_SHA256} ossls_linux_amd64" | sha256sum -c - && \ + install ossls_linux_amd64 /usr/bin/ossls && rm -f ossls_linux_amd64; \ + fi && \ ossls version ENV CGO_ENABLED=1 diff --git a/images/stackrox-test.Dockerfile b/images/stackrox-test.Dockerfile index 83df5824..fd241b9d 100644 --- a/images/stackrox-test.Dockerfile +++ b/images/stackrox-test.Dockerfile @@ -4,6 +4,8 @@ ARG BASE_TAG FROM quay.io/stackrox-io/apollo-ci:${BASE_TAG} as base +ARG TARGETARCH + # This line makes sure that piped commands in RUN instructions exit early. # This should not affect use in CircleCI because Circle doesn't use # CMD/ENTRYPOINT. @@ -24,7 +26,12 @@ RUN set -ex \ ENV BASH_ENV /etc/initial-bash.env # Install Postgres repo -RUN dnf --disablerepo="*" install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm +RUN set -ex && \ + if [ "$TARGETARCH" = "arm64" ]; then \ + dnf --disablerepo="*" install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-aarch64/pgdg-redhat-repo-latest.noarch.rpm; \ + else \ + dnf --disablerepo="*" install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm; \ + fi # Install all the packages RUN dnf update -y \ @@ -63,10 +70,10 @@ RUN set -ex \ # Install docker binary ARG DOCKER_VERSION=29.2.1 RUN set -ex \ - && DOCKER_URL="https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz" \ + && if [ "$TARGETARCH" = "arm64" ]; then DOCKER_ARCH=aarch64; else DOCKER_ARCH=x86_64; fi \ + && DOCKER_URL="https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz" \ && echo Docker URL: $DOCKER_URL \ && wget --no-verbose -O /tmp/docker.tgz "${DOCKER_URL}" \ - && ls -lha /tmp/docker.tgz \ && tar -xz -C /tmp -f /tmp/docker.tgz \ && install /tmp/docker/docker /usr/local/bin \ && rm -rf /tmp/docker /tmp/docker.tgz \ @@ -87,10 +94,11 @@ RUN set -ex \ # helm RUN set -ex \ - && wget --no-verbose -O helm.tgz https://get.helm.sh/helm-v3.11.2-linux-amd64.tar.gz \ + && if [ "$TARGETARCH" = "arm64" ]; then helm_arch=arm64; else helm_arch=amd64; fi \ + && wget --no-verbose -O helm.tgz "https://get.helm.sh/helm-v3.11.2-linux-${helm_arch}.tar.gz" \ && tar -xf helm.tgz \ - && install linux-amd64/helm /usr/local/bin \ - && rm -rf helm.tgz linux-amd64 \ + && install "linux-${helm_arch}/helm" /usr/local/bin \ + && rm -rf helm.tgz "linux-${helm_arch}" \ && command -v helm # Install gradle @@ -107,7 +115,8 @@ RUN set -ex \ # Install aws cli RUN set -ex \ - && wget --no-verbose -O "awscliv2.zip" "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-2.7.17.zip" \ + && if [ "$TARGETARCH" = "arm64" ]; then aws_arch=aarch64; else aws_arch=x86_64; fi \ + && wget --no-verbose -O "awscliv2.zip" "https://awscli.amazonaws.com/awscli-exe-linux-${aws_arch}-2.7.17.zip" \ && unzip awscliv2.zip \ && ./aws/install \ && rm awscliv2.zip \ @@ -115,41 +124,50 @@ RUN set -ex \ && aws --version # Install yq v4.16.2 +ARG YQ_AMD64_SHA256=5c911c4da418ae64af5527b7ee36e77effb85de20c2ce732ed14c7f72743084d +ARG YQ_ARM64_SHA256=eef1f9db6e10fd5fe8c10ef974d38db49f27095cea0759e7de9b2f202ed498ca RUN set -ex \ - && wget --no-verbose "https://github.com/mikefarah/yq/releases/download/v4.16.2/yq_linux_amd64" \ - && sha256sum --check --status <<< "5c911c4da418ae64af5527b7ee36e77effb85de20c2ce732ed14c7f72743084d yq_linux_amd64" \ - && mv yq_linux_amd64 /usr/bin/yq \ + && if [ "$TARGETARCH" = "arm64" ]; then yq_bin=yq_linux_arm64; yq_sha="${YQ_ARM64_SHA256}"; else yq_bin=yq_linux_amd64; yq_sha="${YQ_AMD64_SHA256}"; fi \ + && wget --no-verbose "https://github.com/mikefarah/yq/releases/download/v4.16.2/${yq_bin}" \ + && echo "${yq_sha} ${yq_bin}" | sha256sum -c - \ + && mv "${yq_bin}" /usr/bin/yq \ && chmod +x /usr/bin/yq # Install hub-comment RUN set -ex \ - && wget --quiet https://github.com/joshdk/hub-comment/releases/download/0.1.0-rc6/hub-comment_linux_amd64 \ - && sha256sum --check --status <<< "2a2640f44737873dfe30da0d5b8453419d48a494f277a70fd9108e4204fc4a53 hub-comment_linux_amd64" \ - && mv hub-comment_linux_amd64 /usr/bin/hub-comment \ - && chmod +x /usr/bin/hub-comment + && if [ "$TARGETARCH" = "arm64" ]; then \ + go install "github.com/joshdk/hub-comment@v0.1.0-rc6" && mv "$GOPATH/bin/hub-comment" /usr/bin/hub-comment; \ + else \ + wget --quiet -O hub-comment_linux_amd64 https://github.com/joshdk/hub-comment/releases/download/0.1.0-rc6/hub-comment_linux_amd64 \ + && sha256sum --check --status <<< "2a2640f44737873dfe30da0d5b8453419d48a494f277a70fd9108e4204fc4a53 hub-comment_linux_amd64" \ + && mv hub-comment_linux_amd64 /usr/bin/hub-comment && chmod +x /usr/bin/hub-comment; \ + fi # Install shellcheck ARG SHELLCHECK_VERSION=0.10.0 ARG SHELLCHECK_SHA256=6c881ab0698e4e6ea235245f22832860544f17ba386442fe7e9d629f8cbedf87 +ARG SHELLCHECK_SHA256_ARM64=324a7e89de8fa2aed0d0c28f3dab59cf84c6d74264022c00c22af665ed1a09bb RUN set -ex \ - && wget --quiet "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" \ - && sha256sum --check --status <<< "${SHELLCHECK_SHA256} shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" \ - && tar -xJf "shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" \ + && if [ "$TARGETARCH" = "arm64" ]; then arch=aarch64; pkg="shellcheck-v${SHELLCHECK_VERSION}.linux.${arch}.tar.xz"; sha="${SHELLCHECK_SHA256_ARM64}"; else arch=x86_64; pkg="shellcheck-v${SHELLCHECK_VERSION}.linux.${arch}.tar.xz"; sha="${SHELLCHECK_SHA256}"; fi \ + && wget --quiet "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/${pkg}" \ + && echo "${sha} ${pkg}" | sha256sum -c - \ + && tar -xJf "${pkg}" \ && cp "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" /usr/bin/shellcheck \ - && rm "shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" \ - && rm -rf "shellcheck-v${SHELLCHECK_VERSION}" \ + && rm -f "${pkg}" && rm -rf "shellcheck-v${SHELLCHECK_VERSION}" \ && shellcheck --version # Install hashicorp vault ARG VAULT_VERSION=1.12.1 ARG VAULT_SHA256=839fa81eacd250e0b0298e518751a792cd5d7194650af78cf5da74d7b7b1e5fb +ARG VAULT_SHA256_ARM64=f583cdd21ed1fdc99ec50f5400e79ebc723ed3ce92d2d1d42490cff9143ed693 RUN set -ex \ - && wget --quiet "https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip" \ - && sha256sum --check --status <<< "${VAULT_SHA256} vault_${VAULT_VERSION}_linux_amd64.zip" \ - && unzip "vault_${VAULT_VERSION}_linux_amd64.zip" \ + && if [ "$TARGETARCH" = "arm64" ]; then vault_arch=arm64; vault_sha="${VAULT_SHA256_ARM64}"; else vault_arch=amd64; vault_sha="${VAULT_SHA256}"; fi \ + && wget --quiet "https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_${vault_arch}.zip" \ + && echo "${vault_sha} vault_${VAULT_VERSION}_linux_${vault_arch}.zip" | sha256sum -c - \ + && unzip "vault_${VAULT_VERSION}_linux_${vault_arch}.zip" \ && strip "vault" \ && mv "vault" /usr/bin/vault \ - && rm "vault_${VAULT_VERSION}_linux_amd64.zip" \ + && rm "vault_${VAULT_VERSION}_linux_${vault_arch}.zip" \ && vault --version # Add python development tooling. If these versions have to change check for