diff --git a/.github/workflows/next-build.yml b/.github/workflows/next-build.yml index 2dfebbe33..e28666978 100644 --- a/.github/workflows/next-build.yml +++ b/.github/workflows/next-build.yml @@ -183,6 +183,7 @@ jobs: --bundle-tag ${DWO_BUNDLE_TAG} \ --index-image ${DWO_INDEX_IMG} \ --container-tool docker \ + --multi-arch \ --debug \ --force @@ -193,11 +194,13 @@ jobs: --render ./olm-catalog/next-digest/ \ --push "${DWO_BUNDLE_REPO}:${DWO_DIGEST_BUNDLE_TAG}" \ --container-tool docker \ + --multi-arch \ --debug cp ./olm-catalog/next/{channel,package}.yaml ./olm-catalog/next-digest - docker build . -t ${DWO_DIGEST_INDEX_IMG} -f build/index.next-digest.Dockerfile - docker push ${DWO_DIGEST_INDEX_IMG} + docker buildx build . -t ${DWO_DIGEST_INDEX_IMG} -f build/index.next-digest.Dockerfile \ + --platform linux/amd64,linux/arm64,linux/ppc64le,linux/s390x \ + --push git restore ./olm-catalog/ git clean -fd ./olm-catalog/ diff --git a/build/buildkitd.toml b/build/buildkitd.toml new file mode 100644 index 000000000..f6dc45486 --- /dev/null +++ b/build/buildkitd.toml @@ -0,0 +1,2 @@ +[worker.oci] + max-parallelism = 1 diff --git a/build/scripts/build_digests_bundle.sh b/build/scripts/build_digests_bundle.sh index 247ea4124..e99d02892 100755 --- a/build/scripts/build_digests_bundle.sh +++ b/build/scripts/build_digests_bundle.sh @@ -3,8 +3,12 @@ set -eo pipefail PODMAN=podman +MULTI_ARCH="false" +ARCHITECTURES="linux/amd64,linux/arm64,linux/ppc64le,linux/s390x" SCRIPT_DIR=$(cd "$(dirname "$0")" || exit; pwd) +DEFAULT_BUILDER_NAME="dwo-multi-platform-builder" + usage() { cat < : Push processed digests bundle to (required). Pushing the bundle image to a repository is required because opm render works from a remote repository. --container-tool : Use specific container tool for building/pushing images (default: use podman). + --multi-arch : Create images for the following architectures: $ARCHITECTURES. Note: Docker buildx will be + used for building and pushing the images, instead of the container tool selected with --container-tool. --debug, -d : Print debug information. --help, -h : Show this message. EOF @@ -51,6 +57,7 @@ parse_args() { '--render') RENDER="$2"; shift;; '--push') PUSH_IMAGE="$2"; shift;; '--container-tool') PODMAN="$2"; shift;; + '--multi-arch') MULTI_ARCH="true";; '-d'|'--debug') DEBUG="true";; '-h'|'--help') usage; exit 0;; *) error "Unknown parameter is used: $1."; usage; exit 1;; @@ -81,6 +88,19 @@ preflight() { parse_args "$@" preflight +if [ "$MULTI_ARCH" == "true" ]; then + # Create a multi-arch builder if one doesn't already exist + BUILDER_EXISTS=0 + docker buildx use "$DEFAULT_BUILDER_NAME" || BUILDER_EXISTS=$? + + if [ $BUILDER_EXISTS -eq 0 ]; then + echo "Using $DEFAULT_BUILDER_NAME for build" + else + echo "Setting up Docker buildx builder:" + docker buildx create --name "$DEFAULT_BUILDER_NAME" --driver docker-container --config build/buildkitd.toml --use + fi +fi + # Work in a temporary directory TMPDIR="$(mktemp -d)" info "Working in $TMPDIR" @@ -125,10 +145,17 @@ if [ "$DEBUG" == true ]; then cat "${PROCESSED_DIR}/bundle.Dockerfile" | sed 's|^| |g' fi -info "Building bundle $PUSH_IMAGE" -$PODMAN build -t "$PUSH_IMAGE" -f "${PROCESSED_DIR}/bundle.Dockerfile" "$PROCESSED_DIR" | sed 's|^| |g' -info "Pushing bundle $PUSH_IMAGE" -$PODMAN push "$PUSH_IMAGE" 2>&1 | sed 's|^| |g' +if [ "$MULTI_ARCH" == "true" ]; then + info "Building and pushing bundle $PUSH_IMAGE" + docker buildx build -t "$PUSH_IMAGE" -f "${PROCESSED_DIR}/bundle.Dockerfile" "$PROCESSED_DIR" \ + --platform "$ARCHITECTURES" \ + --push 2>&1 | sed 's|^| |g' +else + info "Building bundle $PUSH_IMAGE" + $PODMAN build -t "$PUSH_IMAGE" -f "${PROCESSED_DIR}/bundle.Dockerfile" "$PROCESSED_DIR" | sed 's|^| |g' + info "Pushing bundle $PUSH_IMAGE" + $PODMAN push "$PUSH_IMAGE" 2>&1 | sed 's|^| |g' +fi NEW_BUNDLE_SHA=$(skopeo inspect "docker://${PUSH_IMAGE}" | jq -r '.Digest') NEW_BUNDLE_DIGEST="${PUSH_IMAGE%%:*}@${NEW_BUNDLE_SHA}" diff --git a/build/scripts/build_index_image.sh b/build/scripts/build_index_image.sh index 4afe5120b..20596b2b3 100755 --- a/build/scripts/build_index_image.sh +++ b/build/scripts/build_index_image.sh @@ -4,12 +4,15 @@ set -e PODMAN=podman FORCE="false" +MULTI_ARCH="false" +ARCHITECTURES="linux/amd64,linux/arm64,linux/ppc64le,linux/s390x" DEBUG="false" DEFAULT_BUNDLE_REPO="quay.io/devfile/devworkspace-operator-bundle" DEFAULT_BUNDLE_TAG="next" DEFAULT_INDEX_IMAGE="quay.io/devfile/devworkspace-operator-index:next" DEFAULT_RELEASE_INDEX_IMAGE="quay.io/devfile/devworkspace-operator-index:release" +DEFAULT_BUILDER_NAME="dwo-multi-platform-builder" error() { echo "[ERROR] $1" @@ -36,6 +39,9 @@ Arguments: --container-tool : Use specific container tool for building/pushing images (default: use podman) --force : Do not prompt for confirmation if pushing to default repos. Intended for use in CI. + --multi-arch : Create images for the following architectures: $ARCHITECTURES. Note: Docker + buildx will be used for building and pushing the images, instead of + the container tool selected with --container-tool. --debug : Don't do any normal cleanup on exit, leaving repo in dirty state Examples: @@ -56,6 +62,7 @@ parse_args() { '--container-tool') PODMAN="$2"; shift 1;; '--release') RELEASE="true";; '--force') FORCE="true";; + '--multi-arch') MULTI_ARCH="true";; '--debug') DEBUG="true";; *) echo "[ERROR] Unknown parameter is used: $1."; usage; exit 1;; esac @@ -65,6 +72,19 @@ parse_args() { parse_args "$@" +if [ "$MULTI_ARCH" == "true" ]; then + # Create a multi-arch builder if one doesn't already exist + BUILDER_EXISTS=0 + docker buildx use "$DEFAULT_BUILDER_NAME" || BUILDER_EXISTS=$? + + if [ $BUILDER_EXISTS -eq 0 ]; then + echo "Using $DEFAULT_BUILDER_NAME for build" + else + echo "Setting up Docker buildx builder:" + docker buildx create --name "$DEFAULT_BUILDER_NAME" --driver docker-container --config build/buildkitd.toml --use + fi +fi + if [ "$RELEASE" == "true" ]; then # Set up for release and check arguments BUNDLE_REPO="${BUNDLE_REPO:-DEFAULT_BUNDLE_REPO}" @@ -118,8 +138,15 @@ fi make generate_olm_bundle_yaml echo "Building bundle image $BUNDLE_IMAGE" -$PODMAN build . -t "$BUNDLE_IMAGE" -f build/bundle.Dockerfile -$PODMAN push "$BUNDLE_IMAGE" 2>&1 +if [ "$MULTI_ARCH" == "true" ]; then + docker buildx build . -t "$BUNDLE_IMAGE" -f build/bundle.Dockerfile \ + --platform "$ARCHITECTURES" \ + --push +else + $PODMAN build . -t "$BUNDLE_IMAGE" -f build/bundle.Dockerfile + $PODMAN push "$BUNDLE_IMAGE" 2>&1 +fi + BUNDLE_SHA=$(skopeo inspect "docker://${BUNDLE_IMAGE}" | jq -r '.Digest') BUNDLE_DIGEST="${BUNDLE_REPO}@${BUNDLE_SHA}" @@ -177,8 +204,15 @@ opm validate "$OUTDIR" # Build index container echo "Building index image $INDEX_IMAGE" -$PODMAN build . -t "$INDEX_IMAGE" -f "$DOCKERFILE" -$PODMAN push "$INDEX_IMAGE" 2>&1 +if [ "$MULTI_ARCH" == "true" ]; then + docker buildx build . -t "$INDEX_IMAGE" -f "$DOCKERFILE" \ + --platform "$ARCHITECTURES" \ + --push +else + $PODMAN build . -t "$INDEX_IMAGE" -f "$DOCKERFILE" + $PODMAN push "$INDEX_IMAGE" 2>&1 +fi + if [ $DEBUG != "true" ] && [ "$RELEASE" != "true" ]; then echo "Cleaning up"