Skip to content

Commit

Permalink
feat: self-contained container image build
Browse files Browse the repository at this point in the history
Signed-off-by: Raphanus Lo <[email protected]>
  • Loading branch information
COLDTURNIP committed Feb 10, 2025
1 parent 39be0e6 commit e0659c2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 70 deletions.
96 changes: 45 additions & 51 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,50 @@ jobs:
build:
name: Build binaries
runs-on: ubuntu-22.04
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=''
branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
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="${branch}-head"
elif [[ "$ref" =~ 'refs/pull/' ]]; then
image_tag="pr${{ github.event.number }}"
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 <<EOF
version_major=${version_major}
version_minor=${version_minor}
version_build=${version_build}
image_tag=${image_tag}
EOF
# Build binaries
- name: Run ci
run: make ci
Expand All @@ -25,12 +65,6 @@ jobs:
flags: unittests
token: ${{ secrets.CODECOV_TOKEN }}

- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: binaries_artifact
path: ./bin/*

build_push_image:
name: Build and push image
runs-on: ubuntu-22.04
Expand All @@ -40,55 +74,15 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Download binaries
uses: actions/download-artifact@v4
with:
name: binaries_artifact
path: ./bin/

- name: Add executable permission
run: |
chmod +x ./bin/*
- name: Copy bin folder to package
run: |
cp -r ./bin ./package/
# For multi-platform support
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Declare branch
run: |
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_ENV"
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

# longhornio/longhorn-share-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/longhorn-share-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/longhorn-share-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
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
TARGETS := $(shell ls scripts)
MACHINE := longhorn
# 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

.dapper:
@echo Downloading dapper
Expand All @@ -10,6 +15,22 @@ TARGETS := $(shell ls scripts)
$(TARGETS): .dapper
./.dapper $@

.PHONY: buildx-machine
buildx-machine:
@docker buildx create --name=$(MACHINE) --platform=$(DEFAULT_PLATFORMS) 2>/dev/null || true
docker buildx inspect $(MACHINE)

# 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

.DEFAULT_GOAL := ci

.PHONY: $(TARGETS)
20 changes: 16 additions & 4 deletions package/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# syntax=docker/dockerfile:1.13.0
FROM registry.suse.com/bci/golang:1.23 AS app_builder

FROM registry.suse.com/bci/bci-base:15.6 AS build
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 AS lib_builder

RUN zypper -n ref && \
zypper update -y
Expand Down Expand Up @@ -73,9 +85,9 @@ RUN sed -i s/systemd// /etc/nsswitch.conf
# ganesha reads /etc/mtab for mounted volumes
RUN ln -sf /proc/self/mounts /etc/mtab

COPY --from=build /usr/local /usr/local/
COPY --from=build /ganesha-extra /
COPY package/bin/longhorn-share-manager-${ARCH} /longhorn-share-manager
COPY --from=lib_builder /usr/local /usr/local/
COPY --from=lib_builder /ganesha-extra /
COPY --from=app_builder /app/bin/longhorn-share-manager-${ARCH} /longhorn-share-manager

# run ldconfig after libs have been copied
RUN ldconfig
Expand Down
64 changes: 49 additions & 15 deletions scripts/package
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,59 @@ source $(dirname $0)/version

cd $(dirname $0)/..

PROJECT=`basename "$PWD"`
project=$(basename "$PWD")

if [ ! -x ./bin/longhorn ]; then
./scripts/build
fi

cp -r bin package/
command -v buildx >/dev/null && build_cmd=(buildx) || build_cmd=(docker buildx)

APIVERSION=`./bin/longhorn-share-manager version --client-only|jq ".clientVersion.apiVersion"`
TAG=${TAG:-"v${APIVERSION}_`date -u +%Y%m%d`"}
# read configurable parameters
REPO=${REPO:-longhornio}
IMAGE=${REPO}/${PROJECT}:${TAG}
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/longhorn-share-manager version --client-only | jq ".clientVersion.apiVersion"); then
TAG="v${api_version}_$(date -u +%Y%m%d)"
else
TAG="$VERSION"
fi
fi

# update base image to get latest changes
BASE_IMAGE=`grep FROM package/Dockerfile | grep -v AS | awk '{print $2}'`
docker pull ${BASE_IMAGE}
image="${REPO}/${IMAGE_NAME}:${TAG}"

builder_args=()
[[ $MACHINE ]] && builder_args+=('--builder' "$MACHINE")

buildx build --load -t ${IMAGE} -f package/Dockerfile .
IFS=' ' read -r -a iid_file_args <<<"$IID_FILE_FLAG"
[[ -n "$IID_FILE" && ${#iid_file_args} == 0 ]] && iid_file_args=('--iidfile' "$IID_FILE")

echo Built ${IMAGE}
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")

echo ${IMAGE} > ./bin/latest_image
# update base image to get latest changes
grep 'FROM.*/' package/Dockerfile | awk '{print $2}' | while read -r base_image
do
docker pull "$base_image"
done

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"

mkdir ./bin || true
echo "$image" > ./bin/latest_image

0 comments on commit e0659c2

Please sign in to comment.