harbor-arm-build/Jenkinsfile

205 lines
6.1 KiB
Groovy

pipeline {
parameters {
string(
name: 'HARBOR_VERSION',
defaultValue: '',
description: 'Harbor tag to build (e.g. v2.14.1). Leave empty to build the latest release.'
)
}
agent {
kubernetes {
label 'harbor-arm-build'
defaultContainer 'builder'
yaml """
apiVersion: v1
kind: Pod
spec:
nodeSelector:
kubernetes.io/arch: arm64
containers:
- name: builder
image: quay.io/podman/stable:v5.2
tty: true
command: ["cat"]
securityContext:
privileged: true
env:
- name: DOCKER_CONFIG
value: /root/.docker
- name: REGISTRY_AUTH_FILE
value: /root/.docker/config.json
- name: XDG_RUNTIME_DIR
value: /var/run/containers
volumeMounts:
- name: workspace-volume
mountPath: /home/jenkins/agent
- name: docker-config-secret
mountPath: /docker-config
- name: containers-storage
mountPath: /var/lib/containers
- name: podman-runtime
mountPath: /var/run/containers
volumes:
- name: docker-config-secret
secret:
secretName: harbor-robot-pipeline
items:
- key: .dockerconfigjson
path: config.json
- name: workspace-volume
emptyDir: {}
- name: containers-storage
emptyDir: {}
- name: podman-runtime
emptyDir: {}
"""
}
}
environment {
IMAGE_NAMESPACE = 'registry.bstein.dev/infra'
TAG_SUFFIX = '-arm64'
REGISTRY_URL = 'registry.bstein.dev'
}
options {
disableConcurrentBuilds()
}
stages {
stage('Checkout pipeline repo') {
steps {
git credentialsId: 'gitea-pat', url: 'https://scm.bstein.dev/bstein/harbor-arm-build.git'
}
}
stage('Setup tooling') {
steps {
container('builder') {
sh '''
set -euo pipefail
microdnf -y install git make curl tar gzip jq golang podman-docker python3
mkdir -p "${DOCKER_CONFIG}"
cp /docker-config/config.json "${DOCKER_CONFIG}/config.json"
# Make the Docker CLI invoke podman (buildah backend).
ln -sf /usr/bin/podman /usr/local/bin/docker
mkdir -p "${XDG_RUNTIME_DIR}"
'''
}
}
}
stage('Resolve version') {
steps {
container('builder') {
script {
def resolved = sh(
label: 'pick version',
returnStdout: true,
script: '''
set -euo pipefail
if [ -n "${HARBOR_VERSION:-}" ]; then
echo "${HARBOR_VERSION}"
exit 0
fi
for attempt in 1 2 3; do
version=$(curl -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'User-Agent: harbor-arm-build' \
https://api.github.com/repos/goharbor/harbor/releases/latest \
| jq -r '.tag_name // empty') || version=""
if [ -n "${version}" ]; then
echo "${version}"
exit 0
fi
sleep $((attempt * 5))
done
echo "Failed to resolve Harbor version from GitHub; set HARBOR_VERSION manually." >&2
exit 1
'''
).trim()
env.HARBOR_VERSION_RESOLVED = resolved
env.HARBOR_SRC_DIR = "harbor-src/harbor-${resolved.startsWith('v') ? resolved.substring(1) : resolved}"
}
}
}
}
stage('Fetch source') {
steps {
container('builder') {
sh """
set -euo pipefail
rm -rf harbor-src
mkdir -p harbor-src
curl -sSL "https://github.com/goharbor/harbor/archive/refs/tags/${env.HARBOR_VERSION_RESOLVED}.tar.gz" | tar xz -C harbor-src
ls -la harbor-src
"""
}
}
}
stage('Build & push (podman/buildah)') {
steps {
container('builder') {
sh '''
set -euo pipefail
VERSION_TAG="${HARBOR_VERSION_RESOLVED}${TAG_SUFFIX}.${BUILD_NUMBER}"
export VERSIONTAG="${VERSION_TAG}"
export BASEIMAGETAG="${VERSION_TAG}"
export IMAGENAMESPACE="${IMAGE_NAMESPACE}"
export BASEIMAGENAMESPACE="${IMAGE_NAMESPACE}"
export DOCKERNETWORK=host
export DOCKER_DEFAULT_PLATFORM=linux/arm64
export PULL_BASE_FROM_DOCKERHUB=false
export BUILD_BASE=true
export BUILDTRIVYADP=false
export BUILD_INSTALLER=true
export BUILDAH_ISOLATION=chroot
export REGISTRY_AUTH_FILE="${DOCKER_CONFIG}/config.json"
git config --global --add safe.directory '*'
cd "${HARBOR_SRC_DIR}"
make compile
make \
VERSIONTAG="${VERSION_TAG}" \
BASEIMAGETAG="${VERSION_TAG}" \
IMAGENAMESPACE="${IMAGE_NAMESPACE}" \
BASEIMAGENAMESPACE="${IMAGE_NAMESPACE}" \
DOCKERNETWORK=host \
PULL_BASE_FROM_DOCKERHUB=false \
BUILD_BASE=true \
BUILDTRIVYADP=false \
BUILD_INSTALLER=true \
build
for pair in \
prepare:harbor-prepare \
redis-photon:harbor-redis \
nginx-photon:harbor-nginx \
registry-photon:harbor-registry; do
pair_src="${pair%%:*}"
pair_dst="${pair##*:}"
src="${IMAGE_NAMESPACE}/${pair_src}:${VERSION_TAG}"
dst="${IMAGE_NAMESPACE}/${pair_dst}:${VERSION_TAG}"
if podman image exists "${src}"; then
podman tag "${src}" "${dst}" || true
fi
done
podman images --format '{{.Repository}}:{{.Tag}}' \
| awk -v ns="${IMAGE_NAMESPACE}/" -v tag="${VERSION_TAG}" 'index($0, ns)==1 && $0 ~ ":"tag"$"' \
| sort -u \
| while read -r img; do
echo "Pushing ${img}"
podman push "${img}"
done
'''
}
}
}
}
post {
always {
echo "done"
}
}
}