diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index a09c3e8..b7692bb 100644 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -26,7 +26,7 @@ jobs: echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY echo "> External trigger running off of main branch. To disable this trigger, add \`socket-proxy_main\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY - EXT_RELEASE=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + EXT_RELEASE=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ && awk '/^P:'"haproxy"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') echo "Type is \`alpine_repo\`" >> $GITHUB_STEP_SUMMARY if grep -q "^socket-proxy_main_${EXT_RELEASE}" <<< "${SKIP_EXTERNAL_TRIGGER}"; then @@ -104,7 +104,7 @@ jobs: if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then echo "Version \`${EXT_RELEASE}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY exit 0 - elif [[ $(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/aarch64/APKINDEX.tar.gz" | tar -xz -C /tmp && awk '/^P:'"haproxy"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') != "${EXT_RELEASE}" ]]; then + elif [[ $(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.22/main/aarch64/APKINDEX.tar.gz" | tar -xz -C /tmp && awk '/^P:'"haproxy"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') != "${EXT_RELEASE}" ]]; then echo "New version \`${EXT_RELEASE}\` found; but not all arch repos updated yet; exiting" >> $GITHUB_STEP_SUMMARY FAILURE_REASON="New version ${EXT_RELEASE} for socket-proxy tag latest is detected, however not all arch repos are updated yet. Will try again later." curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, diff --git a/Dockerfile b/Dockerfile index eb34123..dd360f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM docker.io/alpine:3.21 +FROM docker.io/alpine:3.22 # set version label ARG BUILD_DATE @@ -16,7 +16,7 @@ RUN \ alpine-release \ curl && \ if [ -z ${HAPROXY_VERSION+x} ]; then \ - HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ && awk '/^P:haproxy$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ fi && \ apk add --no-cache \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index eb34123..dd360f6 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM docker.io/alpine:3.21 +FROM docker.io/alpine:3.22 # set version label ARG BUILD_DATE @@ -16,7 +16,7 @@ RUN \ alpine-release \ curl && \ if [ -z ${HAPROXY_VERSION+x} ]; then \ - HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ && awk '/^P:haproxy$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ fi && \ apk add --no-cache \ diff --git a/Dockerfile.riscv64 b/Dockerfile.riscv64 new file mode 100644 index 0000000..dd360f6 --- /dev/null +++ b/Dockerfile.riscv64 @@ -0,0 +1,63 @@ +# syntax=docker/dockerfile:1 + +FROM docker.io/alpine:3.22 + +# set version label +ARG BUILD_DATE +ARG VERSION +ARG HAPROXY_VERSION +LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" +LABEL maintainer="thespad" + +# install packages +RUN \ + echo "**** install build packages ****" && \ + apk add --no-cache \ + alpine-release \ + curl && \ + if [ -z ${HAPROXY_VERSION+x} ]; then \ + HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + && awk '/^P:haproxy$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ + fi && \ + apk add --no-cache \ + haproxy==${HAPROXY_VERSION} && \ + printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ + apk del --no-cache \ + curl && \ + rm -rf \ + /etc/haproxy \ + /tmp/* + +ENV ALLOW_RESTARTS=0 \ + ALLOW_STOP=0 \ + ALLOW_START=0 \ + AUTH=0 \ + BUILD=0 \ + COMMIT=0 \ + CONFIGS=0 \ + CONTAINERS=0 \ + DISTRIBUTION=0 \ + EVENTS=1 \ + EXEC=0 \ + IMAGES=0 \ + INFO=0 \ + LOG_LEVEL=info \ + NETWORKS=0 \ + NODES=0 \ + PING=1 \ + PLUGINS=0 \ + POST=0 \ + SECRETS=0 \ + SERVICES=0 \ + SESSION=0 \ + SOCKET_PATH=/var/run/docker.sock \ + SWARM=0 \ + SYSTEM=0 \ + TASKS=0 \ + VERSION=1 \ + VOLUMES=0 + +# add local files +COPY root/ / + +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/Jenkinsfile b/Jenkinsfile index 664aa07..93990f6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { DEV_DOCKERHUB_IMAGE = 'lsiodev/socket-proxy' PR_DOCKERHUB_IMAGE = 'lspipepr/socket-proxy' DIST_IMAGE = 'alpine' - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.21/main/' + DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.22/main/' DIST_REPO_PACKAGES = 'haproxy' MULTIARCH='true' CI='true' @@ -199,7 +199,7 @@ pipeline { env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/' + env.CONTAINER_NAME env.QUAYIMAGE = 'quay.io/linuxserver.io/' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|riscv64-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER } else { env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER } @@ -223,7 +223,7 @@ pipeline { env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lsiodev-' + env.CONTAINER_NAME env.QUAYIMAGE = 'quay.io/linuxserver.io/lsiodev-' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|riscv64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA } else { env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA } @@ -247,7 +247,7 @@ pipeline { env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lspipepr-' + env.CONTAINER_NAME env.QUAYIMAGE = 'quay.io/linuxserver.io/lspipepr-' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + '|riscv64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST } else { env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST } @@ -698,6 +698,73 @@ pipeline { ''' } } + stage('Build RISCV64') { + agent { + label 'RISCV64' + } + steps { + echo "Running on node: ${NODE_NAME}" + sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.riscv64" + sh "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-socket-proxy/packages\" \ + --label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-socket-proxy\" \ + --label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-socket-proxy\" \ + --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=Socket-proxy\" \ + --label \"org.opencontainers.image.description=The Socket Proxy is a security-enhanced proxy which allows you to apply access rules to the Docker socket, limiting the attack surface for containers such as watchtower or Traefik that need to use it.\" \ + --no-cache --pull -f Dockerfile.riscv64 -t ${IMAGE}:riscv64-${META_TAG} --platform=linux/riscv64 \ + --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 + set -e + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker tag ${IMAGE}:riscv64-${META_TAG} ${i}:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} + done + ''' + withCredentials([ + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' + ] + ]) { + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --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 $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin + if [[ "${PACKAGE_CHECK}" != "true" ]]; then + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker push ${i}:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} & + done + for p in $(jobs -p); do + wait "$p" || { echo "job $p failed" >&2; exit 1; } + done + fi + ''' + } + } + sh '''#! /bin/bash + containers=$(docker ps -aq) + if [[ -n "${containers}" ]]; then + docker stop ${containers} + fi + docker system prune -f --volumes || : + docker image prune -af || : + ''' + } + } } } // Take the image we just built and dump package versions for comparison @@ -811,6 +878,8 @@ pipeline { if [ "${MULTIARCH}" == "true" ]; then 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 pull ghcr.io/linuxserver/lsiodev-buildcache:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} --platform=riscv64 + docker tag ghcr.io/linuxserver/lsiodev-buildcache:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:riscv64-${META_TAG} fi docker run --rm \ --shm-size=1gb \ @@ -885,18 +954,20 @@ pipeline { 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} 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} + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:riscv64-${META_TAG} -t ${MANIFESTIMAGE}:riscv64-latest -t ${MANIFESTIMAGE}:riscv64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} if [ -n "${SEMVER}" ]; then docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:riscv64-${SEMVER} ${CACHEIMAGE}:riscv64-${COMMIT_SHA}-${BUILD_NUMBER} fi done for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do - docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm64v8-latest - docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} + docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:riscv64-latest ${MANIFESTIMAGE}:arm64v8-latest + docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:riscv64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} + docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:riscv64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} if [ -n "${SEMVER}" ]; then - docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} + docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:riscv64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} fi done ''' diff --git a/README.md b/README.md index 8835a61..ddc92b3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ The architectures supported by this image are: | Architecture | Available | Tag | | :----: | :----: | ---- | | x86-64 | ✅ | amd64-\ | +| riscv64 | ✅ | riscv64-\ | | arm64 | ✅ | arm64v8-\ | | armhf | ❌ | | @@ -315,6 +316,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **03.06.25:** - Rebase to Alpine 3.22. Add RISCV support. * **08.04.25:** - Add `LOG_LEVEL` back. * **06.04.25:** - Switch back to haproxy for better handling of `docker exec` connection hijacking. * **02.01.25:** - Support custom read timeout values. diff --git a/jenkins-vars.yml b/jenkins-vars.yml index ef9fcee..2e480a1 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -6,6 +6,7 @@ external_type: alpine_repo release_type: stable release_tag: latest ls_branch: main +build_riscv64: true repo_vars: - BUILD_VERSION_ARG = 'HAPROXY_VERSION' - LS_USER = 'linuxserver' @@ -15,7 +16,7 @@ repo_vars: - DEV_DOCKERHUB_IMAGE = 'lsiodev/socket-proxy' - PR_DOCKERHUB_IMAGE = 'lspipepr/socket-proxy' - DIST_IMAGE = 'alpine' - - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.21/main/' + - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.22/main/' - DIST_REPO_PACKAGES = 'haproxy' - MULTIARCH='true' - CI='true' diff --git a/readme-vars.yml b/readme-vars.yml index fc67295..82284e4 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -54,6 +54,7 @@ full_custom_readme: | | Architecture | Available | Tag | | :----: | :----: | ---- | | x86-64 | ✅ | amd64-\ | + | riscv64 | ✅ | riscv64-\ | | arm64 | ✅ | arm64v8-\ | | armhf | ❌ | | @@ -322,6 +323,7 @@ full_custom_readme: | ## Versions + * **03.06.25:** - Rebase to Alpine 3.22. Add RISCV support. * **08.04.25:** - Add `LOG_LEVEL` back. * **06.04.25:** - Switch back to haproxy for better handling of `docker exec` connection hijacking. * **02.01.25:** - Support custom read timeout values.