Skip to content

Commit

Permalink
Multi-arch build support (#471)
Browse files Browse the repository at this point in the history
* Multiarc support

* Saving artifacts script edit
  • Loading branch information
halim-lee authored Mar 29, 2023
1 parent a79ca2a commit 2232aac
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 37 deletions.
113 changes: 79 additions & 34 deletions .one-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,54 +136,98 @@ containerize:
set -x
fi
# Download Go
GO_VERSION=$(get_env go-version)
if [[ -z "${GO_VERSION}" ]]; then
GO_VERSION="$(grep '^go [0-9]\+.[0-9]\+' go.mod | cut -d ' ' -f 2)"
fi
rm -rf /usr/local/go && wget --no-verbose --header "Accept: application/octet-stream" "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O - | tar -xz -C /usr/local/
## Setup required tooling
make setup-go GO_RELEASE_VERSION=$(get_env go-version)
export PATH=$PATH:/usr/local/go/bin
yum -y -q update
apt-get update
apt-get -qq -y install build-essential software-properties-common uidmap
skopeo --version
# Build images
# PERIODIC_SCAN=$(get_env periodic-rescan)
# PERIODIC_SCAN="$(echo "$PERIODIC_SCAN" | tr '[:upper:]' '[:lower:]')"
# Build images
export RELEASE_TARGET=$(get_env branch)
export PIPELINE_USERNAME=$(get_env ibmcloud-api-user)
export PIPELINE_PASSWORD=$(get_env ibmcloud-api-key-staging)
PIPELINE_REGISTRY=$(get_env pipeline-registry)
PIPELINE_OPERATOR_IMAGE=$(get_env pipeline-operator-image)
export PIPELINE_PASSWORD=$(get_env ibmcloud-api-key-staging)
export PIPELINE_REGISTRY=$(get_env pipeline-registry)
export PIPELINE_OPERATOR_IMAGE=$(get_env pipeline-operator-image)
export PIPELINE_PRODUCTION_IMAGE=$PIPELINE_REGISTRY/$PIPELINE_OPERATOR_IMAGE
export REDHAT_BASE_IMAGE=$(get_env redhat-base-image)
export OPM_VERSION=$(get_env opm-version)
export DISABLE_ARTIFACTORY=$(get_env disable-artifactory)
# export REDHAT_USERNAME=$(get_env redhat-user-id)
# export REDHAT_PASSWORD=$(get_env redhat-password)
# export REDHAT_REGISTRY=$(get_env redhat-registry)
# export W3_USERNAME=$(get_env w3_username)
# export W3_PASSWORD=$(get_env w3_password)
# flags for P and/or Z
export arch=$(get_env architecture)
git clone https://$(get_env git-token)@github.ibm.com/websphere/operators.git
cp -rf operators/scripts/build ./scripts/
# Temporary catalog build scripts (registry mirror to be done)
cp ./scripts/build-catalog.sh ./scripts/build/build-catalog.sh
echo "skopeo version"
skopeo --version || exit 1
# Docker login and setup build configurations
scripts/build/build-initialize.sh
# Build amd64 image
make build-pipeline-releases
# Build ppc64le and s390x images
#./scripts/pipeline/launch-travis.sh -t $(get_env travis-token) -r "https://github.com/application-stacks/runtime-component-operator" -b $(get_env branch) -l
make build-operator-pipeline REGISTRY=${PIPELINE_REGISTRY}
# Build manifest
make build-pipeline-manifest
make build-manifest-pipeline REGISTRY=${PIPELINE_REGISTRY} IMAGE=${PIPELINE_OPERATOR_IMAGE}
# Build bundle image
# ./scripts/pipeline/launch-catalog-build.sh -t $(get_env travis-token) -r "https://github.com/application-stacks/runtime-component-operator" -b $(get_env branch) -l
make install-opm
make bundle-pipeline-releases RELEASE_TARGET=${RELEASE_TARGET}
# Save artifacts
declare -a tags=("${RELEASE_TARGET}" "${RELEASE_TARGET}-amd64")
make build-bundle-pipeline REGISTRY=${PIPELINE_REGISTRY}
# Build catalog image
make build-catalog-pipeline REGISTRY=${PIPELINE_REGISTRY}
# Build catalog manifest
make build-manifest-pipeline REGISTRY=${PIPELINE_REGISTRY} IMAGE=${PIPELINE_OPERATOR_IMAGE}-catalog
echo "**** Saving Artifacts ****"
if [[ "$arch" == "ZXP" ]]; then
declare -a tags=("${RELEASE_TARGET}" "${RELEASE_TARGET}-amd64" "${RELEASE_TARGET}-ppc64le" "${RELEASE_TARGET}-s390x")
else
declare -a tags=("${RELEASE_TARGET}" "${RELEASE_TARGET}-amd64")
fi
for i in "${tags[@]}"
do
IMAGE=$PIPELINE_REGISTRY/$PIPELINE_OPERATOR_IMAGE:$i
DIGEST="$(skopeo inspect docker://$IMAGE | grep Digest | grep -o 'sha[^\"]*')"
ARCH=$(echo $i | cut -d'-' -f 2)
echo "Saving artifact $i name=$IMAGE digest=$DIGEST"
save_artifact $i type=image name="$IMAGE" "digest=$DIGEST" "arch=$ARCH"
{ ARCH="$(echo $i | grep -o '\(amd64\|s390x\|ppc64le\)$')" && TYPE="image"; } || { TYPE="manifest"; }
if [[ "$TYPE" == "manifest" ]]; then
echo "Saving artifact operator-$i type=$TYPE name=$IMAGE digest=$DIGEST"
save_artifact operator-$i type=$TYPE name="$IMAGE" "digest=$DIGEST"
else
echo "Saving artifact operator-$i type=$TYPE name=$IMAGE digest=$DIGEST arch=$ARCH"
save_artifact operator-$i type=$TYPE name="$IMAGE" "digest=$DIGEST" "arch=$ARCH"
fi
done
declare -a catalogs=("catalog-${RELEASE_TARGET}")
for i in "${catalogs[@]}"
IMAGE=$PIPELINE_REGISTRY/$PIPELINE_OPERATOR_IMAGE-bundle:${RELEASE_TARGET}
DIGEST="$(skopeo inspect docker://$IMAGE | grep Digest | grep -o 'sha[^\"]*')"
echo "Saving artifact bundle-${RELEASE_TARGET} name=$IMAGE digest=$DIGEST"
save_artifact bundle-${RELEASE_TARGET} type=image name="$IMAGE" "digest=$DIGEST"
for i in "${tags[@]}"
do
IMAGE=$PIPELINE_REGISTRY/$PIPELINE_OPERATOR_IMAGE:$i
IMAGE=$PIPELINE_REGISTRY/$PIPELINE_OPERATOR_IMAGE-catalog:$i
DIGEST="$(skopeo inspect docker://$IMAGE | grep Digest | grep -o 'sha[^\"]*')"
#ARCH=$(echo $i | cut -d'-' -f 2)
ARCH=amd64
echo "Saving artifact $i name=$IMAGE digest=$DIGEST"
save_artifact $i type=image name="$IMAGE" "digest=$DIGEST" "arch=$ARCH"
{ ARCH="$(echo $i | grep -o '\(amd64\|s390x\|ppc64le\)$')" && TYPE="image"; } || { ARCH="amd64" && TYPE="manifest"; }
if [[ "$TYPE" == "manifest" ]]; then
echo "Saving artifact catalog-$i type=$TYPE name=$IMAGE digest=$DIGEST"
save_artifact catalog-$i type=$TYPE name="$IMAGE" "digest=$DIGEST"
else
echo "Saving artifact catalog-$i type=$TYPE name=$IMAGE digest=$DIGEST arch=$ARCH"
save_artifact catalog-$i type=$TYPE name="$IMAGE" "digest=$DIGEST" "arch=$ARCH"
fi
done
# echo "whitesource scan"
Expand Down Expand Up @@ -265,6 +309,7 @@ acceptance-test:
echo "Skipping acceptance-test, SKIP_KIND_E2E_TEST=$SKIP_KIND_E2E_TEST"
exit 0
fi
# Download and configure golang
GO_VERSION=$(get_env go-version)
if [[ -z "${GO_VERSION}" ]]; then
Expand Down
4 changes: 1 addition & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Build the manager binary
FROM golang:1.19 as builder

ARG GO_ARCH=amd64

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
Expand All @@ -21,7 +19,7 @@ COPY common/ common/
COPY utils/ utils/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$GO_ARCH GO111MODULE=on go build -ldflags="-s -w" -mod vendor -a -o manager main.go
RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -ldflags="-s -w" -mod vendor -a -o manager main.go


#Build final image
Expand Down
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,20 @@ catalog-push: ## Push a catalog image.

dev:
./scripts/dev.sh all

## Multi-Arch changes
.PHONY: setup-go
setup-go: ## Ensure Go is installed.
./scripts/installers/install-go.sh ${GO_RELEASE_VERSION}

build-operator-pipeline:
./scripts/build/build-operator.sh --registry "${REGISTRY}" --image "${PIPELINE_OPERATOR_IMAGE}" --tag "${RELEASE_TARGET}"

build-manifest-pipeline:
./scripts/build/build-manifest.sh --registry "${REGISTRY}" --image "${IMAGE}" --tag "${RELEASE_TARGET}"

build-bundle-pipeline:
./scripts/build/build-bundle.sh --prod-image "${PIPELINE_PRODUCTION_IMAGE}" --registry "${REGISTRY}" --image "${PIPELINE_OPERATOR_IMAGE}" --tag "${RELEASE_TARGET}"

build-catalog-pipeline: opm ## Build a catalog image.
./scripts/build/build-catalog.sh -n "v${OPM_VERSION}" -b "${REDHAT_BASE_IMAGE}" -o "${OPM}" --container-tool "docker" -r "${REGISTRY}" -i "${PIPELINE_OPERATOR_IMAGE}-bundle:${RELEASE_TARGET}" -p "${PIPELINE_PRODUCTION_IMAGE}-bundle" -a "${PIPELINE_OPERATOR_IMAGE}-catalog:${RELEASE_TARGET}" -t "${PWD}/operator-build" -v "${VERSION}"
149 changes: 149 additions & 0 deletions scripts/build-catalog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/bin/bash

#########################################################################################
#
#
# Script to build the multi arch images for catalog
# Note: Assumed to run under <operator root>/scripts
#
#
#########################################################################################

set -Eeo pipefail

OPM_TOOL="opm"
CONTAINER_TOOL="docker"

main() {
parse_arguments "$@"
build_catalog
}

usage() {
script_name=`basename ${0}`
echo "Usage: ${script_name} [OPTIONS]"
echo " -n, --opm-version [REQUIRED] Version of opm (e.g. v4.5)"
echo " -b, --base-image [REQUIRED] The base image that the index will be built upon (e.g. registry.redhat.io/openshift4/ose-operator-registry)"
echo " -t, --output [REQUIRED] The location where the database should be output"
echo " -i, --image-name [REQUIRED] The bundle image name"
echo " -p, --prod-image [REQUIRED] The name of the production image the bundle should point to"
echo " -a, --catalog-image-name [REQUIRED] the catalog image name"
echo " -r, --registry Registry to push the image to"
echo " -c, --container-tool Tool to build image [docker, podman] (default 'docker')"
echo " -o, --opm-tool Name of the opm tool (default 'opm')"
echo " -h, --help Display this help and exit"
echo " -v, --current-version Identifies the current version of this operator"
exit 0
}


function parse_arguments() {
if [[ "$#" == 0 ]]; then
usage
exit 1
fi

# process options
while [[ "$1" != "" ]]; do
case "$1" in
-c | --container-tool)
shift
CONTAINER_TOOL=$1
;;
-o | --opm-tool)
shift
OPM_TOOL=$1
;;
-n | --opm-version)
shift
OPM_VERSION=$1
;;
-b | --base-image)
shift
BASE_INDEX_IMG=$1
;;
-d | --directory)
shift
BASE_MANIFESTS_DIR=$1
;;
-r | --registry)
shift
REGISTRY=$1
echo "$REGISTRY"
;;
-i | --image-name)
shift
BUNDLE_IMAGE=$1
;;
-p | --prod-image)
shift
PROD_IMAGE=$1
;;
-a | --catalog-image-name)
shift
CATALOG_IMAGE=$1
;;
-h | --help)
usage
exit 1
;;
-t | --output)
shift
TMP_DIR=$1
;;
-v | --current-version)
shift
CURRENT_VERSION=$1
;;
esac
shift
done
}

