From 7a7a37c29e67b0c37e75552f71ce378b87f05cca Mon Sep 17 00:00:00 2001 From: Rehan Khan Date: Wed, 6 Nov 2024 11:47:45 +0530 Subject: [PATCH] Made changes to build images using buildah Signed-off-by: Rehan Khan --- .github/workflows/build-images.yaml | 97 +++++++++++++++++++++++++---- make/catalog.mk | 25 +++----- script/build_catalog.sh | 43 ------------- utils/create-manifest.sh | 37 +++++++++++ 4 files changed, 131 insertions(+), 71 deletions(-) delete mode 100755 script/build_catalog.sh create mode 100755 utils/create-manifest.sh diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml index 831d2df3..f1fce3c3 100644 --- a/.github/workflows/build-images.yaml +++ b/.github/workflows/build-images.yaml @@ -163,6 +163,9 @@ jobs: name: Build and push catalog image needs: [build, build-bundle] runs-on: ubuntu-20.04 + strategy: + matrix: + arch: [ amd64, arm64, ppc64le, s390x ] if: github.ref_name == 'main' || startsWith(github.ref, 'refs/tags/v') # We cannot use `env.MAIN_BRANCH_NAME` because `env` context is not available to `job.if`. See https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability steps: - name: Set up Go 1.21.x @@ -170,6 +173,81 @@ jobs: with: go-version: 1.21.x id: go + - name: Check out code + uses: actions/checkout@v3 + - name: Add latest tag + if: ${{ github.ref_name == env.MAIN_BRANCH_NAME }} + id: add-latest-tag + run: | + echo "IMG_TAGS=latest-${{ matrix.arch }} ${{ env.IMG_TAGS }}" >> $GITHUB_ENV + - name: Add release tag + if: ${{ github.ref_name != env.MAIN_BRANCH_NAME }} + id: add-branch-tag + run: | + TAG_NAME=${GITHUB_REF_NAME/\//-} + echo "TAG_NAME=${TAG_NAME}" >> $GITHUB_ENV + echo "IMG_TAGS=${TAG_NAME}-${{ matrix.arch }} ${{ env.IMG_TAGS }}" >> $GITHUB_ENV + - name: Set Operator version + id: operator-version + run: | + tag=${GITHUB_REF_NAME} + if [[ ${tag} =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then + echo "VERSION=${tag#v}" >> $GITHUB_ENV + else + echo "VERSION=${{ github.sha }}" >> $GITHUB_ENV + fi + - name: Install qemu dependency + run: | + sudo apt-get update + sudo apt-get install -y qemu-user-static + - name: Run make catalog (main) + if: ${{ github.ref_name == env.MAIN_BRANCH_NAME }} + run: | + make catalog \ + REGISTRY=${{ env.IMG_REGISTRY_HOST }} ORG=${{ env.IMG_REGISTRY_ORG }} \ + VERSION=${{ env.VERSION }} \ + IMAGE_TAG=${{ github.sha }} \ + AUTHORINO_VERSION=${{ env.LATEST_AUTHORINO_GITREF }} \ + CHANNELS=${{ inputs.channels }} \ + CATALOG_ARCH=${{ matrix.arch }} + - name: Run make catalog (release) + if: ${{ github.ref_name != env.MAIN_BRANCH_NAME }} + run: | + make catalog \ + REGISTRY=${{ env.IMG_REGISTRY_HOST }} ORG=${{ env.IMG_REGISTRY_ORG }} \ + VERSION=${{ env.VERSION }} \ + AUTHORINO_VERSION=${{ github.event.inputs.authorinoVersion }} \ + CHANNELS=${{ inputs.channels }} \ + CATALOG_ARCH=${{ matrix.arch }} + - name: Git diff + run: git diff + - name: Build Image + id: build-image + uses: redhat-actions/buildah-build@v2 + with: + image: ${{ env.OPERATOR_NAME }}-catalog + tags: ${{ env.IMG_TAGS }} + platforms: linux/${{ matrix.arch }} + context: ./catalog + dockerfiles: | + ./catalog/${{ env.OPERATOR_NAME }}-catalog.Dockerfile + - name: Push Image + if: ${{ !env.ACT }} + id: push-to-quay + uses: redhat-actions/push-to-registry@v2 + with: + image: ${{ steps.build-image.outputs.image }} + tags: ${{ steps.build-image.outputs.tags }} + registry: ${{ env.IMG_REGISTRY_HOST }}/${{ env.IMG_REGISTRY_ORG }} + username: ${{ secrets.IMG_REGISTRY_USERNAME }} + password: ${{ secrets.IMG_REGISTRY_TOKEN }} + - name: Print Image URL + run: echo "Image pushed to ${{ steps.push-to-quay.outputs.registry-paths}}" + create-manifests: + name: Create and push catalog image manifests + needs: [build, build-bundle,build-catalog] + runs-on: ubuntu-20.04 + steps: - name: Check out code uses: actions/checkout@v3 - name: Add latest tag @@ -193,25 +271,18 @@ jobs: else echo "VERSION=${{ github.sha }}" >> $GITHUB_ENV fi - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Install qemu dependency + run: | + sudo apt-get update + sudo apt-get install -y qemu-user-static - name: Login to Quay.io uses: docker/login-action@v1 with: registry: ${{ env.IMG_REGISTRY_HOST }} username: ${{ secrets.IMG_REGISTRY_USERNAME }} password: ${{ secrets.IMG_REGISTRY_TOKEN }} - - name: Git diff - run: git diff - - name: build and push catalog (main) - if: ${{ github.ref_name == env.MAIN_BRANCH_NAME }} - shell: bash - env: - TAG: ${{ env.IMG_TAGS }} - run: ./script/build_catalog.sh - - name: build and push catalog (release) - if: ${{ github.ref_name != env.MAIN_BRANCH_NAME }} + - name: Creating and Pushing Manifests shell: bash env: TAG: ${{ env.IMG_TAGS }} - run: ./script/build_catalog.sh \ No newline at end of file + run: ./utils/create-manifest.sh \ No newline at end of file diff --git a/make/catalog.mk b/make/catalog.mk index c7068a24..72e90312 100644 --- a/make/catalog.mk +++ b/make/catalog.mk @@ -3,12 +3,20 @@ # The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:$(IMAGE_TAG) +OPM_DOCKERFILE_VERSION ?= 1.28.0 + +ifeq ($(origin CATALOG_ARCH),undefined) +OPM_DOCKERFILE_TAG = latest +else +OPM_DOCKERFILE_TAG = v$(OPM_DOCKERFILE_VERSION)-$(CATALOG_ARCH) +endif + CATALOG_FILE = $(PROJECT_DIR)/catalog/authorino-operator-catalog/operator.yaml CATALOG_DOCKERFILE = $(PROJECT_DIR)/catalog/authorino-operator-catalog.Dockerfile $(CATALOG_DOCKERFILE): $(OPM) -mkdir -p $(PROJECT_DIR)/catalog/authorino-operator-catalog - cd $(PROJECT_DIR)/catalog && $(OPM) generate dockerfile authorino-operator-catalog + cd $(PROJECT_DIR)/catalog && $(OPM) generate dockerfile authorino-operator-catalog -i "quay.io/operator-framework/opm:${OPM_DOCKERFILE_TAG}" catalog-dockerfile: $(CATALOG_DOCKERFILE) ## Generate catalog dockerfile. $(CATALOG_FILE): $(OPM) $(YQ) @@ -32,19 +40,6 @@ catalog: $(OPM) ## Generate catalog content and validate. $(MAKE) $(CATALOG_FILE) BUNDLE_IMG=$(BUNDLE_IMG) cd $(PROJECT_DIR)/catalog && $(OPM) validate authorino-operator-catalog -.PHONY: catalog-multiarch -catalog-multiarch: $(OPM) ## Generate catalog content using architechture specific binaries and validate. - #Initializing the Catalog - @echo "Building catalog for architecture: $(arch)" - -rm -rf $(PROJECT_DIR)/catalog/authorino-operator-catalog - -rm -rf $(PROJECT_DIR)/catalog/authorino-operator-catalog.Dockerfile - -mkdir -p $(PROJECT_DIR)/catalog/authorino-operator-catalog - cd $(PROJECT_DIR)/catalog && $(OPM) generate dockerfile authorino-operator-catalog -i "quay.io/operator-framework/opm:v1.28.0-${arch}" - @echo "creating dir" - $(MAKE) $(CATALOG_FILE) BUNDLE_IMG=$(BUNDLE_IMG) - @echo "leaving dir" - cd $(PROJECT_DIR)/catalog && $(OPM) validate authorino-operator-catalog - # Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. # Ref https://olm.operatorframework.io/docs/tasks/creating-a-catalog/#catalog-creation-with-raw-file-based-catalogs .PHONY: catalog-build @@ -62,4 +57,4 @@ deploy-catalog: $(KUSTOMIZE) $(YQ) ## Deploy operator to the K8s cluster specifi $(KUSTOMIZE) build config/deploy/olm | kubectl apply -f - undeploy-catalog: $(KUSTOMIZE) ## Undeploy controller from the K8s cluster specified in ~/.kube/config using OLM catalog image. - $(KUSTOMIZE) build config/deploy/olm | kubectl delete -f - + $(KUSTOMIZE) build config/deploy/olm | kubectl delete -f - \ No newline at end of file diff --git a/script/build_catalog.sh b/script/build_catalog.sh deleted file mode 100755 index a176f97c..00000000 --- a/script/build_catalog.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -# Builds the OLM catalog index and pushes it to quay.io. -# To push to your own registry, override the IMG_REGISTRY_HOST , IMG_REGISTRY_ORG , OPERATOR_NAME and TAG env vars, -# i.e: -# IMG_REGISTRY_HOST=quay.io IMG_REGISTRY_ORG=yourusername OPERATOR_NAME=authorino-operator TAG=latest ./script/build_catalog.sh -# -# REQUIREMENTS: -# * a valid login session to a container registry. -# * `docker` -# * `opm` - -set -e # Exit on error - -# Split tags into an array -IFS=' ' read -r -a tags <<< "$TAG" -first_tag="${tags[0]}" -architectures=(${ARCHITECTURES}) -# Build and push catalog images for each architecture -for arch in "${architectures[@]}"; do - make catalog-multiarch arch="${arch}" - image_tag="${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" - make catalog-build CATALOG_IMG="${image_tag}" - docker push "${image_tag}" & - wait -done - -# Tag and push the manifest for tags -for tag in "${tags[@]}"; do - echo "Creating manifest for $TAG" - docker manifest create --amend "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" \ - $(for arch in "${architectures[@]}"; do - echo "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" - done) - docker manifest push "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" - docker rmi "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" || true -done - - -# Clean up images -for arch in "${architectures[@]}"; do - image_tag="${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" - docker rmi "${image_tag}" || true -done \ No newline at end of file diff --git a/utils/create-manifest.sh b/utils/create-manifest.sh new file mode 100755 index 00000000..f960f1e9 --- /dev/null +++ b/utils/create-manifest.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Builds the OLM catalog index manifests and pushes it to quay.io. +# To push to your own registry, override the IMG_REGISTRY_HOST, IMG_REGISTRY_ORG, OPERATOR_NAME, and TAG env vars, +# i.e: +# IMG_REGISTRY_HOST=quay.io IMG_REGISTRY_ORG=yourusername OPERATOR_NAME=authorino-operator TAG=latest ./script/build_catalog.sh +# +set -e # Exit on error +IFS=' ' read -r -a tags <<< "$TAG" +architectures=(${ARCHITECTURES}) +first_tag="${tags[0]}" + + for arch in "${architectures[@]}"; do + # Pull the image for all the architecture + podman pull "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" + done + +for tag in "${tags[@]}"; do + echo "Creating manifest for $tag" + podman manifest create "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" + + for arch in "${architectures[@]}"; do + podman manifest add "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" "docker://${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" + podman manifest annotate "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" \ + --os "linux" \ + --arch "${arch}" + done + # Push the manifest to the repository + podman manifest push --all "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" + # Remove the manifest image after pushing + podman rmi "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${tag}" || true +done + +# Clean up images + for arch in "${architectures[@]}"; do + echo "Removing image for architecture: ${arch} and tag: ${tag}-${arch}" + podman rmi "${IMG_REGISTRY_HOST}/${IMG_REGISTRY_ORG}/${OPERATOR_NAME}-catalog:${first_tag}-${arch}" || true + done \ No newline at end of file