diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 424ab22..1b3ed2a 100755 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ * Read, and fill the Pull Request template * If this is a fix for a typo (in code, documentation, or the README) please file an issue and let us sort it out. We do not need a PR * If the PR is addressing an existing issue include, closes #\, in the body of the PR commit message -* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://discord.gg/YWrKVTn) +* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://linuxserver.io/discord) ## Common files @@ -105,10 +105,10 @@ docker build \ -t linuxserver/bazarr:latest . ``` -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static` ```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset +docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset ``` Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 6ba8f84..7543866 100755 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - name: Discord chat support - url: https://discord.gg/YWrKVTn + url: https://linuxserver.io/discord about: Realtime support / chat with the community and the team. - name: Discourse discussion forum diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index c2b1c0b..31036b0 100755 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -11,18 +11,28 @@ jobs: - name: External Trigger if: github.ref == 'refs/heads/master' + env: + SKIP_EXTERNAL_TRIGGER: ${{ vars.SKIP_EXTERNAL_TRIGGER }} run: | printf "# External trigger for docker-bazarr\n\n" >> $GITHUB_STEP_SUMMARY - if [ -n "${{ secrets.PAUSE_EXTERNAL_TRIGGER_BAZARR_MASTER }}" ]; then + if grep -q "^bazarr_master_" <<< "${SKIP_EXTERNAL_TRIGGER}"; then + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`bazarr_master_\`; will skip trigger if version matches." >> $GITHUB_STEP_SUMMARY + elif grep -q "^bazarr_master" <<< "${SKIP_EXTERNAL_TRIGGER}"; then echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY - echo "> Github secret \`PAUSE_EXTERNAL_TRIGGER_BAZARR_MASTER\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`bazarr_master\`; skipping trigger." >> $GITHUB_STEP_SUMMARY exit 0 fi echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY - echo "> External trigger running off of master branch. To disable this trigger, set a Github secret named \`PAUSE_EXTERNAL_TRIGGER_BAZARR_MASTER\`" >> $GITHUB_STEP_SUMMARY + echo "> External trigger running off of master branch. To disable this trigger, add \`bazarr_master\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY EXT_RELEASE=$(curl -u "${{ secrets.CR_USER }}:${{ secrets.CR_PAT }}" -sX GET "https://api.github.com/repos/morpheus65535/bazarr/releases/latest" | jq -r '. | .tag_name') echo "Type is \`github_stable\`" >> $GITHUB_STEP_SUMMARY + if grep -q "^bazarr_master_${EXT_RELEASE}" <<< "${SKIP_EXTERNAL_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` matches current external release; skipping trigger." >> $GITHUB_STEP_SUMMARY + exit 0 + fi if [ -z "${EXT_RELEASE}" ] || [ "${EXT_RELEASE}" == "null" ]; then echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY echo "> Can't retrieve external version, exiting" >> $GITHUB_STEP_SUMMARY @@ -41,16 +51,35 @@ jobs: token=$(curl -sX GET \ "https://ghcr.io/token?scope=repository%3Alinuxserver%2Fbazarr%3Apull" \ | jq -r '.token') - multidigest=$(curl -s \ + multidigest=$(curl -s \ + --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ + --header "Accept: application/vnd.oci.image.index.v1+json" \ + --header "Authorization: Bearer ${token}" \ + "https://ghcr.io/v2/${image}/manifests/${tag}") + if jq -e '.layers // empty' <<< "${multidigest}" >/dev/null 2>&1; then + # If there's a layer element it's a single-arch manifest so just get that digest + digest=$(jq -r '.config.digest' <<< "${multidigest}") + else + # Otherwise it's multi-arch or has manifest annotations + if jq -e '.manifests[]?.annotations // empty' <<< "${multidigest}" >/dev/null 2>&1; then + # Check for manifest annotations and delete if found + multidigest=$(jq 'del(.manifests[] | select(.annotations))' <<< "${multidigest}") + fi + if [[ $(jq '.manifests | length' <<< "${multidigest}") -gt 1 ]]; then + # If there's still more than one digest, it's multi-arch + multidigest=$(jq -r ".manifests[] | select(.platform.architecture == \"amd64\").digest?" <<< "${multidigest}") + else + # Otherwise it's single arch + multidigest=$(jq -r ".manifests[].digest?" <<< "${multidigest}") + fi + if digest=$(curl -s \ --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ + --header "Accept: application/vnd.oci.image.manifest.v1+json" \ --header "Authorization: Bearer ${token}" \ - "https://ghcr.io/v2/${image}/manifests/${tag}" \ - | jq -r 'first(.manifests[].digest)') - digest=$(curl -s \ - --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ - --header "Authorization: Bearer ${token}" \ - "https://ghcr.io/v2/${image}/manifests/${multidigest}" \ - | jq -r '.config.digest') + "https://ghcr.io/v2/${image}/manifests/${multidigest}"); then + digest=$(jq -r '.config.digest' <<< "${digest}"); + fi + fi image_info=$(curl -sL \ --header "Authorization: Bearer ${token}" \ "https://ghcr.io/v2/${image}/blobs/${digest}") @@ -78,26 +107,38 @@ jobs: echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY exit 0 else - printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY - echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY - response=$(curl -iX POST \ - https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/master/buildWithParameters?PACKAGE_CHECK=false \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") - echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY - echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY - sleep 10 - buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') - buildurl="${buildurl%$'\r'}" - echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY - echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY - curl -iX POST \ - "${buildurl}submitDescription" \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ - --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - --data-urlencode "Submit=Submit" - echo "**** Notifying Discord ****" - TRIGGER_REASON="A version change was detected for bazarr tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ "${artifacts_found}" == "false" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> New version detected, but not all artifacts are published yet; skipping trigger" >> $GITHUB_STEP_SUMMARY + FAILURE_REASON="New version ${EXT_RELEASE} for bazarr tag latest is detected, however not all artifacts are uploaded to upstream release 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, + "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + else + printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY + echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY + if [[ "${artifacts_found}" == "true" ]]; then + echo "All artifacts seem to be uploaded." >> $GITHUB_STEP_SUMMARY + fi + response=$(curl -iX POST \ + https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/master/buildWithParameters?PACKAGE_CHECK=false \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY + curl -iX POST \ + "${buildurl}submitDescription" \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ + --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --data-urlencode "Submit=Submit" + echo "**** Notifying Discord ****" + TRIGGER_REASON="A version change was detected for bazarr tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi fi diff --git a/.github/workflows/package_trigger.yml b/.github/workflows/package_trigger.yml deleted file mode 100755 index c2adea3..0000000 --- a/.github/workflows/package_trigger.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Package Trigger Main - -on: - workflow_dispatch: - -jobs: - package-trigger-master: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4.1.1 - - - name: Package Trigger - if: github.ref == 'refs/heads/master' - run: | - printf "# Package trigger for docker-bazarr\n\n" >> $GITHUB_STEP_SUMMARY - if [ -n "${{ secrets.PAUSE_PACKAGE_TRIGGER_BAZARR_MASTER }}" ]; then - echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY - echo "> Github secret \`PAUSE_PACKAGE_TRIGGER_BAZARR_MASTER\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY - exit 0 - fi - if [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/master/lastBuild/api/json | jq -r '.building') == "true" ]; then - echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY - echo "> There already seems to be an active build on Jenkins; skipping package trigger" >> $GITHUB_STEP_SUMMARY - exit 0 - fi - echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY - echo "> Package trigger running off of master branch. To disable, set a Github secret named \`PAUSE_PACKAGE_TRIGGER_BAZARR_MASTER\`" >> $GITHUB_STEP_SUMMARY - response=$(curl -iX POST \ - https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/master/buildWithParameters?PACKAGE_CHECK=true \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") - echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY - echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY - sleep 10 - buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') - buildurl="${buildurl%$'\r'}" - echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY - echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY - curl -iX POST \ - "${buildurl}submitDescription" \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ - --data-urlencode "description=GHA package trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - --data-urlencode "Submit=Submit" diff --git a/.github/workflows/package_trigger_scheduler.yml b/.github/workflows/package_trigger_scheduler.yml index 8970732..09fd3c4 100755 --- a/.github/workflows/package_trigger_scheduler.yml +++ b/.github/workflows/package_trigger_scheduler.yml @@ -14,6 +14,8 @@ jobs: fetch-depth: '0' - name: Package Trigger Scheduler + env: + SKIP_PACKAGE_TRIGGER: ${{ vars.SKIP_PACKAGE_TRIGGER }} run: | printf "# Package trigger scheduler for docker-bazarr\n\n" >> $GITHUB_STEP_SUMMARY printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY @@ -24,27 +26,75 @@ jobs: continue fi printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY - ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-bazarr/${br}/jenkins-vars.yml | yq -r '.ls_branch') - if [ "${br}" == "${ls_branch}" ]; then + JENKINS_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-bazarr/${br}/jenkins-vars.yml) + if ! curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-bazarr/${br}/Jenkinsfile >/dev/null 2>&1; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> No Jenkinsfile found. Branch is either deprecated or is an early dev branch." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [[ "${br}" == $(yq -r '.ls_branch' <<< "${JENKINS_VARS}") ]]; then echo "Branch appears to be live; checking workflow." >> $GITHUB_STEP_SUMMARY - if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-bazarr/${br}/.github/workflows/package_trigger.yml > /dev/null 2>&1; then - echo "Triggering package trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY - triggered_branches="${triggered_branches}${br} " - curl -iX POST \ - -H "Authorization: token ${{ secrets.CR_PAT }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -d "{\"ref\":\"refs/heads/${br}\"}" \ - https://api.github.com/repos/linuxserver/docker-bazarr/actions/workflows/package_trigger.yml/dispatches - sleep 30 + README_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-bazarr/${br}/readme-vars.yml) + if [[ $(yq -r '.project_deprecation_status' <<< "${README_VARS}") == "true" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Branch appears to be deprecated; skipping trigger." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [[ $(yq -r '.skip_package_check' <<< "${JENKINS_VARS}") == "true" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Skipping branch ${br} due to \`skip_package_check\` being set in \`jenkins-vars.yml\`." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif grep -q "^bazarr_${br}" <<< "${SKIP_PACKAGE_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_PACKAGE_TRIGGER\` contains \`bazarr_${br}\`; skipping trigger." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/${br}/lastBuild/api/json | jq -r '.building' 2>/dev/null) == "true" ]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> There already seems to be an active build on Jenkins; skipping package trigger for ${br}" >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " else - echo "Skipping branch ${br} due to no package trigger workflow present." >> $GITHUB_STEP_SUMMARY + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> Triggering package trigger for branch ${br}" >> $GITHUB_STEP_SUMMARY + printf "> To disable, add \`bazarr_%s\` into the Github organizational variable \`SKIP_PACKAGE_TRIGGER\`.\n\n" "${br}" >> $GITHUB_STEP_SUMMARY + triggered_branches="${triggered_branches}${br} " + response=$(curl -iX POST \ + https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-bazarr/job/${br}/buildWithParameters?PACKAGE_CHECK=true \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + if [[ -z "${response}" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Jenkins build could not be triggered. Skipping branch." + continue + fi + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY + if ! curl -ifX POST \ + "${buildurl}submitDescription" \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ + --data-urlencode "description=GHA package trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --data-urlencode "Submit=Submit"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Unable to change the Jenkins job description." + fi + sleep 20 fi else echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY fi done - echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" - echo "**** Notifying Discord ****" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Package Check Build(s) Triggered for bazarr** \n**Branch(es):** '"${triggered_branches}"' \n**Build URL:** '"https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-bazarr/activity/"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ -n "${triggered_branches}" ]] || [[ -n "${skipped_branches}" ]]; then + if [[ -n "${triggered_branches}" ]]; then + NOTIFY_BRANCHES="**Triggered:** ${triggered_branches} \n" + NOTIFY_BUILD_URL="**Build URL:** https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-bazarr/activity/ \n" + echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" + fi + if [[ -n "${skipped_branches}" ]]; then + NOTIFY_BRANCHES="${NOTIFY_BRANCHES}**Skipped:** ${skipped_branches} \n" + fi + echo "**** Notifying Discord ****" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Package Check Build(s) for bazarr** \n'"${NOTIFY_BRANCHES}"''"${NOTIFY_BUILD_URL}"'"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi diff --git a/Dockerfile b/Dockerfile index ab814e3..290dd86 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM ghcr.io/linuxserver/unrar:latest AS unrar -FROM ghcr.io/linuxserver/baseimage-alpine:3.20 +FROM ghcr.io/linuxserver/baseimage-alpine:3.21 # set version label ARG BUILD_DATE @@ -53,7 +53,7 @@ RUN \ pip install -U --no-cache-dir \ pip \ wheel && \ - pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.20/ \ + pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.21/ \ -r /app/bazarr/bin/requirements.txt \ -r /app/bazarr/bin/postgres-requirements.txt && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 7367157..ab91d28 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -2,7 +2,7 @@ FROM ghcr.io/linuxserver/unrar:arm64v8-latest AS unrar -FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.20 +FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.21 # set version label ARG BUILD_DATE @@ -53,7 +53,7 @@ RUN \ pip install -U --no-cache-dir \ pip \ wheel && \ - pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.20/ \ + pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.21/ \ -r /app/bazarr/bin/requirements.txt \ -r /app/bazarr/bin/postgres-requirements.txt && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ diff --git a/Jenkinsfile b/Jenkinsfile index c4ea070..57d9c26 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { } // Input to determine if this is a package check parameters { - string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK') + string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK') } // Configuration for the variables used for this specific repo environment { @@ -59,11 +59,23 @@ pipeline { steps{ echo "Running on node: ${NODE_NAME}" sh '''#! /bin/bash - containers=$(docker ps -aq) + echo "Pruning builder" + docker builder prune -f --builder container || : + containers=$(docker ps -q) if [[ -n "${containers}" ]]; then - docker stop ${containers} + BUILDX_CONTAINER_ID=$(docker ps -qf 'name=buildx_buildkit') + for container in ${containers}; do + if [[ "${container}" == "${BUILDX_CONTAINER_ID}" ]]; then + echo "skipping buildx container in docker stop" + else + echo "Stopping container ${container}" + docker stop ${container} + fi + done fi - docker system prune -af --volumes || : ''' + docker system prune -f --volumes || : + docker image prune -af || : + ''' script{ env.EXIT_STATUS = '' env.LS_RELEASE = sh( @@ -84,7 +96,7 @@ pipeline { env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/' env.PULL_REQUEST = env.CHANGE_ID - env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml ./.github/workflows/package_trigger.yml ./root/donate.txt' + env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml ./root/donate.txt' } sh '''#! /bin/bash echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" ''' @@ -201,6 +213,7 @@ pipeline { env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER env.META_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' } } } @@ -225,6 +238,7 @@ pipeline { env.META_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/' + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' } } } @@ -249,6 +263,7 @@ pipeline { env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.PR_DOCKERHUB_IMAGE + '/tags/' + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' } } } @@ -321,7 +336,7 @@ pipeline { echo "Jenkinsfile is up to date." fi echo "Starting Stage 2 - Delete old templates" - OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml" + OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml .github/workflows/package_trigger.yml" for i in ${OLD_TEMPLATES}; do if [[ -f "${i}" ]]; then TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}" @@ -345,6 +360,35 @@ pipeline { else echo "No templates to delete" fi + echo "Starting Stage 2.5 - Update init diagram" + if ! grep -q 'init_diagram:' readme-vars.yml; then + echo "Adding the key 'init_diagram' to readme-vars.yml" + sed -i '\\|^#.*changelog.*$|d' readme-vars.yml + sed -i 's|^changelogs:|# init diagram\\ninit_diagram:\\n\\n# changelog\\nchangelogs:|' readme-vars.yml + fi + mkdir -p ${TEMPDIR}/d2 + 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 + yq -ei ".init_diagram |= load_str(\\"${TEMPDIR}/d2/${CONTAINER_NAME}-latest.d2\\")" readme-vars.yml + if [[ $(md5sum readme-vars.yml | cut -c1-8) != $(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/readme-vars.yml | cut -c1-8) ]]; then + echo "'init_diagram' has been updated. Updating repo and exiting build, new one will trigger based on commit." + mkdir -p ${TEMPDIR}/repo + git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} + cd ${TEMPDIR}/repo/${LS_REPO} + git checkout -f master + cp ${WORKSPACE}/readme-vars.yml ${TEMPDIR}/repo/${LS_REPO}/readme-vars.yml + git add readme-vars.yml + git commit -m 'Bot Updating Templated Files' + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git master + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git master + echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} + echo "Updating templates and exiting build, new one will trigger based on commit" + rm -Rf ${TEMPDIR} + exit 0 + else + echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} + echo "Init diagram is unchanged" + fi echo "Starting Stage 3 - Update templates" CURRENTHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8) cd ${TEMPDIR}/docker-${CONTAINER_NAME} @@ -553,8 +597,42 @@ pipeline { --label \"org.opencontainers.image.title=Bazarr\" \ --label \"org.opencontainers.image.description=[Bazarr](https://www.bazarr.media/) is a companion application to Sonarr and Radarr. It can manage and download subtitles based on your requirements. You define your preferences by TV show or movie and Bazarr takes care of everything for you.\" \ --no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \ - --provenance=false --sbom=false \ + --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}:${META_TAG} ${i}:amd64-${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}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & + done + for p in $(jobs -p); do + wait "$p" || { echo "job $p failed" >&2; exit 1; } + done + fi + ''' + } + } } } // Build MultiArch Docker containers for push to LS Repo @@ -585,8 +663,42 @@ pipeline { --label \"org.opencontainers.image.title=Bazarr\" \ --label \"org.opencontainers.image.description=[Bazarr](https://www.bazarr.media/) is a companion application to Sonarr and Radarr. It can manage and download subtitles based on your requirements. You define your preferences by TV show or movie and Bazarr takes care of everything for you.\" \ --no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \ - --provenance=false --sbom=false \ + --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}:amd64-${META_TAG} ${i}:amd64-${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}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & + done + for p in $(jobs -p); do + wait "$p" || { echo "job $p failed" >&2; exit 1; } + done + fi + ''' + } + } } } stage('Build ARM64') { @@ -595,10 +707,6 @@ pipeline { } steps { echo "Running on node: ${NODE_NAME}" - echo 'Logging into Github' - sh '''#! /bin/bash - echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin - ''' sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64" sh "docker buildx build \ --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ @@ -614,18 +722,50 @@ pipeline { --label \"org.opencontainers.image.title=Bazarr\" \ --label \"org.opencontainers.image.description=[Bazarr](https://www.bazarr.media/) is a companion application to Sonarr and Radarr. It can manage and download subtitles based on your requirements. You define your preferences by TV show or movie and Bazarr takes care of everything for you.\" \ --no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \ - --provenance=false --sbom=false \ + --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 "docker tag ${IMAGE}:arm64v8-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}" - retry_backoff(5,5) { - sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}" + sh '''#! /bin/bash + set -e + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker tag ${IMAGE}:arm64v8-${META_TAG} ${i}:arm64v8-${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}:arm64v8-${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 -af --volumes || : ''' + docker system prune -f --volumes || : + docker image prune -af || : + ''' } } } @@ -729,6 +869,14 @@ pipeline { } sh '''#! /bin/bash set -e + if grep -q 'docker-baseimage' <<< "${LS_REPO}"; then + echo "Detected baseimage, setting LSIO_FIRST_PARTY=true" + if [ -n "${CI_DOCKERENV}" ]; then + CI_DOCKERENV="LSIO_FIRST_PARTY=true|${CI_DOCKERENV}" + else + CI_DOCKERENV="LSIO_FIRST_PARTY=true" + fi + fi docker pull ghcr.io/linuxserver/ci:latest if [ "${MULTIARCH}" == "true" ]; then docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64 @@ -741,6 +889,7 @@ pipeline { -e DOCKER_LOGS_TIMEOUT=\"${CI_DELAY}\" \ -e TAGS=\"${CI_TAGS}\" \ -e META_TAG=\"${META_TAG}\" \ + -e RELEASE_TAG=\"latest\" \ -e PORT=\"${CI_PORT}\" \ -e SSL=\"${CI_SSL}\" \ -e BASE=\"${DIST_IMAGE}\" \ @@ -750,6 +899,7 @@ pipeline { -e WEB_SCREENSHOT=\"${CI_WEB}\" \ -e WEB_AUTH=\"${CI_AUTH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \ + -e NODE_NAME=\"${NODE_NAME}\" \ -t ghcr.io/linuxserver/ci:latest \ python3 test_build.py''' } @@ -765,37 +915,23 @@ pipeline { environment name: 'EXIT_STATUS', value: '' } steps { - 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 - for PUSHIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do - docker tag ${IMAGE}:${META_TAG} ${PUSHIMAGE}:${META_TAG} - docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:latest - docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${EXT_RELEASE_TAG} - if [ -n "${SEMVER}" ]; then - docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${SEMVER} - fi - docker push ${PUSHIMAGE}:latest - docker push ${PUSHIMAGE}:${META_TAG} - docker push ${PUSHIMAGE}:${EXT_RELEASE_TAG} - if [ -n "${SEMVER}" ]; then - docker push ${PUSHIMAGE}:${SEMVER} - fi + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + for PUSHIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do + [[ ${PUSHIMAGE%%/*} =~ \\. ]] && PUSHIMAGEPLUS="${PUSHIMAGE}" || PUSHIMAGEPLUS="docker.io/${PUSHIMAGE}" + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + if [[ "${PUSHIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then + CACHEIMAGE=${i} + fi 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} + if [ -n "${SEMVER}" ]; then + docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} + fi + done + ''' } } } @@ -806,57 +942,34 @@ pipeline { environment name: 'EXIT_STATUS', value: '' } steps { - 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 [ "${CI}" == "false" ]; 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} + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do + [[ ${MANIFESTIMAGE%%/*} =~ \\. ]] && MANIFESTIMAGEPLUS="${MANIFESTIMAGE}" || MANIFESTIMAGEPLUS="docker.io/${MANIFESTIMAGE}" + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + if [[ "${MANIFESTIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then + CACHEIMAGE=${i} + fi + 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} + 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} fi - for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do - docker tag ${IMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} - docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-latest - docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} - docker tag ${IMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-latest - docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} - if [ -n "${SEMVER}" ]; then - docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${SEMVER} - docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${SEMVER} - fi - docker push ${MANIFESTIMAGE}:amd64-${META_TAG} - docker push ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} - docker push ${MANIFESTIMAGE}:amd64-latest - docker push ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker push ${MANIFESTIMAGE}:arm64v8-latest - docker push ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} - if [ -n "${SEMVER}" ]; then - docker push ${MANIFESTIMAGE}:amd64-${SEMVER} - docker push ${MANIFESTIMAGE}:arm64v8-${SEMVER} - 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}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${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} - fi - done - ''' - } + 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}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${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} + fi + done + ''' } } } @@ -884,7 +997,7 @@ pipeline { echo '{"tag_name":"'${META_TAG}'",\ "target_commitish": "master",\ "name": "'${META_TAG}'",\ - "body": "**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**'${EXT_REPO}' Changes:**\\n\\n' > start + "body": "**CI Report:**\\n\\n'${CI_URL:-N/A}'\\n\\n**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**Remote Changes:**\\n\\n' > start printf '","draft": false,"prerelease": false}' >> releasebody.json paste -d'\\0' start releasebody.json > releasebody.json.done curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done''' @@ -1017,29 +1130,67 @@ EOF git config --global --unset commit.gpgsign ''' script{ + env.JOB_DATE = sh( + script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''', + returnStdout: true).trim() if (env.EXIT_STATUS == "ABORTED"){ sh 'echo "build aborted"' - } - else if (currentBuild.currentResult == "SUCCESS"){ - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 1681177,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** Success\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ - "username": "Jenkins"}' ${BUILDS_DISCORD} ''' - } - else { - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 16711680,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** failure\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ + }else{ + if (currentBuild.currentResult == "SUCCESS"){ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=1681177 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + }else{ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=16711680 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + } + sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"'color'": '${JOB_WEBHOOK_COLOUR}',\ + "footer": {"text" : "'"${JOB_WEBHOOK_FOOTER}"'"},\ + "timestamp": "'${JOB_DATE}'",\ + "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** '${JOB_WEBHOOK_STATUS}'\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ "username": "Jenkins"}' ${BUILDS_DISCORD} ''' } } } cleanup { sh '''#! /bin/bash - echo "Performing docker system prune!!" - containers=$(docker ps -aq) + echo "Pruning builder!!" + docker builder prune -f --builder container || : + containers=$(docker ps -q) if [[ -n "${containers}" ]]; then - docker stop ${containers} + BUILDX_CONTAINER_ID=$(docker ps -qf 'name=buildx_buildkit') + for container in ${containers}; do + if [[ "${container}" == "${BUILDX_CONTAINER_ID}" ]]; then + echo "skipping buildx container in docker stop" + else + echo "Stopping container ${container}" + docker stop ${container} + fi + done fi - docker system prune -af --volumes || : + docker system prune -f --volumes || : + docker image prune -af || : ''' cleanWs() } diff --git a/README.md b/README.md index e69fe83..20e99f2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)](https://linuxserver.io) [![Blog](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Blog)](https://blog.linuxserver.io "all the things you can do with our containers including How-To guides, opinions and much more!") -[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://discord.gg/YWrKVTn "realtime support / chat with the community and the team.") +[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://linuxserver.io/discord "realtime support / chat with the community and the team.") [![Discourse](https://img.shields.io/discourse/https/discourse.linuxserver.io/topics.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=discourse)](https://discourse.linuxserver.io "post on our community forum.") [![Fleet](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Fleet)](https://fleet.linuxserver.io "an online web interface which displays all of our maintained images.") [![GitHub](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub&logo=github)](https://github.com/linuxserver "view the source for all of our repositories.") @@ -20,7 +20,7 @@ The [LinuxServer.io](https://linuxserver.io) team brings you another container r Find us at: * [Blog](https://blog.linuxserver.io) - all the things you can do with our containers including How-To guides, opinions and much more! -* [Discord](https://discord.gg/YWrKVTn) - realtime support / chat with the community and the team. +* [Discord](https://linuxserver.io/discord) - realtime support / chat with the community and the team. * [Discourse](https://discourse.linuxserver.io) - post on our community forum. * [Fleet](https://fleet.linuxserver.io) - an online web interface which displays all of our maintained images. * [GitHub](https://github.com/linuxserver) - view the source for all of our repositories. @@ -75,11 +75,17 @@ This image provides various versions that are available via tags. Please read th This image can be run with a read-only container filesystem. For details please [read the docs](https://docs.linuxserver.io/misc/read-only/). +## Non-Root Operation + +This image can be run with a non-root user. For details please [read the docs](https://docs.linuxserver.io/misc/non-root/). ## Usage To help you get started creating a container from this image you can either use docker-compose or the docker cli. +>[!NOTE] +>Unless a parameter is flaged as 'optional', it is *mandatory* and a value must be provided. + ### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) ```yaml @@ -123,7 +129,7 @@ Containers are configured using parameters passed at runtime (such as those abov | Parameter | Function | | :----: | --- | -| `-p 6767` | Allows HTTP access to the internal webserver. | +| `-p 6767:6767` | Allows HTTP access to the internal webserver. | | `-e PUID=1000` | for UserID - see below for explanation | | `-e PGID=1000` | for GroupID - see below for explanation | | `-e TZ=Etc/UTC` | specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List). | @@ -131,6 +137,7 @@ Containers are configured using parameters passed at runtime (such as those abov | `-v /movies` | Location of your movies | | `-v /tv` | Location of your TV Shows | | `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). | +| `--user=1000:1000` | Run container with a non-root user. Please [read the docs](https://docs.linuxserver.io/misc/non-root/). | ## Environment variables from files (Docker secrets) @@ -268,7 +275,8 @@ Below are the instructions for updating containers: ### Image Update Notifications - Diun (Docker Image Update Notifier) -**tip**: We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. +>[!TIP] +>We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. ## Building locally @@ -283,16 +291,17 @@ docker build \ -t lscr.io/linuxserver/bazarr:latest . ``` -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static` ```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset +docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset ``` Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. ## Versions +* **24.12.24:** - Rebase to Alpine 3.21. * **24.06.24:** - Rebase to Alpine 3.20. * **23.12.23:** - Rebase to Alpine 3.19. * **19.09.23:** - Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar). diff --git a/package_versions.txt b/package_versions.txt index ac16649..f617340 100644 --- a/package_versions.txt +++ b/package_versions.txt @@ -1,306 +1,306 @@ -NAME VERSION TYPE -Simple Launcher 1.1.0.14 dotnet (+5 duplicates) -alembic 1.13.1 python -alpine-baselayout 3.6.5-r0 apk -alpine-baselayout-data 3.6.5-r0 apk -alpine-keys 2.4-r1 apk -alpine-release 3.20.2-r0 apk -alsa-lib 1.2.11-r0 apk -aniso8601 9.0.1 python -aom-libs 3.9.1-r0 apk -apk-tools 2.14.4-r0 apk -appdirs 1.4.4 python -apprise 1.7.6 python -apscheduler 3.10.4 python -argparse 1.4.0 python -attrs 23.2.0 python -auditok 0.1.5 python -autocommand 2.2.2 python -babelfish 0.6.0 python -backports-functools-lru-cache 2.0.0 python -backports-tarfile 1.2.0 python -backports-zoneinfo 0.2.1 python -bash 5.2.26-r0 apk -beautifulsoup4 4.12.3 python -bidict 0.23.1 python -blinker 1.7.0 python -brotli-libs 1.1.0-r2 apk -busybox 1.36.1-r29 apk -busybox-binsh 1.36.1-r29 apk -c-ares 1.28.1-r0 apk -ca-certificates 20240705-r0 apk -ca-certificates-bundle 20240705-r0 apk -catatonit 0.2.0-r0 apk -certifi 2024.2.2 python -chardet 5.2.0 python -charset-normalizer 3.3.2 python -cjson 1.7.18-r0 apk -click 8.1.7 python -cloudscraper 1.2.58 python -colorama 0.4.6 python -commonmark 0.9.1 python -coreutils 9.5-r1 apk -coreutils-env 9.5-r1 apk -coreutils-fmt 9.5-r1 apk -coreutils-sha512sum 9.5-r1 apk -curl 8.9.1-r1 apk -dbus-libs 1.14.10-r1 apk -decorator 5.1.1 python -deep-translator 1.11.4 python -dnspython 2.6.1 python -dogpile-cache 1.3.2 python -dynaconf 3.2.4 python -enzyme 0.4.1 python -fcache 0.5.2 python -fese 0.2.9 python -ffmpeg 6.1.1-r8 apk -ffmpeg-libavcodec 6.1.1-r8 apk -ffmpeg-libavdevice 6.1.1-r8 apk -ffmpeg-libavfilter 6.1.1-r8 apk -ffmpeg-libavformat 6.1.1-r8 apk -ffmpeg-libavutil 6.1.1-r8 apk -ffmpeg-libpostproc 6.1.1-r8 apk -ffmpeg-libswresample 6.1.1-r8 apk -ffmpeg-libswscale 6.1.1-r8 apk -ffmpeg-python 0.2.0 python -ffsubsync 0.4.25 python -findutils 4.9.0-r5 apk -flask 3.0.2 python -flask-cors 4.0.0 python -flask-migrate 4.0.5 python -flask-restx 1.3.0 python -flask-socketio 5.3.6 python -flask-sqlalchemy 3.1.1 python -fontconfig 2.15.0-r1 apk -freetype 2.13.2-r0 apk -fribidi 1.0.15-r0 apk -ftfy 6.1.3 python -future 1.0.0 python -ga4mp 2.0.4 python -gdbm 1.23-r1 apk -giflib 5.2.2-r0 apk -glib 2.80.2-r0 apk -glslang-libs 1.3.261.1-r0 apk -graphite2 1.3.14-r6 apk -guess-language-spirit 0.5.3 python -guessit 3.8.0 python -h11 0.14.0 python -harfbuzz 8.5.0-r0 apk -html5lib 1.1 python -hwdata-pci 0.382-r0 apk -idna 3.6 python -imath 3.1.11-r2 apk -importlib-metadata 7.0.1 python -importlib-metadata 8.0.0 python -importlib-resources 6.1.2 python -importlib-resources 6.4.0 python -inflect 7.0.0 python -inflect 7.3.1 python -itsdangerous 2.1.2 python -jaraco-context 5.3.0 python -jaraco-functools 4.0.1 python -jaraco-text 3.12.1 python -jinja2 3.1.3 python -jq 1.7.1-r0 apk -js2py 0.74 python -json-tricks 3.17.3 python -jsonschema 4.17.3 python -knowit 0.5.2 python -lame-libs 3.100-r5 apk -lcms2 2.16-r0 apk -libSvtAv1Enc 2.0.0-r1 apk -libacl 2.3.2-r0 apk -libass 0.17.2-r0 apk -libasyncns 0.8-r3 apk -libattr 2.5.2-r0 apk -libblkid 2.40.1-r1 apk -libbluray 1.3.4-r1 apk -libbsd 0.12.2-r0 apk -libbz2 1.0.8-r6 apk -libcrypto3 3.3.1-r3 apk -libcurl 8.9.1-r1 apk -libdav1d 1.4.2-r0 apk -libdovi 3.3.0-r0 apk -libdrm 2.4.120-r0 apk -libeconf 0.6.3-r0 apk -libexpat 2.6.2-r0 apk -libffi 3.4.6-r0 apk -libflac 1.4.3-r1 apk -libgcc 13.2.1_git20240309-r0 apk -libgcrypt 1.10.3-r0 apk -libgomp 13.2.1_git20240309-r0 apk -libgpg-error 1.49-r0 apk -libhwy 1.0.7-r0 apk -libidn2 2.3.7-r0 apk -libintl 0.22.5-r0 apk -libjpeg-turbo 3.0.3-r0 apk -libjxl 0.10.2-r0 apk -libltdl 2.4.7-r3 apk -libmd 1.1.0-r0 apk -libmediainfo 24.04-r0 apk -libmount 2.40.1-r1 apk -libncursesw 6.4_p20240420-r0 apk -libogg 1.3.5-r5 apk -libopenmpt 0.7.7-r0 apk -libpanelw 6.4_p20240420-r0 apk -libpciaccess 0.18.1-r0 apk -libplacebo 6.338.2-r1 apk -libpng 1.6.43-r0 apk -libproc2 4.0.4-r0 apk -libpsl 0.21.5-r1 apk -libpulse 17.0-r0 apk -librist 0.2.10-r1 apk -libsharpyuv 1.3.2-r0 apk -libsndfile 1.2.2-r0 apk -libsodium 1.0.19-r0 apk -libsrt 1.5.3-r0 apk -libssh 0.10.6-r0 apk -libssl3 3.3.1-r3 apk -libstdc++ 13.2.1_git20240309-r0 apk -libtheora 1.1.1-r18 apk -libunibreak 6.1-r0 apk -libunistring 1.2-r0 apk -libva 2.21.0-r0 apk -libvdpau 1.5-r3 apk -libvorbis 1.3.7-r2 apk -libvpx 1.14.1-r0 apk -libwebp 1.3.2-r0 apk -libwebpmux 1.3.2-r0 apk -libx11 1.8.9-r1 apk -libxau 1.0.11-r4 apk -libxcb 1.16.1-r0 apk -libxdmcp 1.1.5-r1 apk -libxext 1.3.6-r2 apk -libxfixes 6.0.1-r4 apk -libxml2 2.12.7-r0 apk -libxslt 1.1.39-r1 apk -libzen 0.4.41-r0 apk -libzmq 4.3.5-r2 apk -lilv-libs 0.24.24-r1 apk -linux-pam 1.6.0-r0 apk -lxml 4.9.4 python -mako 1.3.2 python -markdown 3.5.2 python -markupsafe 2.1.5 python -mbedtls 3.6.1-r0 apk -mediainfo 24.04-r0 apk -more-itertools 10.3.0 python -mpdecimal 4.0.0-r0 apk -mpg123-libs 1.32.6-r0 apk -msgpack 1.0.7 python -musl 1.2.5-r0 apk -musl-utils 1.2.5-r0 apk -my-test-package 1.0 python -ncurses-terminfo-base 6.4_p20240420-r0 apk -netcat-openbsd 1.226-r0 apk -nghttp2-libs 1.62.1-r0 apk -numactl 2.0.18-r0 apk -numpy 2.1.1 python -oauthlib 3.2.2 python -onevpl-libs 2023.3.1-r2 apk -oniguruma 6.9.9-r0 apk -openexr-libiex 3.1.13-r1 apk -openexr-libilmthread 3.1.13-r1 apk -openexr-libopenexr 3.1.13-r1 apk -opus 1.5.2-r0 apk -orc 0.4.37-r0 apk -packaging 24.1 python -pcre2 10.43-r0 apk -pillow 10.4.0 python -pip 24.2 python -platformdirs 4.2.0 python -platformdirs 4.2.2 python -procps-ng 4.0.4-r0 apk -psycopg2-binary 2.9.9 python -pyc 3.12.3-r2 apk -pycountry 23.12.11 python -pydantic 1.10.14 python -pygments 2.17.2 python -pyjsparser 2.7.1 python -pymediainfo 6.1.0 python -pyparsing 3.1.1 python -pyrsistent 0.20.0 python -pysocks 1.7.1 python -pysrt 1.1.2 python -pysubs2 1.6.1 python -python-anticaptcha 1.0.0 python -python-dateutil 2.8.2 python -python-engineio 4.9.0 python -python-socketio 5.11.1 python -python3 3.12.3-r2 apk -python3-pyc 3.12.3-r2 apk -python3-pycache-pyc0 3.12.3-r2 apk -pytz 2024.1 python -pytz-deprecation-shim 0.1.0.post0 python -pyyaml 6.0.1 python -rarfile 4.1 python -rav1e-libs 0.7.1-r0 apk -readline 8.2.10-r0 apk -rebulk 3.2.0 python -referencing 0.23.0 python -requests 2.31.0 python -requests-oauthlib 1.3.1 python -requests-toolbelt 1.0.0 python -retry 0.9.2 python -rich 13.7.0 python -scanelf 1.3.7-r2 apk -sdl2 2.28.5-r1 apk -semver 3.0.2 python -serd-libs 0.32.2-r0 apk -setuptools 74.1.1 python -shaderc 2024.0-r0 apk -shadow 4.15.1-r0 apk -signalrcore 0.9.5 python -simple-websocket 1.0.0 python -six 1.16.0 python -skalibs 2.14.1.1-r0 apk -sord-libs 0.16.16-r0 apk -soupsieve 2.3.2.post1 python -soxr 0.1.3-r7 apk -speexdsp 1.2.1-r2 apk -spirv-tools 1.3.261.1-r0 apk -sqlalchemy 2.0.27 python -sqlite-libs 3.45.3-r1 apk -sratom 0.6.16-r0 apk -srt 3.5.3 python -ssl_client 1.36.1-r29 apk -stevedore 5.2.0 python -tdb-libs 1.4.9-r1 apk -tinyxml2 10.0.0-r0 apk -tld 0.13 python -tomli 2.0.1 python -tqdm 4.66.2 python -trakit 0.2.1 python -typeguard 4.3.0 python -typing-extensions 4.10.0 python -typing-extensions 4.12.2 python -tzdata 2024.1 python -tzdata 2024a-r1 apk -tzlocal 5.2 python -unidecode 1.3.8 python -urllib3 2.2.1 python -utmps-libs 0.1.2.2-r1 apk -v4l-utils-libs 1.24.1-r1 apk -vidstab 1.1.1-r0 apk -vulkan-loader 1.3.261.1-r0 apk -waitress 3.0.0 python -wayland-libs-client 1.22.0-r4 apk -wcwidth 0.2.13 python -webencodings 0.5.1 python -webrtcvad-wheels 2.0.12 python -websocket-client 1.7.0 python -werkzeug 3.0.1 python -wheel 0.43.0 python -wheel 0.44.0 python -whichcraft 0.6.1 python -wsproto 1.2.0 python -x264-libs 0.164_git20231001-r0 apk -x265-libs 3.6-r0 apk -xvidcore 1.3.7-r2 apk -xz-libs 5.6.2-r0 apk -zimg 3.0.5-r2 apk -zipp 3.17.0 python -zipp 3.19.2 python -zix-libs 0.4.2-r0 apk -zlib 1.3.1-r1 apk -zstd-libs 1.5.6-r0 apk +NAME VERSION TYPE +acl-libs 2.3.2-r1 apk +alembic 1.13.1 python +alpine-baselayout 3.6.8-r1 apk +alpine-baselayout-data 3.6.8-r1 apk +alpine-keys 2.5-r0 apk +alpine-release 3.21.3-r0 apk +alsa-lib 1.2.12-r0 apk +aniso8601 9.0.1 python +aom-libs 3.11.0-r0 apk +apk-tools 2.14.6-r3 apk +appdirs 1.4.4 python +apprise 1.7.6 python +apscheduler 3.10.4 python +attrs 23.2.0 python +auditok 0.1.5 python +autocommand 2.2.2 python +babelfish 0.6.0 python +backports-functools-lru-cache 2.0.0 python +backports-tarfile 1.2.0 python +backports-zoneinfo 0.2.1 python +bash 5.2.37-r0 apk +beautifulsoup4 4.12.3 python +bidict 0.23.1 python +blinker 1.7.0 python +brotli-libs 1.1.0-r2 apk +busybox 1.37.0-r12 apk +busybox-binsh 1.37.0-r12 apk +c-ares 1.34.5-r0 apk +ca-certificates 20241121-r1 apk +ca-certificates-bundle 20241121-r1 apk +catatonit 0.2.0-r0 apk +certifi 2024.2.2 python +chardet 5.2.0 python +charset-normalizer 3.3.2 python +cjson 1.7.18-r0 apk +click 8.1.7 python +cloudscraper 1.2.58 python +colorama 0.4.6 python +commonmark 0.9.1 python +coreutils 9.5-r2 apk +coreutils-env 9.5-r2 apk +coreutils-fmt 9.5-r2 apk +coreutils-sha512sum 9.5-r2 apk +curl 8.12.1-r1 apk +dbus-libs 1.14.10-r4 apk +decorator 5.1.1 python +deep-translator 1.11.4 python +dnspython 2.6.1 python +dogpile-cache 1.3.2 python +dynaconf 3.2.4 python +enzyme 0.4.1 python +fcache 0.5.2 python +fese 0.3.0 python +ffmpeg 6.1.2-r1 apk +ffmpeg-libavcodec 6.1.2-r1 apk +ffmpeg-libavdevice 6.1.2-r1 apk +ffmpeg-libavfilter 6.1.2-r1 apk +ffmpeg-libavformat 6.1.2-r1 apk +ffmpeg-libavutil 6.1.2-r1 apk +ffmpeg-libpostproc 6.1.2-r1 apk +ffmpeg-libswresample 6.1.2-r1 apk +ffmpeg-libswscale 6.1.2-r1 apk +ffmpeg-python 0.2.0 python +ffsubsync 0.4.25 python +findutils 4.10.0-r0 apk +flask 3.0.2 python +flask-cors 4.0.0 python +flask-migrate 4.0.5 python +flask-restx 1.3.0 python +flask-socketio 5.3.6 python +flask-sqlalchemy 3.1.1 python +fontconfig 2.15.0-r1 apk +freetype 2.13.3-r0 apk +fribidi 1.0.16-r0 apk +ftfy 6.1.3 python +future 1.0.0 python +ga4mp 2.0.4 python +gdbm 1.24-r0 apk +giflib 5.2.2-r1 apk +glib 2.82.5-r0 apk +glslang-libs 1.3.296.0-r0 apk +graphite2 1.3.14-r6 apk +guess-language-spirit 0.5.3 python +guessit 3.8.0 python +h11 0.14.0 python +harfbuzz 9.0.0-r1 apk +html5lib 1.1 python +hwdata-pci 0.393-r0 apk +idna 3.6 python +imath 3.1.12-r0 apk +importlib-metadata 7.0.1 python +importlib-metadata 8.0.0 python +importlib-resources 6.1.2 python +inflect 7.0.0 python +inflect 7.3.1 python +itsdangerous 2.1.2 python +jaraco-collections 5.1.0 python +jaraco-context 5.3.0 python +jaraco-functools 4.0.1 python +jaraco-text 3.12.1 python +jinja2 3.1.3 python +jq 1.7.1-r0 apk +js2py 0.74 python +json-tricks 3.17.3 python +jsonschema 4.17.3 python +knowit 0.5.3 python +lame-libs 3.100-r5 apk +lcms2 2.16-r0 apk +libSvtAv1Enc 2.2.1-r0 apk +libass 0.17.3-r0 apk +libasyncns 0.8-r4 apk +libattr 2.5.2-r2 apk +libblkid 2.40.4-r1 apk +libbluray 1.3.4-r1 apk +libbsd 0.12.2-r0 apk +libbz2 1.0.8-r6 apk +libcrypto3 3.3.3-r0 apk +libcurl 8.12.1-r1 apk +libdav1d 1.5.0-r0 apk +libdeflate 1.22-r0 apk +libdovi 3.3.1-r0 apk +libdrm 2.4.123-r1 apk +libeconf 0.6.3-r0 apk +libexpat 2.7.0-r0 apk +libffi 3.4.7-r0 apk +libflac 1.4.3-r1 apk +libgcc 14.2.0-r4 apk +libgcrypt 1.10.3-r1 apk +libgomp 14.2.0-r4 apk +libgpg-error 1.51-r0 apk +libhwy 1.0.7-r0 apk +libidn2 2.3.7-r0 apk +libintl 0.22.5-r0 apk +libjpeg-turbo 3.0.4-r0 apk +libjxl 0.10.4-r0 apk +libltdl 2.4.7-r3 apk +libmd 1.1.0-r0 apk +libmediainfo 24.11-r0 apk +libmount 2.40.4-r1 apk +libncursesw 6.5_p20241006-r3 apk +libogg 1.3.5-r5 apk +libopenmpt 0.7.12-r0 apk +libpanelw 6.5_p20241006-r3 apk +libpciaccess 0.18.1-r0 apk +libplacebo 6.338.2-r3 apk +libpng 1.6.47-r0 apk +libproc2 4.0.4-r2 apk +libpsl 0.21.5-r3 apk +libpulse 17.0-r4 apk +librist 0.2.10-r1 apk +libsharpyuv 1.4.0-r0 apk +libsndfile 1.2.2-r2 apk +libsodium 1.0.20-r0 apk +libsrt 1.5.3-r0 apk +libssh 0.11.1-r0 apk +libssl3 3.3.3-r0 apk +libstdc++ 14.2.0-r4 apk +libtheora 1.1.1-r18 apk +libunibreak 6.1-r0 apk +libunistring 1.2-r0 apk +libva 2.22.0-r1 apk +libvdpau 1.5-r4 apk +libvorbis 1.3.7-r2 apk +libvpx 1.15.0-r0 apk +libwebp 1.4.0-r0 apk +libwebpmux 1.4.0-r0 apk +libx11 1.8.10-r0 apk +libxau 1.0.11-r4 apk +libxcb 1.16.1-r0 apk +libxdmcp 1.1.5-r1 apk +libxext 1.3.6-r2 apk +libxfixes 6.0.1-r4 apk +libxml2 2.13.4-r5 apk +libxslt 1.1.42-r2 apk +libzen 0.4.41-r0 apk +libzmq 4.3.5-r2 apk +lilv-libs 0.24.24-r1 apk +linux-pam 1.6.1-r1 apk +lxml 4.9.4 python +mako 1.3.2 python +markdown 3.5.2 python +markupsafe 2.1.5 python +mbedtls 3.6.3-r0 apk +mediainfo 24.11-r0 apk +more-itertools 10.3.0 python +mpdecimal 4.0.0-r0 apk +mpg123-libs 1.32.9-r0 apk +msgpack 1.0.7 python +musl 1.2.5-r9 apk +musl-utils 1.2.5-r9 apk +my-test-package 1.0 python +ncurses-terminfo-base 6.5_p20241006-r3 apk +netcat-openbsd 1.226.1.1-r0 apk +nghttp2-libs 1.64.0-r0 apk +numactl 2.0.18-r0 apk +numpy 2.2.5 python +oauthlib 3.2.2 python +onevpl-libs 2023.3.1-r2 apk +oniguruma 6.9.9-r0 apk +openexr-libiex 3.3.2-r0 apk +openexr-libilmthread 3.3.2-r0 apk +openexr-libopenexr 3.3.2-r0 apk +openexr-libopenexrcore 3.3.2-r0 apk +opus 1.5.2-r1 apk +orc 0.4.40-r1 apk +packaging 24.2 python +pcre2 10.43-r0 apk +pillow 11.2.1 python +pip 25.0.1 python +platformdirs 4.2.0 python +platformdirs 4.2.2 python +procps-ng 4.0.4-r2 apk +psycopg2-binary 2.9.10 python +pyc 3.12.10-r0 apk +pycountry 23.12.11 python +pydantic 1.10.14 python +pygments 2.17.2 python +pyjsparser 2.7.1 python +pymediainfo 6.1.0 python +pyparsing 3.1.1 python +pyrsistent 0.20.0 python +pysocks 1.7.1 python +pysrt 1.1.2 python +pysubs2 1.7.2 python +python-anticaptcha 1.0.0 python +python-dateutil 2.8.2 python +python-engineio 4.9.0 python +python-socketio 5.11.1 python +python3 3.12.10-r0 apk +python3-pyc 3.12.10-r0 apk +python3-pycache-pyc0 3.12.10-r0 apk +pytz 2024.1 python +pytz-deprecation-shim 0.1.0.post0 python +pyyaml 6.0.1 python +rarfile 4.1 python +rav1e-libs 0.7.1-r0 apk +readline 8.2.13-r0 apk +rebulk 3.2.0 python +referencing 0.23.0 python +requests 2.31.0 python +requests-oauthlib 1.3.1 python +requests-toolbelt 1.0.0 python +retry 0.9.2 python +rich 13.7.0 python +scanelf 1.3.8-r1 apk +sdl2 2.30.9-r0 apk +semver 3.0.2 python +serd-libs 0.32.2-r0 apk +setuptools 79.0.0 python +shaderc 2024.0-r2 apk +shadow 4.16.0-r1 apk +signalrcore 0.9.5 python +simple-websocket 1.0.0 python +six 1.16.0 python +skalibs-libs 2.14.3.0-r0 apk +sord-libs 0.16.16-r0 apk +soupsieve 2.3.2.post1 python +soxr 0.1.3-r7 apk +speexdsp 1.2.1-r2 apk +spirv-tools 1.3.296.0-r0 apk +sqlalchemy 2.0.27 python +sqlite-libs 3.48.0-r1 apk +sratom 0.6.16-r0 apk +srt 3.5.3 python +ssl_client 1.37.0-r12 apk +stevedore 5.2.0 python +tdb-libs 1.4.12-r0 apk +textdistance 4.6.2 python +tinyxml2 10.0.0-r0 apk +tld 0.13 python +tomli 2.0.1 python +tqdm 4.66.2 python +trakit 0.2.1 python +typeguard 4.3.0 python +typing-extensions 4.10.0 python +typing-extensions 4.12.2 python +tzdata 2024.1 python +tzdata 2025b-r0 apk +tzlocal 5.2 python +unidecode 1.3.8 python +urllib3 2.2.1 python +utmps-libs 0.1.2.3-r2 apk +v4l-utils-libs 1.28.1-r1 apk +vidstab 1.1.1-r0 apk +vulkan-loader 1.3.296.0-r0 apk +waitress 3.0.0 python +wayland-libs-client 1.23.1-r0 apk +wcwidth 0.2.13 python +webencodings 0.5.1 python +webrtcvad-wheels 2.0.14 python +websocket-client 1.7.0 python +werkzeug 3.0.1 python +wheel 0.45.1 python (+1 duplicate) +whichcraft 0.6.1 python +wsproto 1.2.0 python +x264-libs 0.164.3108-r0 apk +x265-libs 3.6-r0 apk +xvidcore 1.3.7-r2 apk +xz-libs 5.6.3-r1 apk +zimg 3.0.5-r2 apk +zipp 3.17.0 python +zipp 3.19.2 python +zix-libs 0.4.2-r0 apk +zlib 1.3.1-r2 apk +zstd-libs 1.5.6-r2 apk diff --git a/readme-vars.yml b/readme-vars.yml index 0bde643..2474560 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -6,6 +6,7 @@ project_url: "https://www.bazarr.media/" project_logo: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/bazarr.png" project_blurb: "[{{ project_name|capitalize }}]({{ project_url }}) is a companion application to Sonarr and Radarr. It can manage and download subtitles based on your requirements. You define your preferences by TV show or movie and Bazarr takes care of everything for you." project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}" +project_categories: "Media Management" # supported architectures available_architectures: - {arch: "{{ arch_x86_64 }}", tag: "amd64-latest"} @@ -18,7 +19,7 @@ development_versions_items: param_container_name: "{{ project_name }}" param_usage_include_vols: true param_volumes: - - { vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/config", desc: "Persistent config files" } + - {vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/config", desc: "Persistent config files"} param_usage_include_ports: true param_ports: - {external_port: "6767", internal_port: "6767", port_desc: "Allows HTTP access to the internal webserver."} @@ -26,16 +27,55 @@ opt_param_usage_include_vols: true opt_param_volumes: - {vol_path: "/movies", vol_host_path: "/path/to/movies", desc: "Location of your movies"} - {vol_path: "/tv", vol_host_path: "/path/to/tv", desc: "Location of your TV Shows"} - readonly_supported: true - +nonroot_supported: true # application setup block app_setup_block_enabled: true app_setup_block: | - Once running the URL will be `http://:6767`. - You must complete all the setup parameters in the webui before you can save the config. +# init diagram +init_diagram: | + "bazarr:latest": { + docker-mods + base { + fix-attr +\nlegacy cont-init + } + docker-mods -> base + legacy-services + custom services + init-services -> legacy-services + init-services -> custom services + custom services -> legacy-services + legacy-services -> ci-service-check + init-migrations -> init-adduser + init-config -> init-bazarr-config + init-os-end -> init-config + init-bazarr-config -> init-config-end + init-config -> init-config-end + init-crontab-config -> init-config-end + init-config -> init-crontab-config + init-mods-end -> init-custom-files + base -> init-envfile + base -> init-migrations + init-config-end -> init-mods + init-mods-package-install -> init-mods-end + init-mods -> init-mods-package-install + init-adduser -> init-os-end + init-envfile -> init-os-end + init-custom-files -> init-services + init-services -> svc-bazarr + svc-bazarr -> legacy-services + init-services -> svc-cron + svc-cron -> legacy-services + } + Base Images: { + "baseimage-alpine:3.21" + } + "bazarr:latest" <- Base Images # changelog changelogs: + - {date: "24.12.24:", desc: "Rebase to Alpine 3.21."} - {date: "24.06.24:", desc: "Rebase to Alpine 3.20."} - {date: "23.12.23:", desc: "Rebase to Alpine 3.19."} - {date: "19.09.23:", desc: "Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar)."} diff --git a/root/etc/s6-overlay/s6-rc.d/init-bazarr-config/run b/root/etc/s6-overlay/s6-rc.d/init-bazarr-config/run index ae4017a..e0c7233 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-bazarr-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-bazarr-config/run @@ -1,6 +1,7 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash -# permissions -lsiown -R abc:abc \ - /config +if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + lsiown -R abc:abc \ + /config +fi diff --git a/root/etc/s6-overlay/s6-rc.d/svc-bazarr/run b/root/etc/s6-overlay/s6-rc.d/svc-bazarr/run index 8581337..3df693a 100755 --- a/root/etc/s6-overlay/s6-rc.d/svc-bazarr/run +++ b/root/etc/s6-overlay/s6-rc.d/svc-bazarr/run @@ -1,6 +1,12 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash -exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 6767" \ - cd /app/bazarr/bin s6-setuidgid abc python3 /app/bazarr/bin/bazarr.py --no-update --config /config +if [[ -z ${LSIO_NON_ROOT_USER} ]]; then + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 6767" \ + cd /app/bazarr/bin s6-setuidgid abc python3 /app/bazarr/bin/bazarr.py --no-update --config /config +else + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 6767" \ + cd /app/bazarr/bin python3 /app/bazarr/bin/bazarr.py --no-update --config /config +fi