Compare commits

..

80 Commits

Author SHA1 Message Date
LinuxServer-CI
539cb0dde5 Bot Updating Templated Files 2025-02-02 06:53:02 +00:00
LinuxServer-CI
e5bbf12f75 Bot Updating Templated Files 2025-02-02 06:51:22 +00:00
LinuxServer-CI
c7e11607fd Bot Updating Package Versions 2025-01-19 06:51:44 +00:00
LinuxServer-CI
5fcd99d999 Bot Updating Package Versions 2025-01-12 06:52:13 +00:00
LinuxServer-CI
e68221b2c9 Bot Updating Package Versions 2025-01-05 06:51:26 +00:00
LinuxServer-CI
a98b645e63 Bot Updating Package Versions 2025-01-01 22:47:53 +00:00
LinuxServer-CI
b20d69c731 Bot Updating Templated Files 2025-01-01 22:44:54 +00:00
Adam
86351818ad Merge pull request #358 from linuxserver/libtorrent-nonroot 2025-01-01 22:43:30 +00:00
thespad
e23604ae59 Rebase to 3.21 2024-12-20 20:23:19 +00:00
LinuxServer-CI
02c653f874 Bot Updating Package Versions 2024-12-17 23:55:37 +00:00
LinuxServer-CI
e030b69d0a Bot Updating Templated Files 2024-12-17 23:50:55 +00:00
LinuxServer-CI
e29b91f07a Bot Updating Templated Files 2024-12-17 23:49:22 +00:00
LinuxServer-CI
d280e1e2ae Bot Updating Templated Files 2024-12-17 23:47:49 +00:00
LinuxServer-CI
9c8d0acdda Bot Updating Package Versions 2024-11-17 06:53:13 +00:00
LinuxServer-CI
d74f9599c4 Bot Updating Package Versions 2024-11-10 07:02:31 +00:00
LinuxServer-CI
5938779e2d Bot Updating Templated Files 2024-11-10 06:57:55 +00:00
LinuxServer-CI
c6c6bf07ad Bot Updating Templated Files 2024-11-10 06:50:23 +00:00
LinuxServer-CI
5a04d16c05 Bot Updating Package Versions 2024-10-13 06:51:14 +00:00
LinuxServer-CI
2a904cefc5 Bot Updating Package Versions 2024-10-08 12:36:28 +00:00
Adam
a8d106509d Merge pull request #334 from linuxserver/libtorrentv1-dynamic-bind-address 2024-10-08 13:33:44 +01:00
thespad
1d653ed218 Read webui bind address from config if present 2024-10-08 11:08:25 +01:00
LinuxServer-CI
a6894b3176 Bot Updating Package Versions 2024-09-29 06:56:27 +00:00
LinuxServer-CI
92a35d0164 Bot Updating Templated Files 2024-09-29 06:54:23 +00:00
LinuxServer-CI
2d087d62dd Bot Updating Templated Files 2024-09-29 06:53:09 +00:00
LinuxServer-CI
844b27b8f8 Bot Updating Templated Files 2024-09-29 06:51:17 +00:00
LinuxServer-CI
41d1396423 Bot Updating Package Versions 2024-09-22 06:52:13 +00:00
LinuxServer-CI
47ccea6dca Bot Updating Package Versions 2024-09-15 06:51:23 +00:00
LinuxServer-CI
68d130f4da Bot Updating Package Versions 2024-09-08 06:51:02 +00:00
LinuxServer-CI
51a149fb83 Bot Updating Package Versions 2024-09-01 06:51:12 +00:00
LinuxServer-CI
986c774504 Bot Updating Package Versions 2024-08-25 06:51:05 +00:00
LinuxServer-CI
497dba9399 Bot Updating Package Versions 2024-08-19 20:49:41 +00:00
LinuxServer-CI
4b3cc2ac70 Bot Updating Templated Files 2024-08-18 06:52:52 +00:00
LinuxServer-CI
6c51663d65 Bot Updating Templated Files 2024-08-18 06:50:46 +00:00
LinuxServer-CI
ca0d25caa5 Bot Updating Package Versions 2024-08-11 06:51:51 +00:00
LinuxServer-CI
c6bc0cddb5 Bot Updating Package Versions 2024-07-28 06:52:32 +00:00
LinuxServer-CI
b07685bd87 Bot Updating Package Versions 2024-07-17 10:45:33 +00:00
thespad
9df948f0c8 Fix static version in url 2024-07-17 11:42:46 +01:00
thespad
d7ed4941f7 Use netcore 6 version 2024-07-17 11:23:19 +01:00
LinuxServer-CI
6a2f34d79e Bot Updating Package Versions 2024-07-17 10:22:23 +00:00
LinuxServer-CI
3ea4f46afe Bot Updating Templated Files 2024-07-17 10:19:49 +00:00
thespad
4961e321ff Fix amd64 cli path 2024-07-17 11:19:29 +01:00
thespad
4e390f3a02 libtorrent-cli 2024-07-17 11:17:28 +01:00
LinuxServer-CI
44b28c3b54 Bot Updating Package Versions 2024-07-14 06:55:52 +00:00
LinuxServer-CI
5f2da2e99c Bot Updating Templated Files 2024-07-14 06:53:08 +00:00
LinuxServer-CI
f22be93348 Bot Updating Templated Files 2024-07-14 06:51:38 +00:00
LinuxServer-CI
5ebec66860 Bot Updating Templated Files 2024-07-08 15:21:12 +00:00
Roxedus
e7047c96fc Merge pull request #315 from linuxserver/libtorrentv1-ro-tweaks
Don't chown /downloads unless it's mounted (libtorrentv1)
2024-07-08 17:19:50 +02:00
thespad
c11e773eba Don't chown /downloads unless it's mounted 2024-07-03 19:18:38 +01:00
LinuxServer-CI
5640e3bd89 Bot Updating Package Versions 2024-06-30 06:51:13 +00:00
LinuxServer-CI
666fe44a8a Bot Updating Package Versions 2024-06-23 06:51:28 +00:00
LinuxServer-CI
bb21bcf90f Bot Updating Package Versions 2024-06-16 06:51:06 +00:00
LinuxServer-CI
e7b61f7994 Bot Updating Package Versions 2024-06-09 06:52:38 +00:00
LinuxServer-CI
810273f461 Bot Updating Package Versions 2024-05-25 20:28:18 +00:00
thespad
86154fa26e Rebase to 3.20, drop qbittorrent-cli 2024-05-25 21:24:48 +01:00
LinuxServer-CI
7bedef788a Bot Updating Package Versions 2024-05-12 06:54:33 +00:00
LinuxServer-CI
bd5ffc3227 Bot Updating Templated Files 2024-05-12 06:50:41 +00:00
LinuxServer-CI
da745fb734 Bot Updating Templated Files 2024-05-05 06:50:40 +00:00
LinuxServer-CI
0d6981aab8 Bot Updating Package Versions 2024-04-21 06:51:16 +00:00
LinuxServer-CI
46e26ac70b Bot Updating Package Versions 2024-04-14 08:11:03 +00:00
LinuxServer-CI
07590b23cf Bot Updating Package Versions 2024-04-07 06:52:49 +00:00
LinuxServer-CI
91009f15e1 Bot Updating Package Versions 2024-03-31 06:51:36 +00:00
LinuxServer-CI
bb4f22f56e Bot Updating Package Versions 2024-03-24 06:51:32 +00:00
LinuxServer-CI
171f1b0f20 Bot Updating Package Versions 2024-03-17 06:53:22 +00:00
LinuxServer-CI
846566a3ce Bot Updating Templated Files 2024-03-17 06:50:49 +00:00
LinuxServer-CI
baeba6dc47 Bot Updating Package Versions 2024-03-03 06:51:20 +00:00
LinuxServer-CI
03b6f76ede Bot Updating Package Versions 2024-02-25 06:57:18 +00:00
LinuxServer-CI
ac87eba881 Bot Updating Templated Files 2024-02-25 06:53:46 +00:00
LinuxServer-CI
63d4188270 Bot Updating Templated Files 2024-02-25 06:52:07 +00:00
aptalca
fac6120d82 Merge pull request #292 from linuxserver/libtorrentv1-tport
libtorrentv1: do not override torrenting port unless var is set
2024-02-14 15:25:47 -05:00
aptalca
4e9eda5c12 do not override torrenting port unless var is set 2024-02-14 14:59:35 -05:00
Adam
b6b32830b6 Merge pull request #290 from pcdevil/feat/torrenting-port-libtorrentv1
Add torrenting port configuration support for libtorrentv1 branch
2024-02-14 10:18:16 +00:00
LinuxServer-CI
ca71be8c09 Bot Updating Package Versions 2024-02-11 06:51:43 +00:00
Attila Gonda
f770749b51 Add torrenting port configuration support 2024-02-10 12:09:09 +00:00
LinuxServer-CI
bfd0a20156 Bot Updating Package Versions 2024-02-04 06:53:34 +00:00
LinuxServer-CI
91685b2fc3 Bot Updating Package Versions 2024-02-01 09:18:44 +00:00
LinuxServer-CI
a957095eb8 Bot Updating Templated Files 2024-02-01 09:15:43 +00:00
Adam
e797c79f4a Merge pull request #285 from linuxserver/libtorrentv1-3.19
Rebase to Alpine 3.19 (libtorrentv1)
2024-02-01 09:13:14 +00:00
TheSpad
3f19347a19 Rebase to Alpine 3.19 (libtorrentv1) 2024-01-31 19:17:04 +00:00
LinuxServer-CI
784f894771 Bot Updating Package Versions 2024-01-28 06:51:35 +00:00
LinuxServer-CI
c52bb217f2 Bot Updating Package Versions 2024-01-21 06:51:33 +00:00
18 changed files with 1123 additions and 793 deletions

View File