function build_catalog() {
echo "------------ Start of catalog-build ----------------"

##################################################################################
## The catalog index build will eventually require building a bundles.db file that
## includes all previous versions of the operator. For now, that is not a requirement.
## When the time comes that another version is released and there is a need to include
## multiple versions of this operator, changes will be needed in this script. See
## https://github.ibm.com/websphere/automation-operator/blob/main/ci/build-operator.sh
## for an example on how this is done.
##################################################################################

## Define current arch variable
case "$(uname -p)" in
"ppc64le")
readonly arch="ppc64le"
;;
"s390x")
readonly arch="s390x"
;;
*)
readonly arch="amd64"
;;
esac

CATALOG_IMAGE_ARCH="${REGISTRY}/${CATALOG_IMAGE}-$arch"

# Build catalog image
echo "*** Building $CATALOG_IMAGE_ARCH"
${OPM_TOOL} index add --bundles "${REGISTRY}/${BUNDLE_IMAGE}" --tag "${CATALOG_IMAGE_ARCH}" -c docker
if [ "$?" != "0" ]; then
echo "Error building catalog image: $CATALOG_IMAGE_ARCH"
exit 1
fi

# Push catalog image
make catalog-push CATALOG_IMG="${CATALOG_IMAGE_ARCH}"
if [ "$?" != "0" ]; then
echo "Error pushing catalog image: $CATALOG_IMAGE_ARCH"
exit 1
fi

}

