From 815ffbd616752eb4e0aa8028b374bbb1fdfb0a32 Mon Sep 17 00:00:00 2001 From: Raphanus Lo Date: Mon, 3 Feb 2025 14:56:00 +0800 Subject: [PATCH] feat: self-contained container image build Signed-off-by: Raphanus Lo --- .github/workflows/build.yml | 94 +++++++++++++++++-------------------- Makefile | 21 +++++++++ package/Dockerfile | 15 +++++- scripts/package | 53 ++++++++++++++++----- 4 files changed, 119 insertions(+), 64 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79eb1b40..136057d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,10 +11,47 @@ jobs: build: name: Build binaries runs-on: ubuntu-latest + outputs: + version_major: ${{ steps.build_info.outputs.version_major }} + version_minor: ${{ steps.build_info.outputs.version_minor }} + version_build: ${{ steps.build_info.outputs.version_build }} + image_tag: ${{ steps.build_info.outputs.image_tag }} + steps: - name: Checkout code uses: actions/checkout@v4 + - id: build_info + name: Declare build info + run: | + version_major='' + version_minor='' + version_build='' + image_tag='' + + ref=${{ github.ref }} + if [[ "$ref" =~ 'refs/tags/' ]]; then + version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref ) + version_major=$(cut -d. -f1 <<<$version) + version_minor=$(cut -d. -f2 <<<$version) + version_build=$(cut -d. -f3 <<<$version) + image_tag="$version" + elif [[ "$ref" =~ 'refs/heads/' ]]; then + image_tag=${{ env.branch }}-head + fi + + echo "version_major=${version_major}" >>$GITHUB_OUTPUT + echo "version_minor=${version_minor}" >>$GITHUB_OUTPUT + echo "version_build=${version_build}" >>$GITHUB_OUTPUT + echo "image_tag=${image_tag}" >>$GITHUB_OUTPUT + + cat <> "$GITHUB_ENV" - - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - # longhornio/backing-image-manager image - - name: docker-publish - if: ${{ startsWith(github.ref, 'refs/heads/') }} - uses: docker/build-push-action@v5 - with: - context: ./ - push: true - platforms: linux/amd64,linux/arm64 - tags: longhornio/backing-image-manager:${{ env.branch }}-head - file: package/Dockerfile - sbom: true - - - name: docker-publish-with-tag - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: docker/build-push-action@v5 - with: - context: ./ - push: true - platforms: linux/amd64,linux/arm64 - tags: longhornio/backing-image-manager:${{ github.ref_name }} - file: package/Dockerfile - sbom: true + - name: Build and publish image + env: + REPO: docker.io/longhornio + TAG: ${{ needs.build.outputs.image_tag }} + run: make workflow-image-build-push diff --git a/Makefile b/Makefile index d7d72a16..414acaa8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,9 @@ TARGETS := $(shell ls scripts) +MACHINE := rancher +# Define the target platforms that can be used across the ecosystem. +# Note that what would actually be used for a given project will be +# defined in TARGET_PLATFORMS, and must be a subset of the below: +DEFAULT_PLATFORMS := linux/amd64,linux/arm64,darwin/arm64,darwin/amd64 .dapper: @echo Downloading dapper @@ -10,6 +15,22 @@ TARGETS := $(shell ls scripts) $(TARGETS): .dapper ./.dapper $@ +.PHONY: buildx-machine +buildx-machine: + docker buildx ls | grep $(MACHINE) >/dev/null || \ + docker buildx create --name=$(MACHINE) --platform=$(DEFAULT_PLATFORMS) + +# variables needed from GHA caller: +# - REPO: image repo, include $registry/$repo_path +# - TAG: image tag +# - TARGET_PLATFORMS: optional, to be passed for buildx's --platform option +# - IID_FILE_FLAG: optional, options to generate image ID file +.PHONY: workflow-image-build-push workflow-image-build-push-secure +workflow-image-build-push: buildx-machine + MACHINE=$(MACHINE) OUTPUT_ARGS='--push' bash scripts/package +workflow-image-build-push-secure: buildx-machine + MACHINE=$(MACHINE) OUTPUT_ARGS='--push' IS_SECURE=true bash scripts/package + trash: .dapper ./.dapper -m bind trash diff --git a/package/Dockerfile b/package/Dockerfile index 4f2e6e5d..3cd92fca 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -1,4 +1,16 @@ # syntax=docker/dockerfile:1.13.0 +FROM registry.suse.com/bci/golang:1.23 AS builder + +WORKDIR /app + +# Copy the build script and source code +COPY . /app + +# Make the build script executable +RUN chmod +x /app/scripts/build + +# Run the build script +RUN /app/scripts/build FROM registry.suse.com/bci/bci-base:15.6 @@ -20,7 +32,8 @@ RUN zypper -n install kmod curl wget nfs-client nfs4-acl-tools fuse \ librdmacm1 librdmacm-utils libibverbs perl-Config-General libaio-devel sg3_utils \ iputils telnet iperf qemu-tools iproute2 e2fsprogs e2fsprogs-devel xfsprogs xfsprogs-devel -COPY package/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager +COPY --from=builder /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager +RUN chmod +x /usr/local/bin/backing-image-manager VOLUME /usr/local/bin diff --git a/scripts/package b/scripts/package index bc8d9e7e..3a5bdcc8 100755 --- a/scripts/package +++ b/scripts/package @@ -5,21 +5,52 @@ source $(dirname $0)/version cd $(dirname $0)/.. -PROJECT=`basename "$PWD"` +project=$(basename "$PWD") -if [ ! -x ./bin/longhorn ]; then - ./scripts/build +command -v buildx >/dev/null && build_cmd=(buildx) || build_cmd=(docker buildx) + +# read configurable parameters +REPO=${REPO:-longhornio} +IMAGE_NAME=${IMAGE_NAME:-$project} +TAG=${TAG:-''} +OUTPUT_ARGS=${OUTPUT_ARGS:-'--load'} +IS_SECURE=${IS_SECURE:-'false'} +MACHINE=${MACHINE:-''} +TARGET_PLATFORMS=${TARGET_PLATFORMS:-''} +IID_FILE=${IID_FILE:-''} +IID_FILE_FLAG=${IID_FILE_FLAG:-''} + +if [[ -z $TAG ]]; then + if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then + TAG="v${api_version}_$(date -u +%Y%m%d)" + else + TAG="unknown_$(date -u +%Y%m%d)" + fi fi -cp -r bin package/ +image="${REPO}/${IMAGE_NAME}:${TAG}" -APIVERSION=`./bin/backing-image-manager version --client-only|jq ".clientVersion.backingImageManagerAPIVersion"` -TAG="v${APIVERSION}_`date -u +%Y%m%d`" -REPO=${REPO:-longhornio} -IMAGE=${REPO}/${PROJECT}:${TAG} +builder_args=() +[[ $MACHINE ]] && builder_args+=('--builder' "$MACHINE") + +IFS=' ' read -r -a iid_file_args <<<"$IID_FILE_FLAG" +[[ -n "$IID_FILE" && ${#iid_file_args} == 0 ]] && iid_file_args=('--iidfile' "$IID_FILE") + +IFS=' ' read -r -a buildx_args <<<"$OUTPUT_ARGS" +[[ $IS_SECURE == 'true' ]] && buildx_args+=('--sbom=true' '--attest' 'type=provenance,mode=max') +[[ $TARGET_PLATFORMS ]] && buildx_args+=('--platform' "$TARGET_PLATFORMS") -buildx build --load --no-cache -t ${IMAGE} -f package/Dockerfile . +echo "${build_cmd[@]}" build --no-cache \ + "${builder_args[@]}" \ + "${iid_file_args[@]}" \ + "${buildx_args[@]}" \ + -t "$image" -f package/Dockerfile . +"${build_cmd[@]}" build --no-cache \ + "${builder_args[@]}" \ + "${iid_file_args[@]}" \ + "${buildx_args[@]}" \ + -t "$image" -f package/Dockerfile . -echo Built ${IMAGE} +echo "Built $image" -echo ${IMAGE} > ./bin/latest_image +echo "$image" > ./bin/latest_image