@@ -6,7 +6,7 @@
* Read, and fill the Pull Request template * 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 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 #\<issue number>, in the body of the PR commit message * If the PR is addressing an existing issue include, closes #\<issue number>, 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 ## Common files
@@ -105,10 +105,10 @@ docker build \
-t linuxserver/qbittorrent:latest . -t linuxserver/qbittorrent: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 ```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`. Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`.

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Discord chat support - name: Discord chat support
url: https://discord.gg/YWrKVTn url: https://linuxserver.io/discord
about: Realtime support / chat with the community and the team. about: Realtime support / chat with the community and the team.
- name: Discourse discussion forum - name: Discourse discussion forum

View File

@@ -67,10 +67,10 @@ body:
- type: textarea - type: textarea
attributes: attributes:
description: | description: |
Provide a full docker log, output of "docker logs linuxserver.io" Provide a full docker log, output of "docker logs qbittorrent"
label: Container logs label: Container logs
placeholder: | placeholder: |
Output of `docker logs linuxserver.io` Output of `docker logs qbittorrent`
render: bash render: bash
validations: validations:
required: true required: true

View File

@@ -7,22 +7,35 @@ jobs:
external-trigger-libtorrentv1: external-trigger-libtorrentv1:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3.1.0 - uses: actions/checkout@v4.1.1
- name: External Trigger - name: External Trigger
if: github.ref == 'refs/heads/libtorrentv1' if: github.ref == 'refs/heads/libtorrentv1'
env:
SKIP_EXTERNAL_TRIGGER: ${{ vars.SKIP_EXTERNAL_TRIGGER }}
run: | run: |
if [ -n "${{ secrets.PAUSE_EXTERNAL_TRIGGER_QBITTORRENT_LIBTORRENTV1 }}" ]; then printf "# External trigger for docker-qbittorrent\n\n" >> $GITHUB_STEP_SUMMARY
echo "**** Github secret PAUSE_EXTERNAL_TRIGGER_QBITTORRENT_LIBTORRENTV1 is set; skipping trigger. ****" if grep -q "^qbittorrent_libtorrentv1_" <<< "${SKIP_EXTERNAL_TRIGGER}"; then
echo "Github secret \`PAUSE_EXTERNAL_TRIGGER_QBITTORRENT_LIBTORRENTV1\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY
echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`qbittorrent_libtorrentv1_\`; will skip trigger if version matches." >> $GITHUB_STEP_SUMMARY
elif grep -q "^qbittorrent_libtorrentv1" <<< "${SKIP_EXTERNAL_TRIGGER}"; then
echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`qbittorrent_libtorrentv1\`; skipping trigger." >> $GITHUB_STEP_SUMMARY
exit 0 exit 0
fi fi
echo "**** External trigger running off of libtorrentv1 branch. To disable this trigger, set a Github secret named \"PAUSE_EXTERNAL_TRIGGER_QBITTORRENT_LIBTORRENTV1\". ****" echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY
echo "External trigger running off of libtorrentv1 branch. To disable this trigger, set a Github secret named \`PAUSE_EXTERNAL_TRIGGER_QBITTORRENT_LIBTORRENTV1\`" >> $GITHUB_STEP_SUMMARY echo "> External trigger running off of libtorrentv1 branch. To disable this trigger, add \`qbittorrent_libtorrentv1\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY
echo "**** Retrieving external version ****" printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY
EXT_RELEASE=$(curl -u ${{ secrets.CR_USER }}:${{ secrets.CR_PAT }} -sL 'https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases' | jq -r 'first(.[] | select(.prerelease == true) | .tag_name)') EXT_RELEASE=$(curl -u ${{ secrets.CR_USER }}:${{ secrets.CR_PAT }} -sL 'https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases' | jq -r 'first(.[] | select(.prerelease == true) | .tag_name)')
echo "Type is \`custom_version_command\`" >> $GITHUB_STEP_SUMMARY
if grep -q "^qbittorrent_libtorrentv1_${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 if [ -z "${EXT_RELEASE}" ] || [ "${EXT_RELEASE}" == "null" ]; then
echo "**** Can't retrieve external version, exiting ****" echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
echo "> Can't retrieve external version, exiting" >> $GITHUB_STEP_SUMMARY
FAILURE_REASON="Can't retrieve external version for qbittorrent branch libtorrentv1" FAILURE_REASON="Can't retrieve external version for qbittorrent branch libtorrentv1"
GHA_TRIGGER_URL="https://github.com/linuxserver/docker-qbittorrent/actions/runs/${{ github.run_id }}" GHA_TRIGGER_URL="https://github.com/linuxserver/docker-qbittorrent/actions/runs/${{ github.run_id }}"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680, curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680,
@@ -31,24 +44,42 @@ jobs:
exit 1 exit 1
fi fi
EXT_RELEASE=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g') EXT_RELEASE=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g')
echo "**** External version: ${EXT_RELEASE} ****" echo "External version: \`${EXT_RELEASE}\`" >> $GITHUB_STEP_SUMMARY
echo "External version: ${EXT_RELEASE}" >> $GITHUB_STEP_SUMMARY echo "Retrieving last pushed version" >> $GITHUB_STEP_SUMMARY
echo "**** Retrieving last pushed version ****"
image="linuxserver/qbittorrent" image="linuxserver/qbittorrent"
tag="libtorrentv1" tag="libtorrentv1"
token=$(curl -sX GET \ token=$(curl -sX GET \
"https://ghcr.io/token?scope=repository%3Alinuxserver%2Fqbittorrent%3Apull" \ "https://ghcr.io/token?scope=repository%3Alinuxserver%2Fqbittorrent%3Apull" \
| jq -r '.token') | 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.docker.distribution.manifest.v2+json" \
--header "Accept: application/vnd.oci.image.manifest.v1+json" \
--header "Authorization: Bearer ${token}" \ --header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/manifests/${tag}" \ "https://ghcr.io/v2/${image}/manifests/${multidigest}"); then
| jq -r 'first(.manifests[].digest)') digest=$(jq -r '.config.digest' <<< "${digest}");
digest=$(curl -s \ fi
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ fi
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/manifests/${multidigest}" \
| jq -r '.config.digest')
image_info=$(curl -sL \ image_info=$(curl -sL \
--header "Authorization: Bearer ${token}" \ --header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/blobs/${digest}") "https://ghcr.io/v2/${image}/blobs/${digest}")
@@ -60,45 +91,54 @@ jobs:
IMAGE_RELEASE=$(echo ${image_info} | jq -r '.Labels.build_version' | awk '{print $3}') IMAGE_RELEASE=$(echo ${image_info} | jq -r '.Labels.build_version' | awk '{print $3}')
IMAGE_VERSION=$(echo ${IMAGE_RELEASE} | awk -F'-ls' '{print $1}') IMAGE_VERSION=$(echo ${IMAGE_RELEASE} | awk -F'-ls' '{print $1}')
if [ -z "${IMAGE_VERSION}" ]; then if [ -z "${IMAGE_VERSION}" ]; then
echo "**** Can't retrieve last pushed version, exiting ****" echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
echo "Can't retrieve last pushed version, exiting" >> $GITHUB_STEP_SUMMARY
FAILURE_REASON="Can't retrieve last pushed version for qbittorrent tag libtorrentv1" FAILURE_REASON="Can't retrieve last pushed version for qbittorrent tag libtorrentv1"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680, curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680,
"description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}], "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
exit 1 exit 1
fi fi
echo "**** Last pushed version: ${IMAGE_VERSION} ****" echo "Last pushed version: \`${IMAGE_VERSION}\`" >> $GITHUB_STEP_SUMMARY
echo "Last pushed version: ${IMAGE_VERSION}" >> $GITHUB_STEP_SUMMARY
if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then
echo "**** Version ${EXT_RELEASE} already pushed, exiting ****" echo "Version \`${EXT_RELEASE}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY
echo "Version ${EXT_RELEASE} already pushed, exiting" >> $GITHUB_STEP_SUMMARY
exit 0 exit 0
elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/lastBuild/api/json | jq -r '.building') == "true" ]; then elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/lastBuild/api/json | jq -r '.building') == "true" ]; then
echo "**** New version ${EXT_RELEASE} found; but there already seems to be an active build on Jenkins; exiting ****" echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY
echo "New version ${EXT_RELEASE} found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY
exit 0 exit 0
else else
echo "**** New version ${EXT_RELEASE} found; old version was ${IMAGE_VERSION}. Triggering new build ****" if [[ "${artifacts_found}" == "false" ]]; then
echo "New version ${EXT_RELEASE} found; old version was ${IMAGE_VERSION}. Triggering new build" >> $GITHUB_STEP_SUMMARY echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
response=$(curl -iX POST \ echo "> New version detected, but not all artifacts are published yet; skipping trigger" >> $GITHUB_STEP_SUMMARY
https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/buildWithParameters?PACKAGE_CHECK=false \ FAILURE_REASON="New version ${EXT_RELEASE} for qbittorrent tag libtorrentv1 is detected, however not all artifacts are uploaded to upstream release yet. Will try again later."
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903,
echo "**** Jenkins job queue url: ${response%$'\r'} ****" "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}],
echo "**** Sleeping 10 seconds until job starts ****" "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
sleep 10 else
buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY
buildurl="${buildurl%$'\r'}" echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY
echo "**** Jenkins job build url: ${buildurl} ****" if [[ "${artifacts_found}" == "true" ]]; then
echo "Jenkins job build url: ${buildurl}" >> $GITHUB_STEP_SUMMARY echo "All artifacts seem to be uploaded." >> $GITHUB_STEP_SUMMARY
echo "**** Attempting to change the Jenkins job description ****" fi
curl -iX POST \ response=$(curl -iX POST \
"${buildurl}submitDescription" \ https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/buildWithParameters?PACKAGE_CHECK=false \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|")
--data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY
--data-urlencode "Submit=Submit" echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY
echo "**** Notifying Discord ****" sleep 10
TRIGGER_REASON="A version change was detected for qbittorrent tag libtorrentv1. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url')
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, buildurl="${buildurl%$'\r'}"
"description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} 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 qbittorrent tag libtorrentv1. 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 fi

View File

@@ -9,37 +9,37 @@ jobs:
external-trigger-scheduler: external-trigger-scheduler:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3.1.0 - uses: actions/checkout@v4.1.1
with: with:
fetch-depth: '0' fetch-depth: '0'
- name: External Trigger Scheduler - name: External Trigger Scheduler
run: | run: |
echo "**** Branches found: ****" printf "# External trigger scheduler for docker-qbittorrent\n\n" >> $GITHUB_STEP_SUMMARY
git for-each-ref --format='%(refname:short)' refs/remotes printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY
for br in $(git for-each-ref --format='%(refname:short)' refs/remotes) for br in $(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes)
do do
br=$(echo "$br" | sed 's|origin/||g') if [[ "${br}" == "HEAD" ]]; then
echo "**** Evaluating branch ${br} ****" printf "\nSkipping %s.\n" ${br} >> $GITHUB_STEP_SUMMARY
continue
fi
printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY
ls_jenkins_vars=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/jenkins-vars.yml) ls_jenkins_vars=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/jenkins-vars.yml)
ls_branch=$(echo "${ls_jenkins_vars}" | yq -r '.ls_branch') ls_branch=$(echo "${ls_jenkins_vars}" | yq -r '.ls_branch')
ls_trigger=$(echo "${ls_jenkins_vars}" | yq -r '.external_type') ls_trigger=$(echo "${ls_jenkins_vars}" | yq -r '.external_type')
if [[ "${br}" == "${ls_branch}" ]] && [[ "${ls_trigger}" != "os" ]]; then if [[ "${br}" == "${ls_branch}" ]] && [[ "${ls_trigger}" != "os" ]]; then
echo "**** Branch ${br} appears to be live and trigger is not os; checking workflow. ****" echo "Branch appears to be live and trigger is not os; checking workflow." >> $GITHUB_STEP_SUMMARY
if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/.github/workflows/external_trigger.yml > /dev/null 2>&1; then if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/.github/workflows/external_trigger.yml > /dev/null 2>&1; then
echo "**** Workflow exists. Triggering external trigger workflow for branch ${br} ****." echo "Triggering external trigger workflow for branch." >> $GITHUB_STEP_SUMMARY
echo "Triggering external trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY
curl -iX POST \ curl -iX POST \
-H "Authorization: token ${{ secrets.CR_PAT }}" \ -H "Authorization: token ${{ secrets.CR_PAT }}" \
-H "Accept: application/vnd.github.v3+json" \ -H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"refs/heads/${br}\"}" \ -d "{\"ref\":\"refs/heads/${br}\"}" \
https://api.github.com/repos/linuxserver/docker-qbittorrent/actions/workflows/external_trigger.yml/dispatches https://api.github.com/repos/linuxserver/docker-qbittorrent/actions/workflows/external_trigger.yml/dispatches
else else
echo "**** Workflow doesn't exist; skipping trigger. ****" echo "Skipping branch due to no external trigger workflow present." >> $GITHUB_STEP_SUMMARY
echo "Skipping branch ${br} due to no external trigger workflow present." >> $GITHUB_STEP_SUMMARY
fi fi
else else
echo "**** ${br} is either a dev branch, or has no external version; skipping trigger. ****" echo "Skipping branch due to being detected as dev branch or having no external version." >> $GITHUB_STEP_SUMMARY
echo "Skipping branch ${br} due to being detected as dev branch or having no external version." >> $GITHUB_STEP_SUMMARY
fi fi
done done

View File

@@ -1,42 +0,0 @@
name: Package Trigger Main
on:
workflow_dispatch:
jobs:
package-trigger-libtorrentv1:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.1.0
- name: Package Trigger
if: github.ref == 'refs/heads/libtorrentv1'
run: |
if [ -n "${{ secrets.PAUSE_PACKAGE_TRIGGER_QBITTORRENT_LIBTORRENTV1 }}" ]; then
echo "**** Github secret PAUSE_PACKAGE_TRIGGER_QBITTORRENT_LIBTORRENTV1 is set; skipping trigger. ****"
echo "Github secret \`PAUSE_PACKAGE_TRIGGER_QBITTORRENT_LIBTORRENTV1\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY
exit 0
fi
if [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/lastBuild/api/json | jq -r '.building') == "true" ]; then
echo "**** There already seems to be an active build on Jenkins; skipping package trigger ****"
echo "There already seems to be an active build on Jenkins; skipping package trigger" >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "**** Package trigger running off of libtorrentv1 branch. To disable, set a Github secret named \"PAUSE_PACKAGE_TRIGGER_QBITTORRENT_LIBTORRENTV1\". ****"
echo "Package trigger running off of libtorrentv1 branch. To disable, set a Github secret named \`PAUSE_PACKAGE_TRIGGER_QBITTORRENT_LIBTORRENTV1\`" >> $GITHUB_STEP_SUMMARY
response=$(curl -iX POST \
https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/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'} ****"
echo "**** Sleeping 10 seconds until job starts ****"
sleep 10
buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url')
buildurl="${buildurl%$'\r'}"
echo "**** Jenkins job build url: ${buildurl} ****"
echo "Jenkins job build url: ${buildurl}" >> $GITHUB_STEP_SUMMARY
echo "**** Attempting to change the Jenkins job description ****"
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"

View File

@@ -9,42 +9,92 @@ jobs:
package-trigger-scheduler: package-trigger-scheduler:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3.1.0 - uses: actions/checkout@v4.1.1
with: with:
fetch-depth: '0' fetch-depth: '0'
- name: Package Trigger Scheduler - name: Package Trigger Scheduler
env:
SKIP_PACKAGE_TRIGGER: ${{ vars.SKIP_PACKAGE_TRIGGER }}
run: | run: |
echo "**** Branches found: ****" printf "# Package trigger scheduler for docker-qbittorrent\n\n" >> $GITHUB_STEP_SUMMARY
git for-each-ref --format='%(refname:short)' refs/remotes printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY
for br in $(git for-each-ref --format='%(refname:short)' refs/remotes) for br in $(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes)
do do
br=$(echo "$br" | sed 's|origin/||g') if [[ "${br}" == "HEAD" ]]; then
echo "**** Evaluating branch ${br} ****" printf "\nSkipping %s.\n" ${br} >> $GITHUB_STEP_SUMMARY
ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/jenkins-vars.yml | yq -r '.ls_branch') continue
if [ "${br}" == "${ls_branch}" ]; then fi
echo "**** Branch ${br} appears to be live; checking workflow. ****" printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY
if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/.github/workflows/package_trigger.yml > /dev/null 2>&1; then JENKINS_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/jenkins-vars.yml)
echo "**** Workflow exists. Triggering package trigger workflow for branch ${br}. ****" if ! curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/Jenkinsfile >/dev/null 2>&1; then
echo "Triggering package trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
triggered_branches="${triggered_branches}${br} " echo "> No Jenkinsfile found. Branch is either deprecated or is an early dev branch." >> $GITHUB_STEP_SUMMARY
curl -iX POST \ skipped_branches="${skipped_branches}${br} "
-H "Authorization: token ${{ secrets.CR_PAT }}" \ elif [[ "${br}" == $(yq -r '.ls_branch' <<< "${JENKINS_VARS}") ]]; then
-H "Accept: application/vnd.github.v3+json" \ echo "Branch appears to be live; checking workflow." >> $GITHUB_STEP_SUMMARY
-d "{\"ref\":\"refs/heads/${br}\"}" \ README_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-qbittorrent/${br}/readme-vars.yml)
https://api.github.com/repos/linuxserver/docker-qbittorrent/actions/workflows/package_trigger.yml/dispatches if [[ $(yq -r '.project_deprecation_status' <<< "${README_VARS}") == "true" ]]; then
sleep 30 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 "^qbittorrent_${br}" <<< "${SKIP_PACKAGE_TRIGGER}"; then
echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
echo "> Github organizational variable \`SKIP_PACKAGE_TRIGGER\` contains \`qbittorrent_${br}\`; skipping trigger." >> $GITHUB_STEP_SUMMARY
skipped_branches="${skipped_branches}${br} "
elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/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 else
echo "**** Workflow doesn't exist; skipping trigger. ****" echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY
echo "Skipping branch ${br} due to no package trigger workflow present." >> $GITHUB_STEP_SUMMARY echo "> Triggering package trigger for branch ${br}" >> $GITHUB_STEP_SUMMARY
printf "> To disable, add \`qbittorrent_%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-qbittorrent/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 fi
else else
echo "**** ${br} appears to be a dev branch; skipping trigger. ****"
echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY
fi fi
done done
echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" if [[ -n "${triggered_branches}" ]] || [[ -n "${skipped_branches}" ]]; then
echo "**** Notifying Discord ****" if [[ -n "${triggered_branches}" ]]; then
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, NOTIFY_BRANCHES="**Triggered:** ${triggered_branches} \n"
"description": "**Package Check Build(s) Triggered for qbittorrent** \n**Branch(es):** '"${triggered_branches}"' \n**Build URL:** '"https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-qbittorrent/activity/"' \n"}], NOTIFY_BUILD_URL="**Build URL:** https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-qbittorrent/activity/ \n"
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} 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 qbittorrent** \n'"${NOTIFY_BRANCHES}"''"${NOTIFY_BUILD_URL}"'"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
fi

View File

@@ -5,6 +5,8 @@ on:
- '**/run' - '**/run'
- '**/finish' - '**/finish'
- '**/check' - '**/check'
- 'root/migrations/*'
jobs: jobs:
permission_check: permission_check:
uses: linuxserver/github-workflows/.github/workflows/init-svc-executable-permissions.yml@v1 uses: linuxserver/github-workflows/.github/workflows/init-svc-executable-permissions.yml@v1

View File

@@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM ghcr.io/linuxserver/unrar:latest as unrar FROM ghcr.io/linuxserver/unrar:latest AS unrar
FROM ghcr.io/linuxserver/baseimage-alpine:3.18 FROM ghcr.io/linuxserver/baseimage-alpine:3.21
# set version label # set version label
ARG BUILD_DATE ARG BUILD_DATE
@@ -19,17 +19,14 @@ XDG_DATA_HOME="/config"
# install runtime packages and qbitorrent-cli # install runtime packages and qbitorrent-cli
RUN \ RUN \
echo "**** install build packages ****" && \
apk add --no-cache --upgrade --virtual=build-dependencies \
build-base && \
echo "**** install packages ****" && \ echo "**** install packages ****" && \
apk add -U --update --no-cache \ apk add -U --update --no-cache \
grep \
icu-libs \ icu-libs \
openssl1.1-compat \
p7zip \ p7zip \
python3 \ python3 \
qt6-qtbase-sqlite && \ qt6-qtbase-sqlite && \
echo "**** install qbittorrent ****" && \ echo "**** install qbittorrent ****" && \
if [ -z ${QBITTORRENT_VERSION+x} ]; then \ if [ -z ${QBITTORRENT_VERSION+x} ]; then \
QBITTORRENT_VERSION=$(curl -sL "https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases" | \ QBITTORRENT_VERSION=$(curl -sL "https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases" | \
jq -r 'first(.[] | select(.prerelease == true) | .tag_name)'); \ jq -r 'first(.[] | select(.prerelease == true) | .tag_name)'); \
@@ -42,17 +39,16 @@ RUN \
mkdir /qbt && \ mkdir /qbt && \
if [ -z ${QBT_CLI_VERSION+x} ]; then \ if [ -z ${QBT_CLI_VERSION+x} ]; then \
QBT_CLI_VERSION=$(curl -sL "https://api.github.com/repos/fedarovich/qbittorrent-cli/releases/latest" \ QBT_CLI_VERSION=$(curl -sL "https://api.github.com/repos/fedarovich/qbittorrent-cli/releases/latest" \
| jq -r '. | .tag_name'); \ | jq -r '. | .tag_name'); \
fi && \ fi && \
curl -o \ curl -o \
/tmp/qbt.tar.gz -L \ /tmp/qbt.tar.gz -L \
"https://github.com/fedarovich/qbittorrent-cli/releases/download/${QBT_CLI_VERSION}/qbt-linux-alpine-x64-${QBT_CLI_VERSION#v}.tar.gz" && \ "https://github.com/fedarovich/qbittorrent-cli/releases/download/${QBT_CLI_VERSION}/qbt-linux-alpine-x64-net6-${QBT_CLI_VERSION#v}.tar.gz" && \
tar xf \ tar xf \
/tmp/qbt.tar.gz -C \ /tmp/qbt.tar.gz -C \
/qbt && \ /qbt && \
printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \
echo "**** cleanup ****" && \ echo "**** cleanup ****" && \
apk del --purge \
build-dependencies && \
rm -rf \ rm -rf \
/root/.cache \ /root/.cache \
/tmp/* /tmp/*

View File

@@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM ghcr.io/linuxserver/unrar:arm64v8-latest as unrar FROM ghcr.io/linuxserver/unrar:arm64v8-latest AS unrar
FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.18 FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.21
# set version label # set version label
ARG BUILD_DATE ARG BUILD_DATE
@@ -19,17 +19,14 @@ XDG_DATA_HOME="/config"
# install runtime packages and qbitorrent-cli # install runtime packages and qbitorrent-cli
RUN \ RUN \
echo "**** install build packages ****" && \
apk add --no-cache --upgrade --virtual=build-dependencies \
build-base && \
echo "**** install packages ****" && \ echo "**** install packages ****" && \
apk add -U --update --no-cache \ apk add -U --update --no-cache \
grep \
icu-libs \ icu-libs \
openssl1.1-compat \
p7zip \ p7zip \
python3 \ python3 \
qt6-qtbase-sqlite && \ qt6-qtbase-sqlite && \
echo "**** install qbittorrent ****" && \ echo "**** install qbittorrent ****" && \
if [ -z ${QBITTORRENT_VERSION+x} ]; then \ if [ -z ${QBITTORRENT_VERSION+x} ]; then \
QBITTORRENT_VERSION=$(curl -sL "https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases" | \ QBITTORRENT_VERSION=$(curl -sL "https://api.github.com/repos/userdocs/qbittorrent-nox-static/releases" | \
jq -r 'first(.[] | select(.prerelease == true) | .tag_name)'); \ jq -r 'first(.[] | select(.prerelease == true) | .tag_name)'); \
@@ -42,17 +39,16 @@ RUN \
mkdir /qbt && \ mkdir /qbt && \
if [ -z ${QBT_CLI_VERSION+x} ]; then \ if [ -z ${QBT_CLI_VERSION+x} ]; then \
QBT_CLI_VERSION=$(curl -sL "https://api.github.com/repos/fedarovich/qbittorrent-cli/releases/latest" \ QBT_CLI_VERSION=$(curl -sL "https://api.github.com/repos/fedarovich/qbittorrent-cli/releases/latest" \
| jq -r '. | .tag_name'); \ | jq -r '. | .tag_name'); \
fi && \ fi && \
curl -o \ curl -o \
/tmp/qbt.tar.gz -L \ /tmp/qbt.tar.gz -L \
"https://github.com/fedarovich/qbittorrent-cli/releases/download/${QBT_CLI_VERSION}/qbt-linux-alpine-arm64-${QBT_CLI_VERSION#v}.tar.gz" && \ "https://github.com/fedarovich/qbittorrent-cli/releases/download/${QBT_CLI_VERSION}/qbt-linux-alpine-arm64-net6-${QBT_CLI_VERSION#v}.tar.gz" && \
tar xf \ tar xf \
/tmp/qbt.tar.gz -C \ /tmp/qbt.tar.gz -C \
/qbt && \ /qbt && \
printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \
echo "**** cleanup ****" && \ echo "**** cleanup ****" && \
apk del --purge \
build-dependencies && \
rm -rf \ rm -rf \
/root/.cache \ /root/.cache \
/tmp/* /tmp/*

783
Jenkinsfile vendored
View File

@@ -8,7 +8,7 @@ pipeline {
} }
// Input to determine if this is a package check // Input to determine if this is a package check
parameters { 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 // Configuration for the variables used for this specific repo
environment { environment {
@@ -17,6 +17,8 @@ pipeline {
GITLAB_TOKEN=credentials('b6f0f1dd-6952-4cf6-95d1-9c06380283f0') GITLAB_TOKEN=credentials('b6f0f1dd-6952-4cf6-95d1-9c06380283f0')
GITLAB_NAMESPACE=credentials('gitlab-namespace-id') GITLAB_NAMESPACE=credentials('gitlab-namespace-id')
DOCKERHUB_TOKEN=credentials('docker-hub-ci-pat') DOCKERHUB_TOKEN=credentials('docker-hub-ci-pat')
QUAYIO_API_TOKEN=credentials('quayio-repo-api-token')
GIT_SIGNING_KEY=credentials('484fbca6-9a4f-455e-b9e3-97ac98785f5f')
CONTAINER_NAME = 'qbittorrent' CONTAINER_NAME = 'qbittorrent'
BUILD_VERSION_ARG = 'QBITTORRENT_VERSION' BUILD_VERSION_ARG = 'QBITTORRENT_VERSION'
LS_USER = 'linuxserver' LS_USER = 'linuxserver'
@@ -25,27 +27,50 @@ pipeline {
DEV_DOCKERHUB_IMAGE = 'lsiodev/qbittorrent' DEV_DOCKERHUB_IMAGE = 'lsiodev/qbittorrent'
PR_DOCKERHUB_IMAGE = 'lspipepr/qbittorrent' PR_DOCKERHUB_IMAGE = 'lspipepr/qbittorrent'
DIST_IMAGE = 'alpine' DIST_IMAGE = 'alpine'
DIST_TAG = '3.18'
MULTIARCH='true' MULTIARCH='true'
CI='true' CI='true'
CI_WEB='true' CI_WEB='true'
CI_PORT='8080' CI_PORT='8080'
CI_SSL='false' CI_SSL='false'
CI_DELAY='120' CI_DELAY='60'
CI_DOCKERENV='TZ=US/Pacific' CI_DOCKERENV=''
CI_AUTH='user:password' CI_AUTH=''
CI_WEBPATH='' CI_WEBPATH=''
} }
stages { stages {
stage("Set git config"){
steps{
sh '''#!/bin/bash
cat ${GIT_SIGNING_KEY} > /config/.ssh/id_sign
chmod 600 /config/.ssh/id_sign
ssh-keygen -y -f /config/.ssh/id_sign > /config/.ssh/id_sign.pub
echo "Using $(ssh-keygen -lf /config/.ssh/id_sign) to sign commits"
git config --global gpg.format ssh
git config --global user.signingkey /config/.ssh/id_sign
git config --global commit.gpgsign true
'''
}
}
// 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{
echo "Running on node: ${NODE_NAME}"
sh '''#! /bin/bash sh '''#! /bin/bash
containers=$(docker ps -aq) echo "Pruning builder"
docker builder prune -f --builder container || :
containers=$(docker ps -q)
if [[ -n "${containers}" ]]; then 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 fi
docker system prune -af --volumes || : ''' docker system prune -f --volumes || : '''
script{ script{
env.EXIT_STATUS = '' env.EXIT_STATUS = ''
env.LS_RELEASE = sh( env.LS_RELEASE = sh(
@@ -66,7 +91,7 @@ pipeline {
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT 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.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/'
env.PULL_REQUEST = env.CHANGE_ID 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' 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'
} }
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}" '''
@@ -176,6 +201,7 @@ pipeline {
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.META_TAG = 'libtorrentv1-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER env.META_TAG = 'libtorrentv1-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.EXT_RELEASE_TAG = 'libtorrentv1-version-' + env.EXT_RELEASE_CLEAN env.EXT_RELEASE_TAG = 'libtorrentv1-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'
} }
} }
} }
@@ -200,6 +226,7 @@ pipeline {
env.META_TAG = 'libtorrentv1-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA env.META_TAG = 'libtorrentv1-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
env.EXT_RELEASE_TAG = 'libtorrentv1-version-' + env.EXT_RELEASE_CLEAN env.EXT_RELEASE_TAG = 'libtorrentv1-version-' + env.EXT_RELEASE_CLEAN
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/' 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'
} }
} }
} }
@@ -224,6 +251,7 @@ pipeline {
env.EXT_RELEASE_TAG = 'libtorrentv1-version-' + env.EXT_RELEASE_CLEAN env.EXT_RELEASE_TAG = 'libtorrentv1-version-' + env.EXT_RELEASE_CLEAN
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST 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.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'
} }
} }
} }
@@ -246,9 +274,11 @@ pipeline {
-v ${WORKSPACE}:/mnt \ -v ${WORKSPACE}:/mnt \
-e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \ -e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \
-e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \ -e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \
ghcr.io/linuxserver/baseimage-alpine:3.17 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\ ghcr.io/linuxserver/baseimage-alpine:3.20 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\
apk add --no-cache py3-pip && \ apk add --no-cache python3 && \
pip install s3cmd && \ python3 -m venv /lsiopy && \
pip install --no-cache-dir -U pip && \
pip install --no-cache-dir s3cmd && \
s3cmd put --no-preserve --acl-public -m text/xml /mnt/shellcheck-result.xml s3://ci-tests.linuxserver.io/${IMAGE}/${META_TAG}/shellcheck-result.xml" || :''' s3cmd put --no-preserve --acl-public -m text/xml /mnt/shellcheck-result.xml s3://ci-tests.linuxserver.io/${IMAGE}/${META_TAG}/shellcheck-result.xml" || :'''
} }
} }
@@ -263,150 +293,207 @@ pipeline {
} }
} }
steps { steps {
withCredentials([ sh '''#! /bin/bash
[ set -e
$class: 'UsernamePasswordMultiBinding', TEMPDIR=$(mktemp -d)
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', docker pull ghcr.io/linuxserver/jenkins-builder:latest
usernameVariable: 'DOCKERUSER', # Cloned repo paths for templating:
passwordVariable: 'DOCKERPASS' # ${TEMPDIR}/docker-${CONTAINER_NAME}: Cloned branch libtorrentv1 of ${LS_USER}/${LS_REPO} for running the jenkins builder on
] # ${TEMPDIR}/repo/${LS_REPO}: Cloned branch libtorrentv1 of ${LS_USER}/${LS_REPO} for commiting various templated file changes and pushing back to Github
]) { # ${TEMPDIR}/docs/docker-documentation: Cloned docs repo for pushing docs updates to Github
sh '''#! /bin/bash # ${TEMPDIR}/unraid/docker-templates: Cloned docker-templates repo to check for logos
set -e # ${TEMPDIR}/unraid/templates: Cloned templates repo for commiting unraid template changes and pushing back to Github
TEMPDIR=$(mktemp -d) git clone --branch libtorrentv1 --depth 1 https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/docker-${CONTAINER_NAME}
docker pull ghcr.io/linuxserver/jenkins-builder:latest docker run --rm -v ${TEMPDIR}/docker-${CONTAINER_NAME}:/tmp -e LOCAL=true -e PUID=$(id -u) -e PGID=$(id -g) ghcr.io/linuxserver/jenkins-builder:latest
docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH=libtorrentv1 -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest echo "Starting Stage 1 - Jenkinsfile update"
# Stage 1 - Jenkinsfile update if [[ "$(md5sum Jenkinsfile | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile | awk '{ print $1 }')" ]]; then
if [[ "$(md5sum Jenkinsfile | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile | awk '{ print $1 }')" ]]; then mkdir -p ${TEMPDIR}/repo
mkdir -p ${TEMPDIR}/repo git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} cd ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO} git checkout -f libtorrentv1
git checkout -f libtorrentv1 cp ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile ${TEMPDIR}/repo/${LS_REPO}/
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile ${TEMPDIR}/repo/${LS_REPO}/ git add Jenkinsfile
git add Jenkinsfile git commit -m 'Bot Updating Templated Files'
git commit -m 'Bot Updating Templated Files' git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} echo "Updating Jenkinsfile and exiting build, new one will trigger based on commit"
echo "Updating Jenkinsfile" rm -Rf ${TEMPDIR}
rm -Rf ${TEMPDIR} exit 0
exit 0 else
else echo "Jenkinsfile is up to date."
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 .github/workflows/package_trigger.yml"
for i in ${OLD_TEMPLATES}; do
if [[ -f "${i}" ]]; then
TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}"
fi fi
# Stage 2 - Delete old templates done
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 Dockerfile.armhf" if [[ -n "${TEMPLATES_TO_DELETE}" ]]; then
for i in ${OLD_TEMPLATES}; do mkdir -p ${TEMPDIR}/repo
if [[ -f "${i}" ]]; then git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}" cd ${TEMPDIR}/repo/${LS_REPO}
fi git checkout -f libtorrentv1
for i in ${TEMPLATES_TO_DELETE}; do
git rm "${i}"
done done
if [[ -n "${TEMPLATES_TO_DELETE}" ]]; then git commit -m 'Bot Updating Templated Files'
mkdir -p ${TEMPDIR}/repo git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
cd ${TEMPDIR}/repo/${LS_REPO} echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
git checkout -f libtorrentv1 echo "Deleting old/deprecated templates and exiting build, new one will trigger based on commit"
for i in ${TEMPLATES_TO_DELETE}; do rm -Rf ${TEMPDIR}
git rm "${i}" exit 0
done else
git commit -m 'Bot Updating Templated Files' echo "No templates to delete"
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 fi
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 echo "Starting Stage 2.5 - Update init diagram"
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} if ! grep -q 'init_diagram:' readme-vars.yml; then
echo "Deleting old and deprecated templates" echo "Adding the key 'init_diagram' to readme-vars.yml"
rm -Rf ${TEMPDIR} sed -i '\\|^#.*changelog.*$|d' readme-vars.yml
exit 0 sed -i 's|^changelogs:|# init diagram\\ninit_diagram:\\n\\n# changelog\\nchangelogs:|' readme-vars.yml
else fi
echo "No templates to delete" mkdir -p ${TEMPDIR}/d2
fi 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}:libtorrentv1
# Stage 3 - Update templates ls -al ${TEMPDIR}/d2
CURRENTHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8) yq -ei ".init_diagram |= load_str(\\"${TEMPDIR}/d2/${CONTAINER_NAME}-libtorrentv1.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 libtorrentv1
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 libtorrentv1
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
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}
NEWHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8)
if [[ "${CURRENTHASH}" != "${NEWHASH}" ]] || ! grep -q '.jenkins-external' "${WORKSPACE}/.gitignore" 2>/dev/null; then
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 libtorrentv1
cd ${TEMPDIR}/docker-${CONTAINER_NAME} cd ${TEMPDIR}/docker-${CONTAINER_NAME}
NEWHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8) mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/workflows
if [[ "${CURRENTHASH}" != "${NEWHASH}" ]] || ! grep -q '.jenkins-external' "${WORKSPACE}/.gitignore" 2>/dev/null; then mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/ISSUE_TEMPLATE
mkdir -p ${TEMPDIR}/repo cp --parents ${TEMPLATED_FILES} ${TEMPDIR}/repo/${LS_REPO}/ || :
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} cp --parents readme-vars.yml ${TEMPDIR}/repo/${LS_REPO}/ || :
cd ${TEMPDIR}/repo/${LS_REPO} cd ${TEMPDIR}/repo/${LS_REPO}/
git checkout -f libtorrentv1 if ! grep -q '.jenkins-external' .gitignore 2>/dev/null; then
cd ${TEMPDIR}/docker-${CONTAINER_NAME} echo ".jenkins-external" >> .gitignore
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/workflows git add .gitignore
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/ISSUE_TEMPLATE fi
cp --parents ${TEMPLATED_FILES} ${TEMPDIR}/repo/${LS_REPO}/ || : git add readme-vars.yml ${TEMPLATED_FILES}
cp --parents readme-vars.yml ${TEMPDIR}/repo/${LS_REPO}/ || : git commit -m 'Bot Updating Templated Files'
cd ${TEMPDIR}/repo/${LS_REPO}/ git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
if ! grep -q '.jenkins-external' .gitignore 2>/dev/null; then git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1
echo ".jenkins-external" >> .gitignore echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
git add .gitignore echo "Updating templates and exiting build, new one will trigger based on commit"
fi rm -Rf ${TEMPDIR}
git add readme-vars.yml ${TEMPLATED_FILES} exit 0
git commit -m 'Bot Updating Templated Files' else
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git libtorrentv1 echo "No templates to update"
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} fi
echo "Starting Stage 4 - External repo updates: Docs, Unraid Template and Readme Sync to Docker Hub"
mkdir -p ${TEMPDIR}/docs
git clone --depth=1 https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/docs/docker-documentation
if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]] && [[ (! -f ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/docs/docker-documentation/docs/images/
cd ${TEMPDIR}/docs/docker-documentation
GH_DOCS_DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||')
git add docs/images/docker-${CONTAINER_NAME}.md
echo "Updating docs repo"
git commit -m 'Bot Updating Documentation'
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} --rebase
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} || \
(MAXWAIT="10" && echo "Push to docs failed, trying again in ${MAXWAIT} seconds" && \
sleep $((RANDOM % MAXWAIT)) && \
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} --rebase && \
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH})
else
echo "Docs update not needed, skipping"
fi
mkdir -p ${TEMPDIR}/unraid
git clone --depth=1 https://github.com/linuxserver/docker-templates.git ${TEMPDIR}/unraid/docker-templates
git clone --depth=1 https://github.com/linuxserver/templates.git ${TEMPDIR}/unraid/templates
if [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-logo.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-logo.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
elif [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-icon.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-icon.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
fi
if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]] && [[ (! -f ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml) || ("$(md5sum ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml | awk '{ print $1 }')") ]]; then
echo "Updating Unraid template"
cd ${TEMPDIR}/unraid/templates/
GH_TEMPLATES_DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||')
if grep -wq "^${CONTAINER_NAME}$" ${TEMPDIR}/unraid/templates/unraid/ignore.list && [[ -f ${TEMPDIR}/unraid/templates/unraid/deprecated/${CONTAINER_NAME}.xml ]]; then
echo "Image is on the ignore list, and already in the deprecation folder."
elif grep -wq "^${CONTAINER_NAME}$" ${TEMPDIR}/unraid/templates/unraid/ignore.list; then
echo "Image is on the ignore list, marking Unraid template as deprecated"
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add -u unraid/${CONTAINER_NAME}.xml
git mv unraid/${CONTAINER_NAME}.xml unraid/deprecated/${CONTAINER_NAME}.xml || :
git commit -m 'Bot Moving Deprecated Unraid Template' || :
else else
echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add unraid/${CONTAINER_NAME}.xml
git commit -m 'Bot Updating Unraid Template'
fi fi
mkdir -p ${TEMPDIR}/docs git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH} --rebase
git clone https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/docs/docker-documentation git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH} || \
if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]] && [[ (! -f ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then (MAXWAIT="10" && echo "Push to unraid templates failed, trying again in ${MAXWAIT} seconds" && \
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/docs/docker-documentation/docs/images/ sleep $((RANDOM % MAXWAIT)) && \
cd ${TEMPDIR}/docs/docker-documentation git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH} --rebase && \
GH_DOCS_DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||') git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH})
git add docs/images/docker-${CONTAINER_NAME}.md else
git commit -m 'Bot Updating Documentation' echo "No updates to Unraid template needed, skipping"
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} fi
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]]; then
if [[ $(cat ${TEMPDIR}/docker-${CONTAINER_NAME}/README.md | wc -m) -gt 25000 ]]; then
echo "Readme is longer than 25,000 characters. Syncing the lite version to Docker Hub"
DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/README.lite"
else
echo "Syncing readme to Docker Hub"
DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/README.md"
fi fi
mkdir -p ${TEMPDIR}/unraid if curl -s https://hub.docker.com/v2/namespaces/${DOCKERHUB_IMAGE%%/*}/repositories/${DOCKERHUB_IMAGE##*/}/tags | jq -r '.message' | grep -q 404; then
git clone https://github.com/linuxserver/docker-templates.git ${TEMPDIR}/unraid/docker-templates echo "Docker Hub endpoint doesn't exist. Creating endpoint first."
git clone https://github.com/linuxserver/templates.git ${TEMPDIR}/unraid/templates DH_TOKEN=$(curl -d '{"username":"linuxserverci", "password":"'${DOCKERHUB_TOKEN}'"}' -H "Content-Type: application/json" -X POST https://hub.docker.com/v2/users/login | jq -r '.token')
if [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-logo.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-logo.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
elif [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-icon.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-icon.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
fi
if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]] && [[ (! -f ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml) || ("$(md5sum ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml | awk '{ print $1 }')") ]]; then
cd ${TEMPDIR}/unraid/templates/
GH_TEMPLATES_DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||')
if grep -wq "${CONTAINER_NAME}" ${TEMPDIR}/unraid/templates/unraid/ignore.list; then
echo "Image is on the ignore list, marking Unraid template as deprecated"
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add -u unraid/${CONTAINER_NAME}.xml
git mv unraid/${CONTAINER_NAME}.xml unraid/deprecated/${CONTAINER_NAME}.xml || :
git commit -m 'Bot Moving Deprecated Unraid Template' || :
else
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add unraid/${CONTAINER_NAME}.xml
git commit -m 'Bot Updating Unraid Template'
fi
git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH}
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git ${GH_TEMPLATES_DEFAULT_BRANCH}
fi
# Stage 4 - Sync Readme to Docker Hub
if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]]; then
if [[ $(cat ${TEMPDIR}/docker-${CONTAINER_NAME}/README.md | wc -m) > 25000 ]]; then
echo "Readme is longer than 25,000 characters. Syncing the lite version to Docker Hub"
DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/README.lite"
else
echo "Syncing readme to Docker Hub"
DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/README.md"
fi
DH_TOKEN=$(curl -d '{"username":"'${DOCKERUSER}'", "password":"'${DOCKERHUB_TOKEN}'"}' -H "Content-Type: application/json" -X POST https://hub.docker.com/v2/users/login | jq -r '.token')
curl -s \ curl -s \
-H "Authorization: JWT ${DH_TOKEN}" \ -H "Authorization: JWT ${DH_TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-X PATCH \ -X POST \
-d "{\\"full_description\\":$(jq -Rsa . ${DH_README_SYNC_PATH})}" \ -d '{"name":"'${DOCKERHUB_IMAGE##*/}'", "namespace":"'${DOCKERHUB_IMAGE%%/*}'"}' \
https://hub.docker.com/v2/repositories/${DOCKERHUB_IMAGE} || : https://hub.docker.com/v2/repositories/ || :
else
echo "Not the default Github branch. Skipping readme sync to Docker Hub."
fi fi
rm -Rf ${TEMPDIR}''' DH_TOKEN=$(curl -d '{"username":"linuxserverci", "password":"'${DOCKERHUB_TOKEN}'"}' -H "Content-Type: application/json" -X POST https://hub.docker.com/v2/users/login | jq -r '.token')
script{ curl -s \
env.FILES_UPDATED = sh( -H "Authorization: JWT ${DH_TOKEN}" \
script: '''cat /tmp/${COMMIT_SHA}-${BUILD_NUMBER}''', -H "Content-Type: application/json" \
returnStdout: true).trim() -X PATCH \
} -d "{\\"full_description\\":$(jq -Rsa . ${DH_README_SYNC_PATH})}" \
https://hub.docker.com/v2/repositories/${DOCKERHUB_IMAGE} || :
else
echo "Not the default Github branch. Skipping readme sync to Docker Hub."
fi
rm -Rf ${TEMPDIR}'''
script{
env.FILES_UPDATED = sh(
script: '''cat /tmp/${COMMIT_SHA}-${BUILD_NUMBER}''',
returnStdout: true).trim()
} }
} }
} }
@@ -447,23 +534,27 @@ pipeline {
} }
} }
/* ####################### /* #######################
GitLab Mirroring GitLab Mirroring and Quay.io Repo Visibility
####################### */ ####################### */
// Ping into Gitlab to mirror this repo and have a registry endpoint // Ping into Gitlab to mirror this repo and have a registry endpoint & mark this repo on Quay.io as public
stage("GitLab Mirror"){ stage("GitLab Mirror and Quay.io Visibility"){
when { when {
environment name: 'EXIT_STATUS', value: '' environment name: 'EXIT_STATUS', value: ''
} }
steps{ steps{
sh '''curl -H "Content-Type: application/json" -H "Private-Token: ${GITLAB_TOKEN}" -X POST https://gitlab.com/api/v4/projects \ sh '''curl -H "Content-Type: application/json" -H "Private-Token: ${GITLAB_TOKEN}" -X POST https://gitlab.com/api/v4/projects \
-d '{"namespace_id":'${GITLAB_NAMESPACE}',\ -d '{"namespace_id":'${GITLAB_NAMESPACE}',\
"name":"'${LS_REPO}'", "name":"'${LS_REPO}'",
"mirror":true,\ "mirror":true,\
"import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\ "import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\
"issues_access_level":"disabled",\ "issues_access_level":"disabled",\
"merge_requests_access_level":"disabled",\ "merge_requests_access_level":"disabled",\
"repository_access_level":"enabled",\ "repository_access_level":"enabled",\
"visibility":"public"}' ''' "visibility":"public"}' '''
sh '''curl -H "Private-Token: ${GITLAB_TOKEN}" -X PUT "https://gitlab.com/api/v4/projects/Linuxserver.io%2F${LS_REPO}" \
-d "mirror=true&import_url=https://github.com/linuxserver/${LS_REPO}.git" '''
sh '''curl -H "Content-Type: application/json" -H "Authorization: Bearer ${QUAYIO_API_TOKEN}" -X POST "https://quay.io/api/v1/repository${QUAYIMAGE/quay.io/}/changevisibility" \
-d '{"visibility":"public"}' ||: '''
} }
} }
/* ############### /* ###############
@@ -494,7 +585,42 @@ pipeline {
--label \"org.opencontainers.image.title=Qbittorrent\" \ --label \"org.opencontainers.image.title=Qbittorrent\" \
--label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \ --label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \
--no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \ --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} ." --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 // Build MultiArch Docker containers for push to LS Repo
@@ -525,7 +651,42 @@ pipeline {
--label \"org.opencontainers.image.title=Qbittorrent\" \ --label \"org.opencontainers.image.title=Qbittorrent\" \
--label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \ --label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \
--no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \ --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} ." --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') { stage('Build ARM64') {
@@ -534,10 +695,6 @@ pipeline {
} }
steps { steps {
echo "Running on node: ${NODE_NAME}" 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 "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64"
sh "docker buildx build \ sh "docker buildx build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
@@ -553,17 +710,49 @@ pipeline {
--label \"org.opencontainers.image.title=Qbittorrent\" \ --label \"org.opencontainers.image.title=Qbittorrent\" \
--label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \ --label \"org.opencontainers.image.description=The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.\" \
--no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \ --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} ." --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}" sh '''#! /bin/bash
retry(5) { set -e
sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}" 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 sh '''#! /bin/bash
containers=$(docker ps -aq) containers=$(docker ps -aq)
if [[ -n "${containers}" ]]; then if [[ -n "${containers}" ]]; then
docker stop ${containers} docker stop ${containers}
fi fi
docker system prune -af --volumes || : ''' docker system prune -af --volumes || :
'''
} }
} }
} }
@@ -579,7 +768,7 @@ pipeline {
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
TEMPDIR=$(mktemp -d) TEMPDIR=$(mktemp -d)
if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" != "true" ]; then
LOCAL_CONTAINER=${IMAGE}:amd64-${META_TAG} LOCAL_CONTAINER=${IMAGE}:amd64-${META_TAG}
else else
LOCAL_CONTAINER=${IMAGE}:${META_TAG} LOCAL_CONTAINER=${IMAGE}:${META_TAG}
@@ -667,18 +856,27 @@ pipeline {
} }
sh '''#! /bin/bash sh '''#! /bin/bash
set -e 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 docker pull ghcr.io/linuxserver/ci:latest
if [ "${MULTIARCH}" == "true" ]; then if [ "${MULTIARCH}" == "true" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} 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 \
--shm-size=1gb \ --shm-size=1gb \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
-e IMAGE=\"${IMAGE}\" \ -e IMAGE=\"${IMAGE}\" \
-e DELAY_START=\"${CI_DELAY}\" \ -e DOCKER_LOGS_TIMEOUT=\"${CI_DELAY}\" \
-e TAGS=\"${CI_TAGS}\" \ -e TAGS=\"${CI_TAGS}\" \
-e META_TAG=\"${META_TAG}\" \ -e META_TAG=\"${META_TAG}\" \
-e RELEASE_TAG=\"libtorrentv1\" \
-e PORT=\"${CI_PORT}\" \ -e PORT=\"${CI_PORT}\" \
-e SSL=\"${CI_SSL}\" \ -e SSL=\"${CI_SSL}\" \
-e BASE=\"${DIST_IMAGE}\" \ -e BASE=\"${DIST_IMAGE}\" \
@@ -688,6 +886,7 @@ pipeline {
-e WEB_SCREENSHOT=\"${CI_WEB}\" \ -e WEB_SCREENSHOT=\"${CI_WEB}\" \
-e WEB_AUTH=\"${CI_AUTH}\" \ -e WEB_AUTH=\"${CI_AUTH}\" \
-e WEB_PATH=\"${CI_WEBPATH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \
-e NODE_NAME=\"${NODE_NAME}\" \
-t ghcr.io/linuxserver/ci:latest \ -t ghcr.io/linuxserver/ci:latest \
python3 test_build.py''' python3 test_build.py'''
} }
@@ -703,43 +902,23 @@ pipeline {
environment name: 'EXIT_STATUS', value: '' environment name: 'EXIT_STATUS', value: ''
} }
steps { steps {
withCredentials([ retry_backoff(5,5) {
[ sh '''#! /bin/bash
$class: 'UsernamePasswordMultiBinding', set -e
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', for PUSHIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
usernameVariable: 'DOCKERUSER', [[ ${PUSHIMAGE%%/*} =~ \\. ]] && PUSHIMAGEPLUS="${PUSHIMAGE}" || PUSHIMAGEPLUS="docker.io/${PUSHIMAGE}"
passwordVariable: 'DOCKERPASS' IFS=',' read -ra CACHE <<< "$BUILDCACHE"
], for i in "${CACHE[@]}"; do
[ if [[ "${PUSHIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then
$class: 'UsernamePasswordMultiBinding', CACHEIMAGE=${i}
credentialsId: 'Quay.io-Robot', fi
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --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}:libtorrentv1
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${SEMVER}
fi
docker push ${PUSHIMAGE}:libtorrentv1
docker push ${PUSHIMAGE}:${META_TAG}
docker push ${PUSHIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker push ${PUSHIMAGE}:${SEMVER}
fi
done done
''' docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:libtorrentv1 -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
'''
} }
} }
} }
@@ -750,85 +929,34 @@ pipeline {
environment name: 'EXIT_STATUS', value: '' environment name: 'EXIT_STATUS', value: ''
} }
steps { steps {
withCredentials([ retry_backoff(5,5) {
[ sh '''#! /bin/bash
$class: 'UsernamePasswordMultiBinding', set -e
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
usernameVariable: 'DOCKERUSER', [[ ${MANIFESTIMAGE%%/*} =~ \\. ]] && MANIFESTIMAGEPLUS="${MANIFESTIMAGE}" || MANIFESTIMAGEPLUS="docker.io/${MANIFESTIMAGE}"
passwordVariable: 'DOCKERPASS' IFS=',' read -ra CACHE <<< "$BUILDCACHE"
], for i in "${CACHE[@]}"; do
[ if [[ "${MANIFESTIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then
$class: 'UsernamePasswordMultiBinding', CACHEIMAGE=${i}
credentialsId: 'Quay.io-Robot', fi
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --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}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
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-libtorrentv1
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-libtorrentv1
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-libtorrentv1
docker push ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker push ${MANIFESTIMAGE}:arm64v8-libtorrentv1
docker push ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker push ${MANIFESTIMAGE}:amd64-${SEMVER}
docker push ${MANIFESTIMAGE}:arm64v8-${SEMVER}
fi
docker manifest push --purge ${MANIFESTIMAGE}:libtorrentv1 || :
docker manifest create ${MANIFESTIMAGE}:libtorrentv1 ${MANIFESTIMAGE}:amd64-libtorrentv1 ${MANIFESTIMAGE}:arm64v8-libtorrentv1
docker manifest annotate ${MANIFESTIMAGE}:libtorrentv1 ${MANIFESTIMAGE}:arm64v8-libtorrentv1 --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} --os linux --arch arm64 --variant v8
if [ -n "${SEMVER}" ]; then
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER} || :
docker manifest create ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER}
docker manifest annotate ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} --os linux --arch arm64 --variant v8
fi
token=$(curl -sX GET "https://ghcr.io/token?scope=repository%3Alinuxserver%2F${CONTAINER_NAME}%3Apull" | jq -r '.token')
digest=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/linuxserver/${CONTAINER_NAME}/manifests/arm32v7-libtorrentv1")
if [[ $(echo "$digest" | jq -r '.layers') != "null" ]]; then
docker manifest push --purge ${MANIFESTIMAGE}:arm32v7-libtorrentv1 || :
docker manifest create ${MANIFESTIMAGE}:arm32v7-libtorrentv1 ${MANIFESTIMAGE}:amd64-libtorrentv1
docker manifest push --purge ${MANIFESTIMAGE}:arm32v7-libtorrentv1
fi
docker manifest push --purge ${MANIFESTIMAGE}:libtorrentv1
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG}
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER}
fi
done done
''' docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-libtorrentv1 -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-libtorrentv1 -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
done
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
docker buildx imagetools create -t ${MANIFESTIMAGE}:libtorrentv1 ${MANIFESTIMAGE}:amd64-libtorrentv1 ${MANIFESTIMAGE}:arm64v8-libtorrentv1
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
'''
} }
} }
} }
@@ -849,14 +977,14 @@ pipeline {
"object": "'${COMMIT_SHA}'",\ "object": "'${COMMIT_SHA}'",\
"message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to libtorrentv1",\ "message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to libtorrentv1",\
"type": "commit",\ "type": "commit",\
"tagger": {"name": "LinuxServer Jenkins","email": "jenkins@linuxserver.io","date": "'${GITHUB_DATE}'"}}' ''' "tagger": {"name": "LinuxServer-CI","email": "ci@linuxserver.io","date": "'${GITHUB_DATE}'"}}' '''
echo "Pushing New release for Tag" echo "Pushing New release for Tag"
sh '''#! /bin/bash sh '''#! /bin/bash
echo "Updating to ${EXT_RELEASE_CLEAN}" > releasebody.json echo "Updating to ${EXT_RELEASE_CLEAN}" > releasebody.json
echo '{"tag_name":"'${META_TAG}'",\ echo '{"tag_name":"'${META_TAG}'",\
"target_commitish": "libtorrentv1",\ "target_commitish": "libtorrentv1",\
"name": "'${META_TAG}'",\ "name": "'${META_TAG}'",\
"body": "**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**Remote 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": true}' >> releasebody.json printf '","draft": false,"prerelease": true}' >> releasebody.json
paste -d'\\0' start releasebody.json > releasebody.json.done 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''' curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done'''
@@ -981,32 +1109,93 @@ EOF
###################### */ ###################### */
post { post {
always { always {
sh '''#!/bin/bash
rm -rf /config/.ssh/id_sign
rm -rf /config/.ssh/id_sign.pub
git config --global --unset gpg.format
git config --global --unset user.signingkey
git config --global --unset commit.gpgsign
'''
script{ script{
env.JOB_DATE = sh(
script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''',
returnStdout: true).trim()
if (env.EXIT_STATUS == "ABORTED"){ if (env.EXIT_STATUS == "ABORTED"){
sh 'echo "build aborted"' sh 'echo "build aborted"'
} }else{
else if (currentBuild.currentResult == "SUCCESS"){ 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,\ if (env.GITHUBIMAGE =~ /lspipepr/){
"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"}],\ env.JOB_WEBHOOK_STATUS='Success'
"username": "Jenkins"}' ${BUILDS_DISCORD} ''' env.JOB_WEBHOOK_COLOUR=3957028
} env.JOB_WEBHOOK_FOOTER='PR Build'
else { }else if (env.GITHUBIMAGE =~ /lsiodev/){
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,\ env.JOB_WEBHOOK_STATUS='Success'
"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"}],\ 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} ''' "username": "Jenkins"}' ${BUILDS_DISCORD} '''
} }
} }
} }
cleanup { cleanup {
sh '''#! /bin/bash sh '''#! /bin/bash
echo "Performing docker system prune!!" echo "Pruning builder!!"
containers=$(docker ps -aq) docker builder prune -f --builder container || :
containers=$(docker ps -q)
if [[ -n "${containers}" ]]; then 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 fi
docker system prune -af --volumes || : docker system prune -f --volumes || :
''' '''
cleanWs() cleanWs()
} }
} }
} }
def retry_backoff(int max_attempts, int power_base, Closure c) {
int n = 0
while (n < max_attempts) {
try {
c()
return
} catch (err) {
if ((n + 1) >= max_attempts) {
throw err
}
sleep(power_base ** n)
n++
}
}
return
}

View File

@@ -3,7 +3,7 @@
[![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)](https://linuxserver.io) [![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!") [![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.") [![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.") [![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.") [![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: 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! * [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. * [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. * [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. * [GitHub](https://github.com/linuxserver) - view the source for all of our repositories.
@@ -28,7 +28,7 @@ Find us at:
# [linuxserver/qbittorrent](https://github.com/linuxserver/docker-qbittorrent) # [linuxserver/qbittorrent](https://github.com/linuxserver/docker-qbittorrent)
[![Scarf.io pulls](https://scarf.sh/installs-badge/linuxserver-ci/linuxserver%2Fqbittorrent?color=94398d&label-color=555555&logo-color=ffffff&style=for-the-badge&package-type=docker)](https://scarf.sh/gateway/linuxserver-ci/docker/linuxserver%2Fqbittorrent) [![Scarf.io pulls](https://scarf.sh/installs-badge/linuxserver-ci/linuxserver%2Fqbittorrent?color=94398d&label-color=555555&logo-color=ffffff&style=for-the-badge&package-type=docker)](https://scarf.sh)
[![GitHub Stars](https://img.shields.io/github/stars/linuxserver/docker-qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-qbittorrent) [![GitHub Stars](https://img.shields.io/github/stars/linuxserver/docker-qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-qbittorrent)
[![GitHub Release](https://img.shields.io/github/release/linuxserver/docker-qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-qbittorrent/releases) [![GitHub Release](https://img.shields.io/github/release/linuxserver/docker-qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-qbittorrent/releases)
[![GitHub Package Repository](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub%20Package&logo=github)](https://github.com/linuxserver/docker-qbittorrent/packages) [![GitHub Package Repository](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub%20Package&logo=github)](https://github.com/linuxserver/docker-qbittorrent/packages)
@@ -37,7 +37,7 @@ Find us at:
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/linuxserver/qbittorrent) [![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/linuxserver/qbittorrent)
[![Docker Stars](https://img.shields.io/docker/stars/linuxserver/qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/linuxserver/qbittorrent) [![Docker Stars](https://img.shields.io/docker/stars/linuxserver/qbittorrent.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/linuxserver/qbittorrent)
[![Jenkins Build](https://img.shields.io/jenkins/build?labelColor=555555&logoColor=ffffff&style=for-the-badge&jobUrl=https%3A%2F%2Fci.linuxserver.io%2Fjob%2FDocker-Pipeline-Builders%2Fjob%2Fdocker-qbittorrent%2Fjob%2Flibtorrentv1%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/) [![Jenkins Build](https://img.shields.io/jenkins/build?labelColor=555555&logoColor=ffffff&style=for-the-badge&jobUrl=https%3A%2F%2Fci.linuxserver.io%2Fjob%2FDocker-Pipeline-Builders%2Fjob%2Fdocker-qbittorrent%2Fjob%2Flibtorrentv1%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-qbittorrent/job/libtorrentv1/)
[![LSIO CI](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=CI&query=CI&url=https%3A%2F%2Fci-tests.linuxserver.io%2Flinuxserver%2Fqbittorrent%2Flatest%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/qbittorrent/latest/index.html) [![LSIO CI](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=CI&query=CI&url=https%3A%2F%2Fci-tests.linuxserver.io%2Flinuxserver%2Fqbittorrent%2Flibtorrentv1%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/qbittorrent/libtorrentv1/index.html)
The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library. The [Qbittorrent](https://www.qbittorrent.org/) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library.
@@ -80,10 +80,27 @@ Due to issues with CSRF and port mapping, should you require to alter the port f
For example, to set the port to 8090 you need to set -p 8090:8090 and -e WEBUI_PORT=8090 For example, to set the port to 8090 you need to set -p 8090:8090 and -e WEBUI_PORT=8090
### TORRENTING_PORT
A bittorrent client can be an active or a passive node. Running your client as an active node has the advantage of being able to connect to both active and passive peers, and can potentially increase the number of incoming connections. This requires an open port on the host machine which might differ from container's internal one.
Similarly to the WEBUI_PORT, to set the port to 6887 you need to pass -p 6887:6887, -p 6887:6887/udp and -e TORRENTING_PORT=6887 arguments to Docker.
## Read-Only Operation
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 ## Usage
To help you get started creating a container from this image you can either use docker-compose or the docker cli. 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)) ### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose))
```yaml ```yaml
@@ -97,9 +114,10 @@ services:
- PGID=1000 - PGID=1000
- TZ=Etc/UTC - TZ=Etc/UTC
- WEBUI_PORT=8080 - WEBUI_PORT=8080
- TORRENTING_PORT=6881
volumes: volumes:
- /path/to/appdata/config:/config - /path/to/qbittorrent/appdata:/config
- /path/to/downloads:/downloads - /path/to/downloads:/downloads #optional
ports: ports:
- 8080:8080 - 8080:8080
- 6881:6881 - 6881:6881
@@ -116,11 +134,12 @@ docker run -d \
-e PGID=1000 \ -e PGID=1000 \
-e TZ=Etc/UTC \ -e TZ=Etc/UTC \
-e WEBUI_PORT=8080 \ -e WEBUI_PORT=8080 \
-e TORRENTING_PORT=6881 \
-p 8080:8080 \ -p 8080:8080 \
-p 6881:6881 \ -p 6881:6881 \
-p 6881:6881/udp \ -p 6881:6881/udp \
-v /path/to/appdata/config:/config \ -v /path/to/qbittorrent/appdata:/config \
-v /path/to/downloads:/downloads \ -v /path/to/downloads:/downloads `#optional` \
--restart unless-stopped \ --restart unless-stopped \
lscr.io/linuxserver/qbittorrent:libtorrentv1 lscr.io/linuxserver/qbittorrent:libtorrentv1
``` ```
@@ -131,15 +150,18 @@ Containers are configured using parameters passed at runtime (such as those abov
| Parameter | Function | | Parameter | Function |
| :----: | --- | | :----: | --- |
| `-p 8080` | WebUI | | `-p 8080:8080` | WebUI |
| `-p 6881` | tcp connection port | | `-p 6881:6881` | tcp connection port |
| `-p 6881/udp` | udp connection port | | `-p 6881:6881/udp` | udp connection port |
| `-e PUID=1000` | for UserID - see below for explanation | | `-e PUID=1000` | for UserID - see below for explanation |
| `-e PGID=1000` | for GroupID - 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). | | `-e TZ=Etc/UTC` | specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List). |
| `-e WEBUI_PORT=8080` | for changing the port of the web UI, see below for explanation | | `-e WEBUI_PORT=8080` | for changing the port of the web UI, see below for explanation |
| `-e TORRENTING_PORT=6881` | for changing the port of tcp/udp connection, see below for explanation |
| `-v /config` | Contains all relevant configuration files. | | `-v /config` | Contains all relevant configuration files. |
| `-v /downloads` | Location of downloads on disk. | | `-v /downloads` | Location of downloads on disk. |
| `--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) ## Environment variables from files (Docker secrets)
@@ -277,7 +299,8 @@ Below are the instructions for updating containers:
### Image Update Notifications - Diun (Docker Image Update Notifier) ### 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 ## Building locally
@@ -292,16 +315,22 @@ docker build \
-t lscr.io/linuxserver/qbittorrent:libtorrentv1 . -t lscr.io/linuxserver/qbittorrent:libtorrentv1 .
``` ```
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 ```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`. Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`.
## Versions ## Versions
* **20.12.24:** - Rebase to Alpine 3.21.
* **17.07.24:** - Restore qbittorrent-cli as it now supports openssl 3.
* **25.05.24:** - Rebase to Alpine 3.20, remove qbittorrent-cli as it still requires openssl 1.1 which is EOL.
* **14.02.24:** - Only set/override torrenting port if the optional env var is set.
* **14.02.24:** - Add torrenting port support.
* **31.01.24:** - Rebase to Alpine 3.19.
* **25.12.23:** - Only pull stable releases of qbittorrent-cli. * **25.12.23:** - Only pull stable releases of qbittorrent-cli.
* **07.10.23:** - Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar). * **07.10.23:** - Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar).
* **10.08.23:** - Bump unrar to 6.2.10. * **10.08.23:** - Bump unrar to 6.2.10.

