Bot Updating Templated Files

This commit is contained in:
LinuxServer-CI committed 2026-10-17 07:37:14 +00:00
1 parent 0cc53e2034
commit 4d08a0d2a4
1 file changed
+265 -68
Vendored
+265 -68
View File
@@ -52,6 +52,57 @@ pipeline {
''' '''
} }
} }
/* ############################
Bash Function For GHCR Retry
############################ */
// Create a reusable script for a ghcr retry bash function
stage("Create Bash Function"){
steps{
sh '''#! /bin/bash
# create our retry function
retry_ghcr() {
local max_attempts=7
local base_delay=10
local max_delay=90
local attempt=1
local errfile exit_code delay pause
errfile=$(mktemp)
while true; do
# run inside an if so a caller's set -e cannot abort before we get to retry
if "$@" 2> >(tee "${errfile}" >&2); then
exit_code=0
else
exit_code=$?
fi
# make sure tee has finished writing before we read the file
wait $! 2>/dev/null || true
if [[ "${exit_code}" == "0" ]]; then
rm -f "${errfile}"
return 0
elif ! grep -q -i -E "retry-after:|toomanyrequests|too many requests" "${errfile}"; then
rm -f "${errfile}"
return "${exit_code}"
elif (( attempt >= max_attempts )); then
rm -f "${errfile}"
echo "retry: $* failed after ${attempt} attempts (exit ${exit_code})" >&2
return "${exit_code}"
else
# exponential delay: base * 2^(attempt-1), capped at max_delay
delay=$(( base_delay * 2 ** (attempt - 1) ))
(( delay > max_delay )) && delay="${max_delay}"
# jitter between half and full delay so parallel builds spread out
pause=$(( delay / 2 + RANDOM % (delay / 2 + 1) ))
echo "retry: attempt ${attempt}/${max_attempts} failed (exit ${exit_code}); waiting ${pause}s..." >&2
sleep "${pause}"
((attempt++))
fi
done
}
declare -f retry_ghcr > ${WORKSPACE}/retry_ghcr.sh
'''
}
}
// Setup all the basic environment variables needed for the build // Setup all the basic environment variables needed for the build
stage("Set ENV Variables base"){ stage("Set ENV Variables base"){
steps{ steps{
@@ -79,7 +130,9 @@ pipeline {
env.CI_TEST_ATTEMPTED = '' env.CI_TEST_ATTEMPTED = ''
env.PUSH_ATTEMPTED = '' env.PUSH_ATTEMPTED = ''
env.LS_RELEASE = sh( env.LS_RELEASE = sh(
script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''', script: '''#! /bin/bash
source ${WORKSPACE}/retry_ghcr.sh
retry_ghcr docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''',
returnStdout: true).trim() returnStdout: true).trim()
env.LS_RELEASE_NOTES = sh( env.LS_RELEASE_NOTES = sh(
script: '''cat readme-vars.yml | awk -F \\" '/date: "[0-9][0-9].[0-9][0-9].[0-9][0-9]:/ {print $4;exit;}' | sed -E ':a;N;$!ba;s/\\r{0,1}\\n/\\\\n/g' ''', script: '''cat readme-vars.yml | awk -F \\" '/date: "[0-9][0-9].[0-9][0-9].[0-9][0-9]:/ {print $4;exit;}' | sed -E ':a;N;$!ba;s/\\r{0,1}\\n/\\\\n/g' ''',
@@ -100,8 +153,12 @@ pipeline {
if ( env.SYFT_IMAGE_TAG == null ) { if ( env.SYFT_IMAGE_TAG == null ) {
env.SYFT_IMAGE_TAG = 'latest' env.SYFT_IMAGE_TAG = 'latest'
} }
if ( env.GITLAB_TIMEOUT == null ) {
env.GITLAB_TIMEOUT = '600'
}
} }
echo "Using syft image tag ${SYFT_IMAGE_TAG}" echo "Using syft image tag ${SYFT_IMAGE_TAG}"
echo "Using gitlab registry timeout ${GITLAB_TIMEOUT}"
sh '''#! /bin/bash sh '''#! /bin/bash
echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" ''' echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" '''
script{ script{
@@ -281,6 +338,8 @@ pipeline {
} }
sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-jenkins-builder/master/checkrun.sh | /bin/bash''' sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-jenkins-builder/master/checkrun.sh | /bin/bash'''
sh '''#! /bin/bash sh '''#! /bin/bash
source ${WORKSPACE}/retry_ghcr.sh
retry_ghcr docker pull ghcr.io/linuxserver/baseimage-alpine:3.23
docker run --rm \ docker run --rm \
-v ${WORKSPACE}:/mnt \ -v ${WORKSPACE}:/mnt \
-e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \ -e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \
@@ -307,7 +366,8 @@ pipeline {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
TEMPDIR=$(mktemp -d) TEMPDIR=$(mktemp -d)
docker pull ghcr.io/linuxserver/jenkins-builder:latest source ${WORKSPACE}/retry_ghcr.sh
retry_ghcr docker pull ghcr.io/linuxserver/jenkins-builder:latest
# Cloned repo paths for templating: # Cloned repo paths for templating:
# ${TEMPDIR}/docker-${CONTAINER_NAME}: Cloned branch master of ${LS_USER}/${LS_REPO} for running the jenkins builder on # ${TEMPDIR}/docker-${CONTAINER_NAME}: Cloned branch master of ${LS_USER}/${LS_REPO} for running the jenkins builder on
# ${TEMPDIR}/repo/${LS_REPO}: Cloned branch master of ${LS_USER}/${LS_REPO} for commiting various templated file changes and pushing back to Github # ${TEMPDIR}/repo/${LS_REPO}: Cloned branch master of ${LS_USER}/${LS_REPO} for commiting various templated file changes and pushing back to Github
@@ -366,6 +426,7 @@ pipeline {
sed -i 's|^changelogs:|# init diagram\\ninit_diagram:\\n\\n# changelog\\nchangelogs:|' readme-vars.yml sed -i 's|^changelogs:|# init diagram\\ninit_diagram:\\n\\n# changelog\\nchangelogs:|' readme-vars.yml
fi fi
mkdir -p ${TEMPDIR}/d2 mkdir -p ${TEMPDIR}/d2
retry_ghcr docker pull ghcr.io/linuxserver/d2-builder:latest
docker run --rm -v ${TEMPDIR}/d2:/output -e PUID=$(id -u) -e PGID=$(id -g) -e RAW="true" ghcr.io/linuxserver/d2-builder:latest ${CONTAINER_NAME}:latest docker run --rm -v ${TEMPDIR}/d2:/output -e PUID=$(id -u) -e PGID=$(id -g) -e RAW="true" ghcr.io/linuxserver/d2-builder:latest ${CONTAINER_NAME}:latest
ls -al ${TEMPDIR}/d2 ls -al ${TEMPDIR}/d2
yq -ei ".init_diagram |= load_str(\\"${TEMPDIR}/d2/${CONTAINER_NAME}-latest.d2\\")" readme-vars.yml yq -ei ".init_diagram |= load_str(\\"${TEMPDIR}/d2/${CONTAINER_NAME}-latest.d2\\")" readme-vars.yml
@@ -582,22 +643,25 @@ pipeline {
steps { steps {
echo "Running on node: ${NODE_NAME}" echo "Running on node: ${NODE_NAME}"
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile" sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile"
sh "docker buildx build \ sh '''#! /bin/bash
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ source ${WORKSPACE}/retry_ghcr.sh
--label \"org.opencontainers.image.authors=linuxserver.io\" \ retry_ghcr docker buildx build \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages\" \ --label "org.opencontainers.image.created=${GITHUB_DATE}" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag\" \ --label "org.opencontainers.image.authors=linuxserver.io" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-swag\" \ --label "org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \ --label "org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \ --label "org.opencontainers.image.source=https://github.com/linuxserver/docker-swag" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \ --label "org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label "org.opencontainers.image.revision=${COMMIT_SHA}" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label "org.opencontainers.image.vendor=linuxserver.io" \
--label \"org.opencontainers.image.title=Swag\" \ --label "org.opencontainers.image.licenses=GPL-3.0-only" \
--label \"org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.\" \ --label "org.opencontainers.image.ref.name=${COMMIT_SHA}" \
--no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \ --label "org.opencontainers.image.title=Swag" \
--provenance=true --sbom=true --builder=container --load \ --label "org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention." \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." --no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \
--provenance=true --sbom=true --builder=container --load \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION="${VERSION_TAG}" --build-arg BUILD_DATE=${GITHUB_DATE} .
'''
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
@@ -616,6 +680,17 @@ pipeline {
retry_backoff(5,5) { retry_backoff(5,5) {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
# run a registry.gitlab.com command under what is left of the gitlab time budget
gitlab_timeout() {
local remaining=$(( GITLAB_DEADLINE - SECONDS ))
if (( remaining <= 0 )); then
echo "gitlab timeout budget of ${GITLAB_TIMEOUT}s used up, skipping: $*" >&2
return 124
fi
timeout "${remaining}" "$@"
}
GITLAB_DEADLINE=$(( SECONDS + GITLAB_TIMEOUT ))
echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
@@ -625,11 +700,16 @@ pipeline {
declare -A pids declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & if [[ "${i}" == *"registry.gitlab.com"* ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
${TIMEOUT_CMD} docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i" pids[$!]="$i"
done done
for p in "${!pids[@]}"; do for p in "${!pids[@]}"; do
wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]] && exit 1; } wait "$p" || { if [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]]; then exit 1; fi; }
done done
fi fi
''' '''
@@ -651,22 +731,25 @@ pipeline {
steps { steps {
echo "Running on node: ${NODE_NAME}" echo "Running on node: ${NODE_NAME}"
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile" sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile"
sh "docker buildx build \ sh '''#! /bin/bash
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ source ${WORKSPACE}/retry_ghcr.sh
--label \"org.opencontainers.image.authors=linuxserver.io\" \ retry_ghcr docker buildx build \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages\" \ --label "org.opencontainers.image.created=${GITHUB_DATE}" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag\" \ --label "org.opencontainers.image.authors=linuxserver.io" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-swag\" \ --label "org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \ --label "org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \ --label "org.opencontainers.image.source=https://github.com/linuxserver/docker-swag" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \ --label "org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label "org.opencontainers.image.revision=${COMMIT_SHA}" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label "org.opencontainers.image.vendor=linuxserver.io" \
--label \"org.opencontainers.image.title=Swag\" \ --label "org.opencontainers.image.licenses=GPL-3.0-only" \
--label \"org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.\" \ --label "org.opencontainers.image.ref.name=${COMMIT_SHA}" \
--no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \ --label "org.opencontainers.image.title=Swag" \
--provenance=true --sbom=true --builder=container --load \ --label "org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention." \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." --no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \
--provenance=true --sbom=true --builder=container --load \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION="${VERSION_TAG}" --build-arg BUILD_DATE=${GITHUB_DATE} .
'''
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
@@ -685,6 +768,17 @@ pipeline {
retry_backoff(5,5) { retry_backoff(5,5) {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
# run a registry.gitlab.com command under what is left of the gitlab time budget
gitlab_timeout() {
local remaining=$(( GITLAB_DEADLINE - SECONDS ))
if (( remaining <= 0 )); then
echo "gitlab timeout budget of ${GITLAB_TIMEOUT}s used up, skipping: $*" >&2
return 124
fi
timeout "${remaining}" "$@"
}
GITLAB_DEADLINE=$(( SECONDS + GITLAB_TIMEOUT ))
echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
@@ -694,11 +788,16 @@ pipeline {
declare -A pids declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & if [[ "${i}" == *"registry.gitlab.com"* ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
${TIMEOUT_CMD} docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i" pids[$!]="$i"
done done
for p in "${!pids[@]}"; do for p in "${!pids[@]}"; do
wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]] && exit 1; } wait "$p" || { if [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]]; then exit 1; fi; }
done done
fi fi
''' '''
@@ -713,22 +812,64 @@ pipeline {
steps { steps {
echo "Running on node: ${NODE_NAME}" echo "Running on node: ${NODE_NAME}"
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64" sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64"
sh "docker buildx build \ sh '''#! /bin/bash
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ # create our retry function
--label \"org.opencontainers.image.authors=linuxserver.io\" \ retry_ghcr() {
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages\" \ local max_attempts=7
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag\" \ local base_delay=10
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-swag\" \ local max_delay=90
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \ local attempt=1
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \ local errfile exit_code delay pause
--label \"org.opencontainers.image.vendor=linuxserver.io\" \ errfile=$(mktemp)
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ while true; do
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ # run inside an if so a caller's set -e cannot abort before we get to retry
--label \"org.opencontainers.image.title=Swag\" \ if "$@" 2> >(tee "${errfile}" >&2); then
--label \"org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.\" \ exit_code=0
--no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \ else
--provenance=true --sbom=true --builder=container --load \ exit_code=$?
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." fi
# make sure tee has finished writing before we read the file
wait $! 2>/dev/null || true
if [[ "${exit_code}" == "0" ]]; then
rm -f "${errfile}"
return 0
elif ! grep -q -i -E "retry-after:|toomanyrequests|too many requests" "${errfile}"; then
rm -f "${errfile}"
return "${exit_code}"
elif (( attempt >= max_attempts )); then
rm -f "${errfile}"
echo "retry: $* failed after ${attempt} attempts (exit ${exit_code})" >&2
return "${exit_code}"
else
# exponential delay: base * 2^(attempt-1), capped at max_delay
delay=$(( base_delay * 2 ** (attempt - 1) ))
(( delay > max_delay )) && delay="${max_delay}"
# jitter between half and full delay so parallel builds spread out
pause=$(( delay / 2 + RANDOM % (delay / 2 + 1) ))
echo "retry: attempt ${attempt}/${max_attempts} failed (exit ${exit_code}); waiting ${pause}s..." >&2
sleep "${pause}"
((attempt++))
fi
done
}
retry_ghcr docker buildx build \
--label "org.opencontainers.image.created=${GITHUB_DATE}" \
--label "org.opencontainers.image.authors=linuxserver.io" \
--label "org.opencontainers.image.url=https://github.com/linuxserver/docker-swag/packages" \
--label "org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-swag" \
--label "org.opencontainers.image.source=https://github.com/linuxserver/docker-swag" \
--label "org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}" \
--label "org.opencontainers.image.revision=${COMMIT_SHA}" \
--label "org.opencontainers.image.vendor=linuxserver.io" \
--label "org.opencontainers.image.licenses=GPL-3.0-only" \
--label "org.opencontainers.image.ref.name=${COMMIT_SHA}" \
--label "org.opencontainers.image.title=Swag" \
--label "org.opencontainers.image.description=SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention." \
--no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \
--provenance=true --sbom=true --builder=container --load \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION="${VERSION_TAG}" --build-arg BUILD_DATE=${GITHUB_DATE} .
'''
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
@@ -747,6 +888,17 @@ pipeline {
retry_backoff(5,5) { retry_backoff(5,5) {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
# run a registry.gitlab.com command under what is left of the gitlab time budget
gitlab_timeout() {
local remaining=$(( GITLAB_DEADLINE - SECONDS ))
if (( remaining <= 0 )); then
echo "gitlab timeout budget of ${GITLAB_TIMEOUT}s used up, skipping: $*" >&2
return 124
fi
timeout "${remaining}" "$@"
}
GITLAB_DEADLINE=$(( SECONDS + GITLAB_TIMEOUT ))
echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
@@ -755,11 +907,16 @@ pipeline {
declare -A pids declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} & if [[ "${i}" == *"registry.gitlab.com"* ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
${TIMEOUT_CMD} docker push ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i" pids[$!]="$i"
done done
for p in "${!pids[@]}"; do for p in "${!pids[@]}"; do
wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]] && exit 1; } wait "$p" || { if [[ "${pids[$p]}" != *"quay.io"* && "${pids[$p]}" != *"registry.gitlab.com"* ]]; then exit 1; fi; }
done done
fi fi
''' '''
@@ -794,6 +951,8 @@ pipeline {
LOCAL_CONTAINER=${IMAGE}:${META_TAG} LOCAL_CONTAINER=${IMAGE}:${META_TAG}
fi fi
touch ${TEMPDIR}/package_versions.txt touch ${TEMPDIR}/package_versions.txt
source ${WORKSPACE}/retry_ghcr.sh
retry_ghcr docker pull ghcr.io/anchore/syft:${SYFT_IMAGE_TAG}
docker run --rm \ docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ${TEMPDIR}:/tmp \ -v ${TEMPDIR}:/tmp \
@@ -885,9 +1044,10 @@ pipeline {
CI_DOCKERENV="LSIO_FIRST_PARTY=true" CI_DOCKERENV="LSIO_FIRST_PARTY=true"
fi fi
fi fi
docker pull ghcr.io/linuxserver/ci:${CITEST_IMAGETAG} source ${WORKSPACE}/retry_ghcr.sh
retry_ghcr docker pull ghcr.io/linuxserver/ci:${CITEST_IMAGETAG}
if [ "${MULTIARCH}" == "true" ]; then if [ "${MULTIARCH}" == "true" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64 retry_ghcr docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG} docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
fi fi
docker run --rm \ docker run --rm \
@@ -932,7 +1092,23 @@ pipeline {
retry_backoff(5,5) { retry_backoff(5,5) {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
# run a registry.gitlab.com command under what is left of the gitlab time budget
gitlab_timeout() {
local remaining=$(( GITLAB_DEADLINE - SECONDS ))
if (( remaining <= 0 )); then
echo "gitlab timeout budget of ${GITLAB_TIMEOUT}s used up, skipping: $*" >&2
return 124
fi
timeout "${remaining}" "$@"
}
GITLAB_DEADLINE=$(( SECONDS + GITLAB_TIMEOUT ))
for PUSHIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do for PUSHIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
if [[ "${PUSHIMAGE}" == "${GITLABIMAGE}" ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
[[ ${PUSHIMAGE%%/*} =~ \\. ]] && PUSHIMAGEPLUS="${PUSHIMAGE}" || PUSHIMAGEPLUS="docker.io/${PUSHIMAGE}" [[ ${PUSHIMAGE%%/*} =~ \\. ]] && PUSHIMAGEPLUS="${PUSHIMAGE}" || PUSHIMAGEPLUS="docker.io/${PUSHIMAGE}"
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
@@ -940,10 +1116,10 @@ pipeline {
CACHEIMAGE=${i} CACHEIMAGE=${i}
fi fi
done done
docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:latest -t ${PUSHIMAGE}:${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:latest -t ${PUSHIMAGE}:${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" && "${PUSHIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" && "${PUSHIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" && "${PUSHIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" && "${PUSHIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
fi fi
done done
@@ -964,7 +1140,23 @@ pipeline {
retry_backoff(5,5) { retry_backoff(5,5) {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
# run a registry.gitlab.com command under what is left of the gitlab time budget
gitlab_timeout() {
local remaining=$(( GITLAB_DEADLINE - SECONDS ))
if (( remaining <= 0 )); then
echo "gitlab timeout budget of ${GITLAB_TIMEOUT}s used up, skipping: $*" >&2
return 124
fi
timeout "${remaining}" "$@"
}
GITLAB_DEADLINE=$(( SECONDS + GITLAB_TIMEOUT ))
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
if [[ "${MANIFESTIMAGE}" == "${GITLABIMAGE}" ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
if [[ "${MANIFESTIMAGE%%/*}" =~ \\. ]]; then if [[ "${MANIFESTIMAGE%%/*}" =~ \\. ]]; then
MANIFESTIMAGEPLUS="${MANIFESTIMAGE}" MANIFESTIMAGEPLUS="${MANIFESTIMAGE}"
else else
@@ -976,26 +1168,31 @@ pipeline {
CACHEIMAGE=${i} CACHEIMAGE=${i}
fi fi
done done
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-latest -t ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-latest -t ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${META_TAG} -t ${MANIFESTIMAGE}:arm64v8-latest -t ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${META_TAG} -t ${MANIFESTIMAGE}:arm64v8-latest -t ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \ ${TIMEOUT_CMD} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
fi fi
done done
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm64v8-latest || \ if [[ "${MANIFESTIMAGE}" == "${GITLABIMAGE}" ]]; then
TIMEOUT_CMD="gitlab_timeout"
else
TIMEOUT_CMD=""
fi
${TIMEOUT_CMD} docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm64v8-latest || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} || \ ${TIMEOUT_CMD} docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} || \ ${TIMEOUT_CMD} docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} || \ ${TIMEOUT_CMD} docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; } { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" && "${MANIFESTIMAGE}" != "${GITLABIMAGE}" ]]; then exit 1; fi; }
fi fi
done done