# --- Run ---

main $*
37 changes: 37 additions & 0 deletions scripts/installers/install-go.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

set -o errexit
set -o nounset

main() {
DEFAULT_RELEASE_VERSION="$(grep '^go [0-9]\+.[0-9]\+' go.mod | cut -d ' ' -f 2)"
RELEASE_VERSION=${1:-$DEFAULT_RELEASE_VERSION}

if [[ -x "$(command -v go)" ]]; then
if go version | grep -q "$RELEASE_VERSION"; then
go version
exit 0
else
echo "****** Another go version detected"
fi
fi

if [[ "$(uname)" = "Darwin" ]]; then
binary_url="https://golang.org/dl/go${RELEASE_VERSION}.darwin-amd64.tar.gz"
elif [[ "$(uname -p)" = "s390x" ]]; then
binary_url="https://golang.org/dl/go${RELEASE_VERSION}.linux-s390x.tar.gz"
elif [[ "$(uname -p)" = "ppc64le" ]]; then
binary_url="https://golang.org/dl/go${RELEASE_VERSION}.linux-ppc64le.tar.gz"
else
binary_url="https://golang.org/dl/go${RELEASE_VERSION}.linux-amd64.tar.gz"
fi

echo "****** Installing Go version $RELEASE_VERSION on $(uname)"

rm -rf /usr/local/go && wget --no-verbose --header "Accept: application/octet-stream" "${binary_url}" -O - | tar -xz -C /usr/local/
export PATH=$PATH:/usr/local/go/bin

go version
}

main "$@"

0 comments on commit 2232aac

Please sign in to comment.