View File

@@ -7,7 +7,6 @@ custom_version_command: "curl -sL 'https://api.github.com/repos/userdocs/qbittor
release_type: prerelease release_type: prerelease
release_tag: libtorrentv1 release_tag: libtorrentv1
ls_branch: libtorrentv1 ls_branch: libtorrentv1
build_armhf: false
repo_vars: repo_vars:
- CONTAINER_NAME = 'qbittorrent' - CONTAINER_NAME = 'qbittorrent'
- BUILD_VERSION_ARG = 'QBITTORRENT_VERSION' - BUILD_VERSION_ARG = 'QBITTORRENT_VERSION'
@@ -17,13 +16,12 @@ repo_vars:
- DEV_DOCKERHUB_IMAGE = 'lsiodev/qbittorrent' - DEV_DOCKERHUB_IMAGE = 'lsiodev/qbittorrent'
- PR_DOCKERHUB_IMAGE = 'lspipepr/qbittorrent' - PR_DOCKERHUB_IMAGE = 'lspipepr/qbittorrent'
- DIST_IMAGE = 'alpine' - DIST_IMAGE = 'alpine'
- DIST_TAG = '3.18'
- MULTIARCH='true' - MULTIARCH='true'
- CI='true' - CI='true'
- CI_WEB='true' - CI_WEB='true'
- CI_PORT='8080' - CI_PORT='8080'
- CI_SSL='false' - CI_SSL='false'
- CI_DELAY='120' - CI_DELAY='60'
- CI_DOCKERENV='TZ=US/Pacific' - CI_DOCKERENV=''
- CI_AUTH='user:password' - CI_AUTH=''
- CI_WEBPATH='' - CI_WEBPATH=''

View File

@@ -1,253 +1,260 @@
NAME VERSION TYPE NAME VERSION TYPE
7zip 22.01-r5 apk 7zip 24.08-r0 apk
Alba.CsConsoleFormat 1.0.0.89 dotnet Alba.CsConsoleFormat 1.0.0.89 dotnet
BencodeNET 2.3.0.0 dotnet BencodeNET 2.3.0.0 dotnet
Bouncy Castle for .NET (netstandard2.0) 1.8.8.2 dotnet Bouncy Castle for .NET (netstandard2.0) 1.8.8.2 dotnet
CommandLineUtils 2.4.4+3c2a4909757a51602dcca9b961d577511b85fd31.3c2a4909757a51602dcca9b961d577511b85fd31 dotnet CommandLineUtils 2.4.4+3c2a4909757a51602dcca9b961d577511b85fd31.3c2a4909757a51602dcca9b961d577511b85fd31 dotnet
CsvHelper 12.0.0.0 dotnet CsvHelper 12.1.2 dotnet
Json.NET 13.0.3.27908 dotnet Json.NET 13.0.3.27908 dotnet
Microsoft.CSharp 4.700.22.56512 dotnet Microsoft.CSharp 6.0.3524.45918 dotnet
Microsoft.VisualBasic 4.700.22.56512 dotnet Microsoft.VisualBasic 6.0.3524.45918 dotnet
Microsoft.VisualBasic.Core 4.700.22.56512 dotnet Microsoft.VisualBasic.Core 11.100.3524.45918 dotnet
Microsoft.Win32.Primitives 4.700.22.56512 dotnet Microsoft.Win32.Primitives 6.0.3524.45918 dotnet
Microsoft.Win32.Registry 4.700.22.56512 dotnet Microsoft.Win32.Registry 6.0.3524.45918 dotnet
Mono.Posix.NETStandard 1.0.0.0 dotnet Mono.Posix.NETStandard 1.0.0.0 dotnet
NJsonSchema 9.14.1.0 dotnet NJsonSchema 9.14.1.0 dotnet
Portable.Xaml.dll 0.18.0.0 dotnet Portable.Xaml.dll 0.18.0.0 dotnet
QBittorrent.Client 1.9.23349.1 dotnet QBittorrent.Client 1.9.24285.1 dotnet
System 4.700.22.56512 dotnet System 6.0.3524.45918 dotnet
System.AppContext 4.700.22.56512 dotnet System.AppContext 6.0.3524.45918 dotnet
System.Buffers 4.700.22.56512 dotnet System.Buffers 6.0.3524.45918 dotnet
System.Collections 4.700.22.56512 dotnet System.Collections 6.0.3524.45918 dotnet
System.Collections.Concurrent 4.700.22.56512 dotnet System.Collections.Concurrent 6.0.3524.45918 dotnet
System.Collections.Immutable 4.700.22.56512 dotnet System.Collections.Immutable 6.0.3524.45918 dotnet
System.Collections.NonGeneric 4.700.22.56512 dotnet System.Collections.NonGeneric 6.0.3524.45918 dotnet
System.Collections.Specialized 4.700.22.56512 dotnet System.Collections.Specialized 6.0.3524.45918 dotnet
System.ComponentModel 4.700.22.56512 dotnet System.ComponentModel 6.0.3524.45918 dotnet
System.ComponentModel.Annotations 4.700.22.56512 dotnet System.ComponentModel.Annotations 6.0.3524.45918 dotnet
System.ComponentModel.DataAnnotations 4.700.22.56512 dotnet System.ComponentModel.DataAnnotations 6.0.3524.45918 dotnet
System.ComponentModel.EventBasedAsync 4.700.22.56512 dotnet System.ComponentModel.EventBasedAsync 6.0.3524.45918 dotnet
System.ComponentModel.Primitives 4.700.22.56512 dotnet System.ComponentModel.Primitives 6.0.3524.45918 dotnet
System.ComponentModel.TypeConverter 4.700.22.56512 dotnet System.ComponentModel.TypeConverter 6.0.3524.45918 dotnet
System.Configuration 4.700.22.56512 dotnet System.Configuration 6.0.3524.45918 dotnet
System.Console 4.700.22.56512 dotnet System.Console 6.0.3524.45918 dotnet
System.Core 4.700.22.56512 dotnet System.Core 6.0.3524.45918 dotnet
System.Data 4.700.22.56512 dotnet System.Data 6.0.3524.45918 dotnet
System.Data.Common 4.700.22.56512 dotnet System.Data.Common 6.0.3524.45918 dotnet
System.Data.DataSetExtensions 4.700.22.56512 dotnet System.Data.DataSetExtensions 6.0.3524.45918 dotnet
System.Diagnostics.Contracts 4.700.22.56512 dotnet System.Diagnostics.Contracts 6.0.3524.45918 dotnet
System.Diagnostics.Debug 4.700.22.56512 dotnet System.Diagnostics.Debug 6.0.3524.45918 dotnet
System.Diagnostics.DiagnosticSource 4.700.22.56512 dotnet System.Diagnostics.DiagnosticSource 6.0.3524.45918 dotnet
System.Diagnostics.FileVersionInfo 4.700.22.56512 dotnet System.Diagnostics.FileVersionInfo 6.0.3524.45918 dotnet
System.Diagnostics.Process 4.700.22.56512 dotnet System.Diagnostics.Process 6.0.3524.45918 dotnet
System.Diagnostics.StackTrace 4.700.22.56512 dotnet System.Diagnostics.StackTrace 6.0.3524.45918 dotnet
System.Diagnostics.TextWriterTraceListener 4.700.22.56512 dotnet System.Diagnostics.TextWriterTraceListener 6.0.3524.45918 dotnet
System.Diagnostics.Tools 4.700.22.56512 dotnet System.Diagnostics.Tools 6.0.3524.45918 dotnet
System.Diagnostics.TraceSource 4.700.22.56512 dotnet System.Diagnostics.TraceSource 6.0.3524.45918 dotnet
System.Diagnostics.Tracing 4.700.22.56512 dotnet System.Diagnostics.Tracing 6.0.3524.45918 dotnet
System.Drawing 4.700.22.56512 dotnet System.Drawing 6.0.3524.45918 dotnet
System.Drawing.Primitives 4.700.22.56512 dotnet System.Drawing.Primitives 6.0.3524.45918 dotnet
System.Dynamic.Runtime 4.700.22.56512 dotnet System.Dynamic.Runtime 6.0.3524.45918 dotnet
System.Globalization 4.700.22.56512 dotnet System.Formats.Asn1 6.0.3524.45918 dotnet
System.Globalization.Calendars 4.700.22.56512 dotnet System.Globalization 6.0.3524.45918 dotnet
System.Globalization.Extensions 4.700.22.56512 dotnet System.Globalization.Calendars 6.0.3524.45918 dotnet
System.IO 4.700.22.56512 dotnet System.Globalization.Extensions 6.0.3524.45918 dotnet
System.IO.Compression 4.700.22.56512 dotnet System.IO 6.0.3524.45918 dotnet
System.IO.Compression.Brotli 4.700.22.56512 dotnet System.IO.Compression 6.0.3524.45918 dotnet
System.IO.Compression.FileSystem 4.700.22.56512 dotnet System.IO.Compression.Brotli 6.0.3524.45918 dotnet
System.IO.Compression.ZipFile 4.700.22.56512 dotnet System.IO.Compression.FileSystem 6.0.3524.45918 dotnet
System.IO.FileSystem 4.700.22.56512 dotnet System.IO.Compression.ZipFile 6.0.3524.45918 dotnet
System.IO.FileSystem.AccessControl 4.700.22.56512 dotnet System.IO.FileSystem 6.0.3524.45918 dotnet
System.IO.FileSystem.DriveInfo 4.700.22.56512 dotnet System.IO.FileSystem.AccessControl 6.0.3524.45918 dotnet
System.IO.FileSystem.Primitives 4.700.22.56512 dotnet System.IO.FileSystem.DriveInfo 6.0.3524.45918 dotnet
System.IO.FileSystem.Watcher 4.700.22.56512 dotnet System.IO.FileSystem.Primitives 6.0.3524.45918 dotnet
System.IO.IsolatedStorage 4.700.22.56512 dotnet System.IO.FileSystem.Watcher 6.0.3524.45918 dotnet
System.IO.MemoryMappedFiles 4.700.22.56512 dotnet System.IO.IsolatedStorage 6.0.3524.45918 dotnet
System.IO.Pipes 4.700.22.56512 dotnet System.IO.MemoryMappedFiles 6.0.3524.45918 dotnet
System.IO.Pipes.AccessControl 4.700.22.56512 dotnet System.IO.Pipes 6.0.3524.45918 dotnet
System.IO.UnmanagedMemoryStream 4.700.22.56512 dotnet System.IO.Pipes.AccessControl 6.0.3524.45918 dotnet
System.Linq 4.700.22.56512 dotnet System.IO.UnmanagedMemoryStream 6.0.3524.45918 dotnet
System.Linq.Expressions 4.700.22.56512 dotnet System.Linq 6.0.3524.45918 dotnet
System.Linq.Parallel 4.700.22.56512 dotnet System.Linq.Expressions 6.0.3524.45918 dotnet
System.Linq.Queryable 4.700.22.56512 dotnet System.Linq.Parallel 6.0.3524.45918 dotnet
System.Memory 4.700.22.56512 dotnet System.Linq.Queryable 6.0.3524.45918 dotnet
System.Net 4.700.22.56512 dotnet System.Memory 6.0.3524.45918 dotnet
System.Net.Http 4.700.22.56512 dotnet System.Net 6.0.3524.45918 dotnet
System.Net.HttpListener 4.700.22.56512 dotnet System.Net.Http 6.0.3524.45918 dotnet
System.Net.IPNetwork 2.5.235 dotnet System.Net.Http.Json 6.0.3524.45918 dotnet
System.Net.Mail 4.700.22.56512 dotnet System.Net.HttpListener 6.0.3524.45918 dotnet
System.Net.NameResolution 4.700.22.56512 dotnet System.Net.IPNetwork 2.5.235 dotnet
System.Net.NetworkInformation 4.700.22.56512 dotnet System.Net.Mail 6.0.3524.45918 dotnet
System.Net.Ping 4.700.22.56512 dotnet System.Net.NameResolution 6.0.3524.45918 dotnet
System.Net.Primitives 4.700.22.56512 dotnet System.Net.NetworkInformation 6.0.3524.45918 dotnet
System.Net.Requests 4.700.22.56512 dotnet System.Net.Ping 6.0.3524.45918 dotnet
System.Net.Security 4.700.22.56512 dotnet System.Net.Primitives 6.0.3524.45918 dotnet
System.Net.ServicePoint 4.700.22.56512 dotnet System.Net.Quic 6.0.3524.45918 dotnet
System.Net.Sockets 4.700.22.56512 dotnet System.Net.Requests 6.0.3524.45918 dotnet
System.Net.WebClient 4.700.22.56512 dotnet System.Net.Security 6.0.3524.45918 dotnet
System.Net.WebHeaderCollection 4.700.22.56512 dotnet System.Net.ServicePoint 6.0.3524.45918 dotnet
System.Net.WebProxy 4.700.22.56512 dotnet System.Net.Sockets 6.0.3524.45918 dotnet
System.Net.WebSockets 4.700.22.56512 dotnet System.Net.WebClient 6.0.3524.45918 dotnet
System.Net.WebSockets.Client 4.700.22.56512 dotnet System.Net.WebHeaderCollection 6.0.3524.45918 dotnet
System.Numerics 4.700.22.56512 dotnet System.Net.WebProxy 6.0.3524.45918 dotnet
System.Numerics.Vectors 4.700.22.56512 dotnet System.Net.WebSockets 6.0.3524.45918 dotnet
System.ObjectModel 4.700.22.56512 dotnet System.Net.WebSockets.Client 6.0.3524.45918 dotnet
System.Private.CoreLib 3.1.32-servicing.22559.2+c17d273aa03d4b9d14c92248a91f0d0faa881b98 dotnet System.Numerics 6.0.3524.45918 dotnet
System.Private.DataContractSerialization 4.700.22.56512 dotnet System.Numerics.Vectors 6.0.3524.45918 dotnet
System.Private.Uri 4.700.22.56512 dotnet System.ObjectModel 6.0.3524.45918 dotnet
System.Private.Xml 4.700.22.56512 dotnet System.Private.CoreLib 6.0.3524.45918 dotnet
System.Private.Xml.Linq 4.700.22.56512 dotnet System.Private.DataContractSerialization 6.0.3524.45918 dotnet
System.Reflection 4.700.22.56512 dotnet System.Private.Uri 6.0.3524.45918 dotnet
System.Reflection.DispatchProxy 4.700.22.56512 dotnet System.Private.Xml 6.0.3524.45918 dotnet
System.Reflection.Emit 4.700.22.56512 dotnet System.Private.Xml.Linq 6.0.3524.45918 dotnet
System.Reflection.Emit.ILGeneration 4.700.22.56512 dotnet System.Reflection 6.0.3524.45918 dotnet
System.Reflection.Emit.Lightweight 4.700.22.56512 dotnet System.Reflection.DispatchProxy 6.0.3524.45918 dotnet
System.Reflection.Extensions 4.700.22.56512 dotnet System.Reflection.Emit 6.0.3524.45918 dotnet
System.Reflection.Metadata 4.700.22.56512 dotnet System.Reflection.Emit.ILGeneration 6.0.3524.45918 dotnet
System.Reflection.Primitives 4.700.22.56512 dotnet System.Reflection.Emit.Lightweight 6.0.3524.45918 dotnet
System.Reflection.TypeExtensions 4.700.22.56512 dotnet System.Reflection.Extensions 6.0.3524.45918 dotnet
System.Resources.Reader 4.700.22.56512 dotnet System.Reflection.Metadata 6.0.3524.45918 dotnet
System.Resources.ResourceManager 4.700.22.56512 dotnet System.Reflection.Primitives 6.0.3524.45918 dotnet
System.Resources.Writer 4.700.22.56512 dotnet System.Reflection.TypeExtensions 6.0.3524.45918 dotnet
System.Runtime 4.700.22.56512 dotnet System.Resources.Reader 6.0.3524.45918 dotnet
System.Runtime.CompilerServices.VisualC 4.700.22.56512 dotnet System.Resources.ResourceManager 6.0.3524.45918 dotnet
System.Runtime.Extensions 4.700.22.56512 dotnet System.Resources.Writer 6.0.3524.45918 dotnet
System.Runtime.Handles 4.700.22.56512 dotnet System.Runtime 6.0.3524.45918 dotnet
System.Runtime.InteropServices 4.700.22.56512 dotnet System.Runtime.CompilerServices.VisualC 6.0.3524.45918 dotnet
System.Runtime.InteropServices.RuntimeInformation 4.700.22.56512 dotnet System.Runtime.Extensions 6.0.3524.45918 dotnet
System.Runtime.InteropServices.WindowsRuntime 4.700.22.56512 dotnet System.Runtime.Handles 6.0.3524.45918 dotnet
System.Runtime.Intrinsics 4.700.22.56512 dotnet System.Runtime.InteropServices 6.0.3524.45918 dotnet
System.Runtime.Loader 4.700.22.56512 dotnet System.Runtime.InteropServices.RuntimeInformation 6.0.3524.45918 dotnet
System.Runtime.Numerics 4.700.22.56512 dotnet System.Runtime.Intrinsics 6.0.3524.45918 dotnet
System.Runtime.Serialization 4.700.22.56512 dotnet System.Runtime.Loader 6.0.3524.45918 dotnet
System.Runtime.Serialization.Formatters 4.700.22.56512 dotnet System.Runtime.Numerics 6.0.3524.45918 dotnet
System.Runtime.Serialization.Json 4.700.22.56512 dotnet System.Runtime.Serialization 6.0.3524.45918 dotnet
System.Runtime.Serialization.Primitives 4.700.22.56512 dotnet System.Runtime.Serialization.Formatters 6.0.3524.45918 dotnet
System.Runtime.Serialization.Xml 4.700.22.56512 dotnet System.Runtime.Serialization.Json 6.0.3524.45918 dotnet
System.Runtime.WindowsRuntime 4.700.22.56512 dotnet System.Runtime.Serialization.Primitives 6.0.3524.45918 dotnet
System.Runtime.WindowsRuntime.UI.Xaml 4.700.22.56512 dotnet System.Runtime.Serialization.Xml 6.0.3524.45918 dotnet
System.Security 4.700.22.56512 dotnet System.Security 6.0.3524.45918 dotnet
System.Security.AccessControl 4.700.22.56512 dotnet System.Security.AccessControl 6.0.3524.45918 dotnet
System.Security.Claims 4.700.22.56512 dotnet System.Security.Claims 6.0.3524.45918 dotnet
System.Security.Cryptography.Algorithms 4.700.22.56512 dotnet System.Security.Cryptography.Algorithms 6.0.3524.45918 dotnet
System.Security.Cryptography.Cng 4.700.22.56512 dotnet System.Security.Cryptography.Cng 6.0.3524.45918 dotnet
System.Security.Cryptography.Csp 4.700.22.56512 dotnet System.Security.Cryptography.Csp 6.0.3524.45918 dotnet
System.Security.Cryptography.Encoding 4.700.22.56512 dotnet System.Security.Cryptography.Encoding 6.0.3524.45918 dotnet
System.Security.Cryptography.OpenSsl 4.700.22.56512 dotnet System.Security.Cryptography.OpenSsl 6.0.3524.45918 dotnet
System.Security.Cryptography.Primitives 4.700.22.56512 dotnet System.Security.Cryptography.Primitives 6.0.3524.45918 dotnet
System.Security.Cryptography.ProtectedData 5.0.20.51904 dotnet System.Security.Cryptography.ProtectedData 5.0.20.51904 dotnet
System.Security.Cryptography.X509Certificates 4.700.22.56512 dotnet System.Security.Cryptography.X509Certificates 6.0.3524.45918 dotnet
System.Security.Principal 4.700.22.56512 dotnet System.Security.Principal 6.0.3524.45918 dotnet
System.Security.Principal.Windows 4.700.22.56512 dotnet System.Security.Principal.Windows 6.0.3524.45918 dotnet
System.Security.SecureString 4.700.22.56512 dotnet System.Security.SecureString 6.0.3524.45918 dotnet
System.ServiceModel.Web 4.700.22.56512 dotnet System.ServiceModel.Web 6.0.3524.45918 dotnet
System.ServiceProcess 4.700.22.56512 dotnet System.ServiceProcess 6.0.3524.45918 dotnet
System.Text.Encoding 4.700.22.56512 dotnet System.Text.Encoding 6.0.3524.45918 dotnet
System.Text.Encoding.CodePages 4.700.22.56512 dotnet System.Text.Encoding.CodePages 6.0.3524.45918 dotnet
System.Text.Encoding.Extensions 4.700.22.56512 dotnet System.Text.Encoding.Extensions 6.0.3524.45918 dotnet
System.Text.Encodings.Web 4.700.22.56512 dotnet System.Text.Encodings.Web 6.0.3524.45918 dotnet
System.Text.Json 4.700.22.56512 dotnet System.Text.Json 6.0.3524.45918 dotnet
System.Text.RegularExpressions 4.700.22.56512 dotnet System.Text.RegularExpressions 6.0.3524.45918 dotnet
System.Threading 4.700.22.56512 dotnet System.Threading 6.0.3524.45918 dotnet
System.Threading.Channels 4.700.22.56512 dotnet System.Threading.Channels 6.0.3524.45918 dotnet
System.Threading.Overlapped 4.700.22.56512 dotnet System.Threading.Overlapped 6.0.3524.45918 dotnet
System.Threading.Tasks 4.700.22.56512 dotnet System.Threading.Tasks 6.0.3524.45918 dotnet
System.Threading.Tasks.Dataflow 4.700.22.56512 dotnet System.Threading.Tasks.Dataflow 6.0.3524.45918 dotnet
System.Threading.Tasks.Extensions 4.700.22.56512 dotnet System.Threading.Tasks.Extensions 6.0.3524.45918 dotnet
System.Threading.Tasks.Parallel 4.700.22.56512 dotnet System.Threading.Tasks.Parallel 6.0.3524.45918 dotnet
System.Threading.Thread 4.700.22.56512 dotnet System.Threading.Thread 6.0.3524.45918 dotnet
System.Threading.ThreadPool 4.700.22.56512 dotnet System.Threading.ThreadPool 6.0.3524.45918 dotnet
System.Threading.Timer 4.700.22.56512 dotnet System.Threading.Timer 6.0.3524.45918 dotnet
System.Transactions 4.700.22.56512 dotnet System.Transactions 6.0.3524.45918 dotnet
System.Transactions.Local 4.700.22.56512 dotnet System.Transactions.Local 6.0.3524.45918 dotnet
System.ValueTuple 4.700.22.56512 dotnet System.ValueTuple 6.0.3524.45918 dotnet
System.Web 4.700.22.56512 dotnet System.Web 6.0.3524.45918 dotnet
System.Web.HttpUtility 4.700.22.56512 dotnet System.Web.HttpUtility 6.0.3524.45918 dotnet
System.Windows 4.700.22.56512 dotnet System.Windows 6.0.3524.45918 dotnet
System.Xml 4.700.22.56512 dotnet System.Xml 6.0.3524.45918 dotnet
System.Xml.Linq 4.700.22.56512 dotnet System.Xml.Linq 6.0.3524.45918 dotnet
System.Xml.ReaderWriter 4.700.22.56512 dotnet System.Xml.ReaderWriter 6.0.3524.45918 dotnet
System.Xml.Serialization 4.700.22.56512 dotnet System.Xml.Serialization 6.0.3524.45918 dotnet
System.Xml.XDocument 4.700.22.56512 dotnet System.Xml.XDocument 6.0.3524.45918 dotnet
System.Xml.XPath 4.700.22.56512 dotnet System.Xml.XPath 6.0.3524.45918 dotnet
System.Xml.XPath.XDocument 4.700.22.56512 dotnet System.Xml.XPath.XDocument 6.0.3524.45918 dotnet
System.Xml.XmlDocument 4.700.22.56512 dotnet System.Xml.XmlDocument 6.0.3524.45918 dotnet
System.Xml.XmlSerializer 4.700.22.56512 dotnet System.Xml.XmlSerializer 6.0.3524.45918 dotnet
WindowsBase 4.700.22.56512 dotnet WindowsBase 6.0.3524.45918 dotnet
alpine-baselayout 3.4.3-r1 apk acl-libs 2.3.2-r1 apk
alpine-baselayout-data 3.4.3-r1 apk alpine-baselayout 3.6.8-r1 apk
alpine-keys 2.4-r1 apk alpine-baselayout-data 3.6.8-r1 apk
alpine-release 3.18.5-r0 apk alpine-keys 2.5-r0 apk
apk-tools 2.14.0-r2 apk alpine-release 3.21.2-r0 apk
bash 5.2.15-r5 apk apk-tools 2.14.6-r2 apk
brotli-libs 1.0.9-r14 apk bash 5.2.37-r0 apk
busybox 1.36.1-r5 apk brotli-libs 1.1.0-r2 apk
busybox-binsh 1.36.1-r5 apk busybox 1.37.0-r12 apk
ca-certificates 20230506-r0 apk busybox-binsh 1.37.0-r12 apk
ca-certificates-bundle 20230506-r0 apk c-ares 1.34.3-r0 apk
coreutils 9.3-r1 apk ca-certificates 20241121-r1 apk
curl 8.5.0-r0 apk ca-certificates-bundle 20241121-r1 apk
dbus-libs 1.14.8-r0 apk catatonit 0.2.0-r0 apk
double-conversion 3.2.1-r1 apk coreutils 9.5-r2 apk
gdbm 1.23-r1 apk coreutils-env 9.5-r2 apk
glib 2.76.4-r0 apk coreutils-fmt 9.5-r2 apk
icu-data-en 73.2-r2 apk coreutils-sha512sum 9.5-r2 apk
icu-libs 73.2-r2 apk curl 8.11.1-r0 apk
jq 1.6-r4 apk dbus-libs 1.14.10-r4 apk
libacl 2.3.1-r3 apk double-conversion 3.3.0-r0 apk
libattr 2.5.1-r4 apk duktape 2.7.0-r1 apk
libb2 0.98.1-r2 apk findutils 4.10.0-r0 apk
libblkid 2.38.1-r8 apk gdbm 1.24-r0 apk
libbsd 0.11.7-r1 apk glib 2.82.4-r0 apk
libbz2 1.0.8-r5 apk grep 3.11-r0 apk
libc-utils 0.7.2-r5 apk icu-data-en 74.2-r0 apk
libcrypto1.1 1.1.1u-r1 apk icu-libs 74.2-r0 apk
libcrypto3 3.1.4-r3 apk jq 1.7.1-r0 apk
libcurl 8.5.0-r0 apk libattr 2.5.2-r2 apk
libexpat 2.5.0-r1 apk libb2 0.98.1-r3 apk
libffi 3.4.4-r2 apk libblkid 2.40.4-r0 apk
libgcc 12.2.1_git20220924-r10 apk libbsd 0.12.2-r0 apk
libgomp 12.2.1_git20220924-r10 apk libbz2 1.0.8-r6 apk
libidn2 2.3.4-r1 apk libcrypto3 3.3.2-r4 apk
libintl 0.21.1-r7 apk libcurl 8.11.1-r0 apk
libmd 1.0.4-r2 apk libeconf 0.6.3-r0 apk
libmount 2.38.1-r8 apk libexpat 2.6.4-r0 apk
libncursesw 6.4_p20230506-r0 apk libffi 3.4.6-r0 apk
libpanelw 6.4_p20230506-r0 apk libgcc 14.2.0-r4 apk
libpcre2-16 10.42-r1 apk libgomp 14.2.0-r4 apk
libproc2 4.0.4-r0 apk libidn2 2.3.7-r0 apk
libssl1.1 1.1.1u-r1 apk libintl 0.22.5-r0 apk
libssl3 3.1.4-r3 apk libmd 1.1.0-r0 apk
libstdc++ 12.2.1_git20220924-r10 apk libmount 2.40.4-r0 apk
libunistring 1.1-r1 apk libncursesw 6.5_p20241006-r3 apk
linux-pam 1.5.2-r10 apk libpanelw 6.5_p20241006-r3 apk
mpdecimal 2.5.1-r2 apk libpcre2-16 10.43-r0 apk
mscorlib 4.700.22.56512 dotnet libproc2 4.0.4-r2 apk
musl 1.2.4-r2 apk libproxy 0.5.9-r0 apk
musl-utils 1.2.4-r2 apk libpsl 0.21.5-r3 apk
ncurses-terminfo-base 6.4_p20230506-r0 apk libssl3 3.3.2-r4 apk
netcat-openbsd 1.219-r1 apk libstdc++ 14.2.0-r4 apk
netstandard 4.700.22.56512 dotnet libunistring 1.2-r0 apk
nghttp2-libs 1.57.0-r0 apk linux-pam 1.6.1-r1 apk
oniguruma 6.9.8-r1 apk mpdecimal 4.0.0-r0 apk
openssl1.1-compat 1.1.1u-r1 apk mscorlib 6.0.3524.45918 dotnet
pcre2 10.42-r1 apk musl 1.2.5-r8 apk
procps-ng 4.0.4-r0 apk musl-utils 1.2.5-r8 apk
pyc 0.1-r0 apk ncurses-terminfo-base 6.5_p20241006-r3 apk
python3 3.11.6-r0 apk netcat-openbsd 1.226.1.1-r0 apk
python3-pyc 3.11.6-r0 apk netstandard 6.0.3524.45918 dotnet
python3-pycache-pyc0 3.11.6-r0 apk nghttp2-libs 1.64.0-r0 apk
qbt 1.8.24012.1+00a638ba43f1a80a03cc8be139f586ce9886c908 dotnet oniguruma 6.9.9-r0 apk
qt6-qtbase 6.5.2-r0 apk pcre2 10.43-r0 apk
qt6-qtbase-sqlite 6.5.2-r0 apk procps-ng 4.0.4-r2 apk
readline 8.2.1-r1 apk pyc 3.12.8-r1 apk
scanelf 1.3.7-r1 apk python3 3.12.8-r1 apk
shadow 4.13-r4 apk python3-pyc 3.12.8-r1 apk
skalibs 2.13.1.1-r1 apk python3-pycache-pyc0 3.12.8-r1 apk
sqlite-libs 3.41.2-r2 apk qbt 1.8.24285.1+c5794123bd204e629729e52e7177834c4ba3bfc2 dotnet
ssl_client 1.36.1-r5 apk qt6-qtbase 6.8.0-r1 apk
tzdata 2023d-r0 apk qt6-qtbase-sqlite 6.8.0-r1 apk
utmps-libs 0.1.2.1-r1 apk readline 8.2.13-r0 apk
xz-libs 5.4.3-r0 apk scanelf 1.3.8-r1 apk
zlib 1.2.13-r1 apk shadow 4.16.0-r1 apk
zstd-libs 1.5.5-r4 apk skalibs-libs 2.14.3.0-r0 apk
sqlite-libs 3.47.1-r0 apk
ssl_client 1.37.0-r12 apk
tzdata 2024b-r1 apk
utmps-libs 0.1.2.3-r2 apk
xz-libs 5.6.3-r0 apk
zlib 1.3.1-r2 apk
zstd-libs 1.5.6-r2 apk

View File

@@ -6,35 +6,35 @@ project_url: "https://www.qbittorrent.org/"
project_logo: "https://github.com/linuxserver/docker-templates/raw/master/linuxserver.io/img/qbittorrent-icon.png" project_logo: "https://github.com/linuxserver/docker-templates/raw/master/linuxserver.io/img/qbittorrent-icon.png"
project_blurb: "The [{{ project_name|capitalize }}]({{ project_url }}) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library." project_blurb: "The [{{ project_name|capitalize }}]({{ project_url }}) project aims to provide an open-source software alternative to µTorrent. qBittorrent is based on the Qt toolkit and libtorrent-rasterbar library."
project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}" project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}"
# supported architectures # supported architectures
available_architectures: available_architectures:
- { arch: "{{ arch_x86_64 }}", tag: "amd64-latest"} - {arch: "{{ arch_x86_64 }}", tag: "amd64-latest"}
- { arch: "{{ arch_arm64 }}", tag: "arm64v8-latest"} - {arch: "{{ arch_arm64 }}", tag: "arm64v8-latest"}
# development version # development version
development_versions: true development_versions: true
development_versions_items: development_versions_items:
- { tag: "latest", desc: "Stable qbittorrent releases" } - {tag: "latest", desc: "Stable qbittorrent releases"}
- { tag: "libtorrentv1", desc: "Static qbittorrent builds using libtorrent v1" } - {tag: "libtorrentv1", desc: "Static qbittorrent builds using libtorrent v1"}
# container parameters # container parameters
common_param_env_vars_enabled: true common_param_env_vars_enabled: true
param_container_name: "{{ project_name }}" param_container_name: "{{ project_name }}"
param_usage_include_vols: true param_usage_include_vols: true
param_volumes: param_volumes:
- { vol_path: "/config", vol_host_path: "/path/to/appdata/config", desc: "Contains all relevant configuration files." } - {vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/appdata", desc: "Contains all relevant configuration files."}
- { vol_path: "/downloads", vol_host_path: "/path/to/downloads", desc: "Location of downloads on disk." }
param_usage_include_ports: true param_usage_include_ports: true
param_ports: param_ports:
- { external_port: "8080", internal_port: "8080", port_desc: "WebUI" } - {external_port: "8080", internal_port: "8080", port_desc: "WebUI"}
- { external_port: "6881", internal_port: "6881", port_desc: "tcp connection port" } - {external_port: "6881", internal_port: "6881", port_desc: "tcp connection port"}
- { external_port: "6881", internal_port: "6881/udp", port_desc: "udp connection port" } - {external_port: "6881", internal_port: "6881/udp", port_desc: "udp connection port"}
param_usage_include_env: true param_usage_include_env: true
param_env_vars: param_env_vars:
- { env_var: "TZ", env_value: "Europe/London", desc: "Specify a timezone to use EG Europe/London"} - {env_var: "WEBUI_PORT", env_value: "8080", desc: "for changing the port of the web UI, see below for explanation"}
- { env_var: "WEBUI_PORT", env_value: "8080", desc: "for changing the port of the web UI, see below for explanation"} - {env_var: "TORRENTING_PORT", env_value: "6881", desc: "for changing the port of tcp/udp connection, see below for explanation"}
opt_param_usage_include_vols: true
opt_param_volumes:
- {vol_path: "/downloads", vol_host_path: "/path/to/downloads", desc: "Location of downloads on disk."}
readonly_supported: true
nonroot_supported: true
# application setup block # application setup block
app_setup_block_enabled: true app_setup_block_enabled: true
app_setup_block: | app_setup_block: |
@@ -50,44 +50,94 @@ app_setup_block: |
For example, to set the port to 8090 you need to set -p 8090:8090 and -e WEBUI_PORT=8090 For example, to set the port to 8090 you need to set -p 8090:8090 and -e WEBUI_PORT=8090
### TORRENTING_PORT
A bittorrent client can be an active or a passive node. Running your client as an active node has the advantage of being able to connect to both active and passive peers, and can potentially increase the number of incoming connections. This requires an open port on the host machine which might differ from container's internal one.
Similarly to the WEBUI_PORT, to set the port to 6887 you need to pass -p 6887:6887, -p 6887:6887/udp and -e TORRENTING_PORT=6887 arguments to Docker.
# init diagram
init_diagram: |
"qbittorrent:libtorrentv1": {
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-os-end -> init-config
init-config -> init-config-end
init-crontab-config -> init-config-end
init-qbittorrent-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-config -> init-qbittorrent-config
init-custom-files -> init-services
init-services -> svc-cron
svc-cron -> legacy-services
init-services -> svc-qbittorrent
svc-qbittorrent -> legacy-services
}
Base Images: {
"baseimage-alpine:3.21"
}
"qbittorrent:libtorrentv1" <- Base Images
# changelog # changelog
changelogs: changelogs:
- { date: "25.12.23:", desc: "Only pull stable releases of qbittorrent-cli."} - {date: "20.12.24:", desc: "Rebase to Alpine 3.21."}
- { date: "07.10.23:", desc: "Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar)."} - {date: "17.07.24:", desc: "Restore qbittorrent-cli as it now supports openssl 3."}
- { date: "10.08.23:", desc: "Bump unrar to 6.2.10."} - {date: "25.05.24:", desc: "Rebase to Alpine 3.20, remove qbittorrent-cli as it still requires openssl 1.1 which is EOL."}
- { date: "17.06.23:", desc: "Rebase to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf)." } - {date: "14.02.24:", desc: "Only set/override torrenting port if the optional env var is set."}
- { date: "10.06.23:", desc: "Bump unrar to 6.2.8." } - {date: "14.02.24:", desc: "Add torrenting port support."}
- { date: "25.02.23:", desc: "Add qt6-qtbase-sqlite to support SQLite database for resume files."} - {date: "31.01.24:", desc: "Rebase to Alpine 3.19."}
- { date: "15.01.23:", desc: "Rebase to Alpine 3.17, add openssl1.1-compat." } - {date: "25.12.23:", desc: "Only pull stable releases of qbittorrent-cli."}
- { date: "29.11.22:", desc: "Add icu-libs to support qbittorrent-cli." } - {date: "07.10.23:", desc: "Install unrar from [linuxserver repo](https://github.com/linuxserver/docker-unrar)."}
- { date: "30.10.22:", desc: "Add libtorrent v1 branch." } - {date: "10.08.23:", desc: "Bump unrar to 6.2.10."}
- { date: "31.08.22:", desc: "Rebase to Alpine Edge again to follow latest releases." } - {date: "17.06.23:", desc: "Rebase to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf)."}
- { date: "12.08.22:", desc: "Bump unrar to 6.1.7." } - {date: "10.06.23:", desc: "Bump unrar to 6.2.8."}
- { date: "16.06.22:", desc: "Rebase to Alpine 3.16 from edge." } - {date: "25.02.23:", desc: "Add qt6-qtbase-sqlite to support SQLite database for resume files."}
- { date: "25.05.22:", desc: "Fetch qbitorrent-cli from upstream repo." } - {date: "15.01.23:", desc: "Rebase to Alpine 3.17, add openssl1.1-compat."}
- { date: "02.03.22:", desc: "Add unrar, 7zip, and qbitorrent-cli." } - {date: "29.11.22:", desc: "Add icu-libs to support qbittorrent-cli."}
- { date: "01.03.22:", desc: "Add python for search plugin support." } - {date: "30.10.22:", desc: "Add libtorrent v1 branch."}
- { date: "23.02.22:", desc: "Rebase to Alpine Edge, install from Alpine repos." } - {date: "31.08.22:", desc: "Rebase to Alpine Edge again to follow latest releases."}
- { date: "19.02.22:", desc: "Add jq to build-stage" } - {date: "12.08.22:", desc: "Bump unrar to 6.1.7."}
- { date: "07.01.22:", desc: "Rebase to Alpine, build from source." } - {date: "16.06.22:", desc: "Rebase to Alpine 3.16 from edge."}
- { date: "06.01.22:", desc: "Deprecate unstable branch." } - {date: "25.05.22:", desc: "Fetch qbitorrent-cli from upstream repo."}
- { date: "10.02.21:", desc: "Rebase to focal." } - {date: "02.03.22:", desc: "Add unrar, 7zip, and qbitorrent-cli."}
- { date: "20.01.21:", desc: "Deprecate `UMASK_SET` in favor of UMASK in baseimage, see above for more information." } - {date: "01.03.22:", desc: "Add python for search plugin support."}
- { date: "12.11.20:", desc: "Stop creating /config/data directory on startup" } - {date: "23.02.22:", desc: "Rebase to Alpine Edge, install from Alpine repos."}
- { date: "03.04.20:", desc: "Fix adding search engine plugin" } - {date: "19.02.22:", desc: "Add jq to build-stage"}
- { date: "02.08.19:", desc: "Add qbitorrent-cli for processing scripts." } - {date: "07.01.22:", desc: "Rebase to Alpine, build from source."}
- { date: "23.03.19:", desc: "Switching to new Base images, shift to arm32v7 tag." } - {date: "06.01.22:", desc: "Deprecate unstable branch."}
- { date: "14.01.19:", desc: "Rebase to Ubuntu, add multi arch and pipeline logic." } - {date: "10.02.21:", desc: "Rebase to focal."}
- { date: "25.09.18:", desc: "Use buildstage type build, bump qbitorrent to 4.1.3." } - {date: "20.01.21:", desc: "Deprecate `UMASK_SET` in favor of UMASK in baseimage, see above for more information."}
- { date: "14.08.18:", desc: "Rebase to alpine 3.8, bump libtorrent to 1.1.9 and qbitorrent to 4.1.2." } - {date: "12.11.20:", desc: "Stop creating /config/data directory on startup"}
- { date: "08.06.18:", desc: "Bump qbitorrent to 4.1.1." } - {date: "03.04.20:", desc: "Fix adding search engine plugin"}
- { date: "26.04.18:", desc: "Bump libtorrent to 1.1.7." } - {date: "02.08.19:", desc: "Add qbitorrent-cli for processing scripts."}
- { date: "02.03.18:", desc: "Bump qbitorrent to 4.0.4 and libtorrent to 1.1.6." } - {date: "23.03.19:", desc: "Switching to new Base images, shift to arm32v7 tag."}
- { date: "02.01.18:", desc: "Deprecate cpu_core routine lack of scaling." } - {date: "14.01.19:", desc: "Rebase to Ubuntu, add multi arch and pipeline logic."}
- { date: "19.12.17:", desc: "Update to v4.0.3." } - {date: "25.09.18:", desc: "Use buildstage type build, bump qbitorrent to 4.1.3."}
- { date: "09.02.17:", desc: "Rebase to alpine 3.7" } - {date: "14.08.18:", desc: "Rebase to alpine 3.8, bump libtorrent to 1.1.9 and qbitorrent to 4.1.2."}
- { date: "01.12.17:", desc: "Update to v4.0.2." } - {date: "08.06.18:", desc: "Bump qbitorrent to 4.1.1."}
- { date: "27.11.17:", desc: "Update to v4 and use cpu_core routine to speed up builds." } - {date: "26.04.18:", desc: "Bump libtorrent to 1.1.7."}
- { date: "16.09.17:", desc: "Bump to 3.3.16, Add WEBUI_PORT variable and notes to README to allow changing port of webui." } - {date: "02.03.18:", desc: "Bump qbitorrent to 4.0.4 and libtorrent to 1.1.6."}
- { date: "01.08.17:", desc: "Initial Release." } - {date: "02.01.18:", desc: "Deprecate cpu_core routine lack of scaling."}
- { date: "12.02.18:", desc: "Initial Release." } - {date: "19.12.17:", desc: "Update to v4.0.3."}
- {date: "09.02.17:", desc: "Rebase to alpine 3.7"}
- {date: "01.12.17:", desc: "Update to v4.0.2."}
- {date: "27.11.17:", desc: "Update to v4 and use cpu_core routine to speed up builds."}
- {date: "16.09.17:", desc: "Bump to 3.3.16, Add WEBUI_PORT variable and notes to README to allow changing port of webui."}
- {date: "01.08.17:", desc: "Initial Release."}
- {date: "12.02.18:", desc: "Initial Release."}

View File

@@ -9,13 +9,13 @@ if [[ ! -f /config/qBittorrent/qBittorrent.conf ]]; then
cp /defaults/qBittorrent.conf /config/qBittorrent/qBittorrent.conf cp /defaults/qBittorrent.conf /config/qBittorrent/qBittorrent.conf
fi fi
# chown download directory if currently not set to abc if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
if [[ -d /downloads ]]; then # chown download directory if currently not set to abc
if [[ "$(stat -c '%U' /downloads)" != "abc" ]]; then if grep -qe ' /downloads ' /proc/mounts; then
lsiown -R abc:abc /downloads lsiown abc:abc /downloads
fi fi
fi
# permissions # permissions
lsiown -R abc:abc \ lsiown -R abc:abc \
/config /config
fi

View File

@@ -2,7 +2,21 @@
# shellcheck shell=bash # shellcheck shell=bash
WEBUI_PORT=${WEBUI_PORT:-8080} WEBUI_PORT=${WEBUI_PORT:-8080}
if [[ -n "${TORRENTING_PORT}" ]]; then
TORRENTING_PORT_ARG="--torrenting-port=${TORRENTING_PORT}"
fi
exec \ WEBUI_ADDRESS=$(grep -Po "^WebUI\\\Address=\K(.*)" /config/qBittorrent/qBittorrent.conf)
s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ if [[ -z ${WEBUI_ADDRESS} ]] || [[ ${WEBUI_ADDRESS} == "*" ]]; then
s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" WEBUI_ADDRESS="localhost"
fi
if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
exec \
s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z ${WEBUI_ADDRESS} ${WEBUI_PORT}" \
s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" ${TORRENTING_PORT_ARG}
else
exec \
s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z ${WEBUI_ADDRESS} ${WEBUI_PORT}" \
/app/qbittorrent-nox --webui-port="${WEBUI_PORT}" ${TORRENTING_PORT_ARG}
fi

View File

@@ -1,4 +1,5 @@
#!/usr/bin/with-contenv bash #!/usr/bin/with-contenv bash
# shellcheck shell=bash
# qbt bash wrapper to prompt user when trying to save password # qbt bash wrapper to prompt user when trying to save password
if [[ "$@" == "settings set password" ]]; then if [[ "$@" == "settings set password" ]]; then