From bf4041a43e4f7517830f3de24ee29f12374d293b Mon Sep 17 00:00:00 2001 From: thespad Date: Thu, 29 Aug 2024 17:05:54 +0100 Subject: [PATCH 1/7] Rebase to noble, add encryption support --- Dockerfile | 19 +++++++----- Dockerfile.aarch64 | 19 +++++++----- Jenkinsfile | 10 +++---- README.md | 16 ++++++---- jenkins-vars.yml | 5 ++-- readme-vars.yml | 18 ++++++------ .../s6-rc.d/init-duplicati-config/run | 29 ++++++++++++++++++- root/etc/s6-overlay/s6-rc.d/svc-duplicati/run | 3 +- 8 files changed, 78 insertions(+), 41 deletions(-) diff --git a/Dockerfile b/Dockerfile index 23f0275..a95d289 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/linuxserver/baseimage-ubuntu:jammy +FROM ghcr.io/linuxserver/baseimage-ubuntu:noble # set version label ARG BUILD_DATE @@ -10,18 +10,20 @@ LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DA LABEL maintainer="aptalca" # environment settings -ENV HOME="/config" -ENV DEBIAN_FRONTEND="noninteractive" +ARG DEBIAN_FRONTEND="noninteractive" +ENV HOME="/config" \ + TMPDIR=/run/duplicati-temp \ + DUPLICATI__REQUIRE_DB_ENCRYPTION_KEY=true \ + DUPLICATI__SERVER_DATAFOLDER=/config \ + DUPLICATI__WEBSERVICE_PORT=8200 \ + DUPLICATI__WEBSERVICE_INTERFACE=any \ + DUPLICATI__WEBSERVICE_ALLOWED_HOSTNAMES=* RUN \ - echo "**** add mono repository ****" && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \ - echo "deb http://download.mono-project.com/repo/ubuntu stable-focal main" | tee /etc/apt/sources.list.d/mono-official.list && \ echo "**** install packages ****" && \ apt-get update && \ apt-get install -y \ - mono-devel \ - mono-vbnc \ + libicu74 \ unzip && \ echo "**** install duplicati ****" && \ if [ -z ${DUPLICATI_RELEASE+x} ]; then \ @@ -35,6 +37,7 @@ RUN \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ apt-get clean && \ rm -rf \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 449cdfe..f5518c2 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/linuxserver/baseimage-ubuntu:arm64v8-jammy +FROM ghcr.io/linuxserver/baseimage-ubuntu:arm64v8-noble # set version label ARG BUILD_DATE @@ -10,18 +10,20 @@ LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DA LABEL maintainer="aptalca" # environment settings -ENV HOME="/config" -ENV DEBIAN_FRONTEND="noninteractive" +ARG DEBIAN_FRONTEND="noninteractive" +ENV HOME="/config" \ + TMPDIR=/run/duplicati-temp \ + DUPLICATI__REQUIRE_DB_ENCRYPTION_KEY=true \ + DUPLICATI__SERVER_DATAFOLDER=/config \ + DUPLICATI__WEBSERVICE_PORT=8200 \ + DUPLICATI__WEBSERVICE_INTERFACE=any \ + DUPLICATI__WEBSERVICE_ALLOWED_HOSTNAMES=* RUN \ - echo "**** add mono repository ****" && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \ - echo "deb http://download.mono-project.com/repo/ubuntu stable-focal main" | tee /etc/apt/sources.list.d/mono-official.list && \ echo "**** install pockages ****" && \ apt-get update && \ apt-get install -y \ - mono-devel \ - mono-vbnc \ + libicu74 \ unzip && \ echo "**** install duplicati ****" && \ if [ -z ${DUPLICATI_RELEASE+x} ]; then \ @@ -35,6 +37,7 @@ RUN \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ apt-get clean && \ rm -rf \ diff --git a/Jenkinsfile b/Jenkinsfile index 3e9187e..4654b57 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -35,8 +35,8 @@ pipeline { CI_PORT='8200' CI_SSL='false' CI_DELAY='120' - CI_DOCKERENV='TZ=US/Pacific|ISCI=true' - CI_AUTH='user:password' + CI_DOCKERENV='SETTINGS_ENCRYPTION_KEY=abcde12345' + CI_AUTH='' CI_WEBPATH='' } stages { @@ -543,7 +543,7 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Duplicati\" \ - --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon Cloud Drive & S3, Google Drive, box.com, Mega, hubiC and many others.\" \ + --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) is a backup client that securely stores encrypted, incremental, compressed backups on local storage, cloud storage services and remote file servers. It works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon S3, Google Drive, box.com, Mega, B2, and many others.\" \ --no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \ --provenance=false --sbom=false \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." @@ -575,7 +575,7 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Duplicati\" \ - --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon Cloud Drive & S3, Google Drive, box.com, Mega, hubiC and many others.\" \ + --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) is a backup client that securely stores encrypted, incremental, compressed backups on local storage, cloud storage services and remote file servers. It works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon S3, Google Drive, box.com, Mega, B2, and many others.\" \ --no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \ --provenance=false --sbom=false \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." @@ -604,7 +604,7 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Duplicati\" \ - --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon Cloud Drive & S3, Google Drive, box.com, Mega, hubiC and many others.\" \ + --label \"org.opencontainers.image.description=[Duplicati](https://www.duplicati.com/) is a backup client that securely stores encrypted, incremental, compressed backups on local storage, cloud storage services and remote file servers. It works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon S3, Google Drive, box.com, Mega, B2, and many others.\" \ --no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \ --provenance=false --sbom=false \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." diff --git a/README.md b/README.md index b6a0acc..d91dacc 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Find us at: [![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-duplicati%2Fjob%2Fmaster%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-duplicati/job/master/) [![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%2Fduplicati%2Flatest%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/duplicati/latest/index.html) -[Duplicati](https://www.duplicati.com/) works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon Cloud Drive & S3, Google Drive, box.com, Mega, hubiC and many others. +[Duplicati](https://www.duplicati.com/) is a backup client that securely stores encrypted, incremental, compressed backups on local storage, cloud storage services and remote file servers. It works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon S3, Google Drive, box.com, Mega, B2, and many others. [![duplicati](https://github.com/linuxserver/docker-templates/raw/master/linuxserver.io/img/duplicati-icon.png)](https://www.duplicati.com/) @@ -68,7 +68,9 @@ This image provides various versions that are available via tags. Please read th ## Application Setup -The webui is at `:8200` , create backup jobs etc via the webui, for local backups select `/backups` as the destination. For more information see [Duplicati](https://www.duplicati.com/). +The webui is at `:8200`. + +For local backups select `/backups` as the destination. For more information see [Duplicati](https://www.duplicati.com/). ## Usage @@ -86,9 +88,10 @@ services: - PUID=1000 - PGID=1000 - TZ=Etc/UTC + - SETTINGS_ENCRYPTION_KEY= - CLI_ARGS= #optional volumes: - - /path/to/appdata/config:/config + - /path/to/duplicati/config:/config - /path/to/backups:/backups - /path/to/source:/source ports: @@ -104,9 +107,10 @@ docker run -d \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Etc/UTC \ + -e SETTINGS_ENCRYPTION_KEY= \ -e CLI_ARGS= `#optional` \ -p 8200:8200 \ - -v /path/to/appdata/config:/config \ + -v /path/to/duplicati/config:/config \ -v /path/to/backups:/backups \ -v /path/to/source:/source \ --restart unless-stopped \ @@ -123,6 +127,7 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e PUID=1000` | for UserID - see below for explanation | | `-e PGID=1000` | for GroupID - see below for explanation | | `-e TZ=Etc/UTC` | specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List). | +| `-e SETTINGS_ENCRYPTION_KEY=` | Encryption key for settings database. Minimum 8 characters, alphanumeric. | | `-e CLI_ARGS=` | Optionally specify any [CLI variables](https://duplicati.readthedocs.io/en/latest/07-other-command-line-utilities/) you want to launch the app with | | `-v /config` | Contains all relevant configuration files. | | `-v /backups` | Path to store local backups. | @@ -289,7 +294,8 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions -* **15.02.23:** - Deprecate armhf. +* **29.08.24:** - Rebase to Noble, add support for settings DB encryption. +* **15.02.23:** - Rebase to Jammy. * **03.08.22:** - Deprecate armhf. * **25.04.22:** - Rebase to mono:focal. * **01.08.19:** - Rebase to Linuxserver LTS mono version. diff --git a/jenkins-vars.yml b/jenkins-vars.yml index a68c733..70e510d 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -6,7 +6,6 @@ external_type: custom_json release_type: stable release_tag: latest ls_branch: master -build_armhf: false repo_vars: - JSON_URL = 'https://api.github.com/repos/duplicati/duplicati/releases' - JSON_PATH = 'first(.[] | select(.tag_name | contains("beta"))) | .tag_name' @@ -24,6 +23,6 @@ repo_vars: - CI_PORT='8200' - CI_SSL='false' - CI_DELAY='120' - - CI_DOCKERENV='TZ=US/Pacific|ISCI=true' - - CI_AUTH='user:password' + - CI_DOCKERENV='SETTINGS_ENCRYPTION_KEY=abcde12345' + - CI_AUTH='' - CI_WEBPATH='' diff --git a/readme-vars.yml b/readme-vars.yml index 25b4e50..a6971fa 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -4,7 +4,7 @@ project_name: duplicati project_url: "https://www.duplicati.com/" project_logo: "https://github.com/linuxserver/docker-templates/raw/master/linuxserver.io/img/duplicati-icon.png" -project_blurb: "[{{ project_name|capitalize }}]({{ project_url }}) works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon Cloud Drive & S3, Google Drive, box.com, Mega, hubiC and many others." +project_blurb: "[{{ project_name|capitalize }}]({{ project_url }}) is a backup client that securely stores encrypted, incremental, compressed backups on local storage, cloud storage services and remote file servers. It works with standard protocols like FTP, SSH, WebDAV as well as popular services like Microsoft OneDrive, Amazon S3, Google Drive, box.com, Mega, B2, and many others." project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}" # supported architectures @@ -23,33 +23,33 @@ common_param_env_vars_enabled: true param_container_name: "{{ project_name }}" param_usage_include_vols: true 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 }}/config", desc: "Contains all relevant configuration files." } - { vol_path: "/backups", vol_host_path: "/path/to/backups", desc: "Path to store local backups." } - { vol_path: "/source", vol_host_path: "/path/to/source", desc: "Path to source for files to backup." } param_usage_include_ports: true param_ports: - { external_port: "8200", internal_port: "8200", port_desc: "http gui" } + param_usage_include_env: true param_env_vars: - - { env_var: "TZ", env_value: "Europe/London", desc: "Specify a timezone to use EG Europe/London"} + - { env_var: "SETTINGS_ENCRYPTION_KEY", env_value: "", desc: "Encryption key for settings database. Minimum 8 characters, alphanumeric."} # optional container parameters opt_param_usage_include_env: true opt_param_env_vars: - { env_var: "CLI_ARGS", env_value: "", desc: "Optionally specify any [CLI variables](https://duplicati.readthedocs.io/en/latest/07-other-command-line-utilities/) you want to launch the app with" } -# optional parameters -optional_block_1: false -optional_block_1_items: "" - # application setup block app_setup_block_enabled: true app_setup_block: | - The webui is at `:8200` , create backup jobs etc via the webui, for local backups select `/backups` as the destination. For more information see [Duplicati]({{project_url}}). + The webui is at `:8200`. + + For local backups select `/backups` as the destination. For more information see [Duplicati]({{project_url}}). # changelog changelogs: - - { date: "15.02.23:", desc: "Deprecate armhf." } + - { date: "29.08.24:", desc: "Rebase to Noble, add support for settings DB encryption." } + - { date: "15.02.23:", desc: "Rebase to Jammy." } - { date: "03.08.22:", desc: "Deprecate armhf." } - { date: "25.04.22:", desc: "Rebase to mono:focal." } - { date: "01.08.19:", desc: "Rebase to Linuxserver LTS mono version." } diff --git a/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run b/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run index efea851..0c8482d 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run @@ -1,6 +1,33 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash +mkdir -p /run/duplicati-temp + +if [[ -f "/config/Duplicati-server.sqlite" ]]; then + # Existing install + if [[ -n ${SETTINGS_ENCRYPTION_KEY} ]]; then + # Enable settings encryption + true + else + # Disable settings encryption + printf "true" > /run/s6/container_environment/DUPLICATI__DISABLE_DB_ENCRYPTION + echo "*** Missing encryption key, unable to encrypt your settings database ***" + echo "*** Please set a value for SETTINGS_ENCRYPTION_KEY and recreate the container ***" + fi +else + # New install + if [[ -n ${SETTINGS_ENCRYPTION_KEY} ]]; then + # Enable settings encryption + true + else + # Halt init + echo "*** Missing encryption key, unable to encrypt your settings database ***" + echo "*** Please set a value for SETTINGS_ENCRYPTION_KEY and recreate the container ***" + sleep infinity + fi +fi + # permissions lsiown -R abc:abc \ - /config + /config \ + /run/duplicati-temp diff --git a/root/etc/s6-overlay/s6-rc.d/svc-duplicati/run b/root/etc/s6-overlay/s6-rc.d/svc-duplicati/run index 23ca6b4..c423daa 100755 --- a/root/etc/s6-overlay/s6-rc.d/svc-duplicati/run +++ b/root/etc/s6-overlay/s6-rc.d/svc-duplicati/run @@ -3,5 +3,4 @@ exec \ s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost 8200" \ - cd /app/duplicati s6-setuidgid abc mono Duplicati.Server.exe \ - --webservice-interface=any --server-datafolder=/config --webservice-allowed-hostnames=* $CLI_ARGS + cd /app/duplicati s6-setuidgid abc ./duplicati-server $CLI_ARGS From 788a53e65bc4eee046c0dbec4729dc0d965fb834 Mon Sep 17 00:00:00 2001 From: thespad Date: Thu, 29 Aug 2024 19:43:29 +0100 Subject: [PATCH 2/7] Set default webui password --- Jenkinsfile | 2 +- README.md | 3 +++ jenkins-vars.yml | 2 +- readme-vars.yml | 1 + root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run | 3 +++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4654b57..7734ea5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -37,7 +37,7 @@ pipeline { CI_DELAY='120' CI_DOCKERENV='SETTINGS_ENCRYPTION_KEY=abcde12345' CI_AUTH='' - CI_WEBPATH='' + CI_WEBPATH='/login.html' } stages { stage("Set git config"){ diff --git a/README.md b/README.md index d91dacc..257ae0a 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ services: - TZ=Etc/UTC - SETTINGS_ENCRYPTION_KEY= - CLI_ARGS= #optional + - DUPLICATI__WEBSERVICE_PASSWORD= #optional volumes: - /path/to/duplicati/config:/config - /path/to/backups:/backups @@ -109,6 +110,7 @@ docker run -d \ -e TZ=Etc/UTC \ -e SETTINGS_ENCRYPTION_KEY= \ -e CLI_ARGS= `#optional` \ + -e DUPLICATI__WEBSERVICE_PASSWORD= `#optional` \ -p 8200:8200 \ -v /path/to/duplicati/config:/config \ -v /path/to/backups:/backups \ @@ -129,6 +131,7 @@ Containers are configured using parameters passed at runtime (such as those abov | `-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 SETTINGS_ENCRYPTION_KEY=` | Encryption key for settings database. Minimum 8 characters, alphanumeric. | | `-e CLI_ARGS=` | Optionally specify any [CLI variables](https://duplicati.readthedocs.io/en/latest/07-other-command-line-utilities/) you want to launch the app with | +| `-e DUPLICATI__WEBSERVICE_PASSWORD=` | Password for the webui. If left unset will default to `changeme` and can be changed from the webui settings. | | `-v /config` | Contains all relevant configuration files. | | `-v /backups` | Path to store local backups. | | `-v /source` | Path to source for files to backup. | diff --git a/jenkins-vars.yml b/jenkins-vars.yml index 70e510d..55fb411 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -25,4 +25,4 @@ repo_vars: - CI_DELAY='120' - CI_DOCKERENV='SETTINGS_ENCRYPTION_KEY=abcde12345' - CI_AUTH='' - - CI_WEBPATH='' + - CI_WEBPATH='/login.html' diff --git a/readme-vars.yml b/readme-vars.yml index a6971fa..2e9f122 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -38,6 +38,7 @@ param_env_vars: opt_param_usage_include_env: true opt_param_env_vars: - { env_var: "CLI_ARGS", env_value: "", desc: "Optionally specify any [CLI variables](https://duplicati.readthedocs.io/en/latest/07-other-command-line-utilities/) you want to launch the app with" } + - { env_var: "DUPLICATI__WEBSERVICE_PASSWORD", env_value: "", desc: "Password for the webui. If left unset will default to `changeme` and can be changed from the webui settings."} # application setup block app_setup_block_enabled: true diff --git a/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run b/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run index 0c8482d..e250138 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-duplicati-config/run @@ -16,6 +16,9 @@ if [[ -f "/config/Duplicati-server.sqlite" ]]; then fi else # New install + if [[ -z ${DUPLICATI__WEBSERVICE_PASSWORD} ]]; then + printf "changeme" > /run/s6/container_environment/DUPLICATI__WEBSERVICE_PASSWORD + fi if [[ -n ${SETTINGS_ENCRYPTION_KEY} ]]; then # Enable settings encryption true From a2c5187f22aac02b543f04638c94dda83b7bf098 Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 29 Nov 2024 15:46:22 +0000 Subject: [PATCH 3/7] Update for release --- .github/CONTRIBUTING.md | 4 +- .github/workflows/external_trigger.yml | 64 +++++++++++------- .../workflows/package_trigger_scheduler.yml | 65 ++++++++++++++----- Dockerfile | 2 +- Jenkinsfile | 62 ++++++++++++++---- README.md | 10 +-- readme-vars.yml | 2 +- 7 files changed, 148 insertions(+), 61 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 05f0ae5..ac0a4db 100755 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -105,10 +105,10 @@ docker build \ -t linuxserver/duplicati:latest . ``` -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static` ```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset +docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset ``` Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index 56a7501..6736a8c 100755 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -11,15 +11,17 @@ jobs: - name: External Trigger if: github.ref == 'refs/heads/master' + env: + SKIP_EXTERNAL_TRIGGER: ${{ vars.SKIP_EXTERNAL_TRIGGER }} run: | printf "# External trigger for docker-duplicati\n\n" >> $GITHUB_STEP_SUMMARY - if [ -n "${{ secrets.PAUSE_EXTERNAL_TRIGGER_DUPLICATI_MASTER }}" ]; then + if grep -q "^duplicati_master" <<< "${SKIP_EXTERNAL_TRIGGER}"; then echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY - echo "> Github secret \`PAUSE_EXTERNAL_TRIGGER_DUPLICATI_MASTER\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`duplicati_master\`; skipping trigger." >> $GITHUB_STEP_SUMMARY exit 0 fi echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY - echo "> External trigger running off of master branch. To disable this trigger, set a Github secret named \`PAUSE_EXTERNAL_TRIGGER_DUPLICATI_MASTER\`" >> $GITHUB_STEP_SUMMARY + echo "> External trigger running off of master branch. To disable this trigger, add \`duplicati_master\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY EXT_RELEASE=$(curl -u "${{ secrets.CR_USER }}:${{ secrets.CR_PAT }}" -sX GET "https://api.github.com/repos/duplicati/duplicati/releases" | jq -r '. | first(.[] | select(.tag_name | contains("beta"))) | .tag_name') echo "Type is \`custom_json\`" >> $GITHUB_STEP_SUMMARY @@ -78,26 +80,38 @@ jobs: echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY exit 0 else - printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY - echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY - response=$(curl -iX POST \ - https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-duplicati/job/master/buildWithParameters?PACKAGE_CHECK=false \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") - echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY - echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY - sleep 10 - buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') - buildurl="${buildurl%$'\r'}" - echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY - echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY - curl -iX POST \ - "${buildurl}submitDescription" \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ - --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - --data-urlencode "Submit=Submit" - echo "**** Notifying Discord ****" - TRIGGER_REASON="A version change was detected for duplicati tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ "${artifacts_found}" == "false" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> New version detected, but not all artifacts are published yet; skipping trigger" >> $GITHUB_STEP_SUMMARY + FAILURE_REASON="New version ${EXT_RELEASE} for duplicati tag latest is detected, however not all artifacts are uploaded to upstream release yet. Will try again later." + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + else + printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY + echo "New version \`${EXT_RELEASE}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY + if "${artifacts_found}" == "true" ]]; then + echo "All artifacts seem to be uploaded." >> $GITHUB_STEP_SUMMARY + fi + response=$(curl -iX POST \ + https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-duplicati/job/master/buildWithParameters?PACKAGE_CHECK=false \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY + curl -iX POST \ + "${buildurl}submitDescription" \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ + --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --data-urlencode "Submit=Submit" + echo "**** Notifying Discord ****" + TRIGGER_REASON="A version change was detected for duplicati tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi fi diff --git a/.github/workflows/package_trigger_scheduler.yml b/.github/workflows/package_trigger_scheduler.yml index e6ba09e..7085ff2 100755 --- a/.github/workflows/package_trigger_scheduler.yml +++ b/.github/workflows/package_trigger_scheduler.yml @@ -14,6 +14,8 @@ jobs: fetch-depth: '0' - name: Package Trigger Scheduler + env: + SKIP_PACKAGE_TRIGGER: ${{ vars.SKIP_PACKAGE_TRIGGER }} run: | printf "# Package trigger scheduler for docker-duplicati\n\n" >> $GITHUB_STEP_SUMMARY printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY @@ -24,27 +26,58 @@ jobs: continue fi printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY - ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-duplicati/${br}/jenkins-vars.yml | yq -r '.ls_branch') - if [ "${br}" == "${ls_branch}" ]; then + JENKINS_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-duplicati/${br}/jenkins-vars.yml) + if [[ "${br}" == $(yq -r '.ls_branch' <<< "${JENKINS_VARS}") ]]; then echo "Branch appears to be live; checking workflow." >> $GITHUB_STEP_SUMMARY - if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-duplicati/${br}/.github/workflows/package_trigger.yml > /dev/null 2>&1; then - echo "Triggering package trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY + if [[ $(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 "^duplicati_${br}" <<< "${SKIP_PACKAGE_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_PACKAGE_TRIGGER\` contains \`duplicati_${br}\`; skipping trigger." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-duplicati/job/${br}/lastBuild/api/json | jq -r '.building') == "true" ]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> There already seems to be an active build on Jenkins; skipping package trigger for ${br}" >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + else + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> Triggering package trigger for branch ${br}" >> $GITHUB_STEP_SUMMARY + printf "> To disable, add \`duplicati_%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-duplicati/job/${br}/buildWithParameters?PACKAGE_CHECK=true \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY curl -iX POST \ - -H "Authorization: token ${{ secrets.CR_PAT }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -d "{\"ref\":\"refs/heads/${br}\"}" \ - https://api.github.com/repos/linuxserver/docker-duplicati/actions/workflows/package_trigger.yml/dispatches - sleep 30 - else - echo "Skipping branch ${br} due to no package trigger workflow present." >> $GITHUB_STEP_SUMMARY + "${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" + sleep 20 fi else echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY fi done - echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" - echo "**** Notifying Discord ****" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Package Check Build(s) Triggered for duplicati** \n**Branch(es):** '"${triggered_branches}"' \n**Build URL:** '"https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-duplicati/activity/"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ -n "${triggered_branches}" ]] || [[ -n "${skipped_branches}" ]]; then + if [[ -n "${triggered_branches}" ]]; then + NOTIFY_BRANCHES="**Triggered:** ${triggered_branches} \n" + NOTIFY_BUILD_URL="**Build URL:** https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-duplicati/activity/ \n" + echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" + fi + if [[ -n "${skipped_branches}" ]]; then + NOTIFY_BRANCHES="${NOTIFY_BRANCHES}**Skipped:** ${skipped_branches} \n" + fi + echo "**** Notifying Discord ****" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Package Check Build(s) for duplicati** \n'"${NOTIFY_BRANCHES}"''"${NOTIFY_BUILD_URL}"'"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi diff --git a/Dockerfile b/Dockerfile index a95d289..1f9c652 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN \ fi && \ mkdir -p \ /app/duplicati && \ - duplicati_url=$(curl -s https://api.github.com/repos/duplicati/duplicati/releases/tags/"${DUPLICATI_RELEASE}" |jq -r '.assets[].browser_download_url' |grep '.zip$' |grep -v signatures) && \ + duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" |jq -r '.assets[].browser_download_url' |grep 'linux-x64-gui.zip$') && \ curl -o \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ diff --git a/Jenkinsfile b/Jenkinsfile index 7734ea5..b9fb864 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -83,7 +83,7 @@ pipeline { env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/' env.PULL_REQUEST = env.CHANGE_ID - env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml ./.github/workflows/package_trigger.yml' + 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 echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" ''' @@ -313,7 +313,7 @@ pipeline { echo "Jenkinsfile is up to date." fi echo "Starting Stage 2 - Delete old templates" - OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml" + OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml .github/workflows/package_trigger.yml" for i in ${OLD_TEMPLATES}; do if [[ -f "${i}" ]]; then TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}" @@ -721,6 +721,14 @@ pipeline { } sh '''#! /bin/bash set -e + if grep -q 'docker-baseimage' <<< "${LS_REPO}"; then + echo "Detected baseimage, setting LSIO_FIRST_PARTY=true" + if [ -n "${CI_DOCKERENV}" ]; then + CI_DOCKERENV="LSIO_FIRST_PARTY=true|${CI_DOCKERENV}" + else + CI_DOCKERENV="LSIO_FIRST_PARTY=true" + fi + fi docker pull ghcr.io/linuxserver/ci:latest if [ "${MULTIARCH}" == "true" ]; then docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64 @@ -733,6 +741,7 @@ pipeline { -e DOCKER_LOGS_TIMEOUT=\"${CI_DELAY}\" \ -e TAGS=\"${CI_TAGS}\" \ -e META_TAG=\"${META_TAG}\" \ + -e RELEASE_TAG=\"latest\" \ -e PORT=\"${CI_PORT}\" \ -e SSL=\"${CI_SSL}\" \ -e BASE=\"${DIST_IMAGE}\" \ @@ -742,6 +751,7 @@ pipeline { -e WEB_SCREENSHOT=\"${CI_WEB}\" \ -e WEB_AUTH=\"${CI_AUTH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \ + -e NODE_NAME=\"${NODE_NAME}\" \ -t ghcr.io/linuxserver/ci:latest \ python3 test_build.py''' } @@ -876,7 +886,7 @@ pipeline { echo '{"tag_name":"'${META_TAG}'",\ "target_commitish": "master",\ "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": false}' >> releasebody.json paste -d'\\0' start releasebody.json > releasebody.json.done curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done''' @@ -1009,17 +1019,45 @@ EOF git config --global --unset commit.gpgsign ''' script{ + env.JOB_DATE = sh( + script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''', + returnStdout: true).trim() if (env.EXIT_STATUS == "ABORTED"){ sh 'echo "build aborted"' - } - else if (currentBuild.currentResult == "SUCCESS"){ - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 1681177,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** Success\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ - "username": "Jenkins"}' ${BUILDS_DISCORD} ''' - } - else { - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 16711680,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** failure\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ + }else{ + if (currentBuild.currentResult == "SUCCESS"){ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=1681177 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + }else{ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=16711680 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + } + sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"'color'": '${JOB_WEBHOOK_COLOUR}',\ + "footer": {"text" : "'"${JOB_WEBHOOK_FOOTER}"'"},\ + "timestamp": "'${JOB_DATE}'",\ + "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** '${JOB_WEBHOOK_STATUS}'\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ "username": "Jenkins"}' ${BUILDS_DISCORD} ''' } } diff --git a/README.md b/README.md index 257ae0a..0f3c8e4 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ The webui is at `:8200`. For local backups select `/backups` as the destination. For more information see [Duplicati](https://www.duplicati.com/). + ## Usage To help you get started creating a container from this image you can either use docker-compose or the docker cli. @@ -272,7 +273,8 @@ Below are the instructions for updating containers: ### Image Update Notifications - Diun (Docker Image Update Notifier) -**tip**: We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. +>[!TIP] +>We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. ## Building locally @@ -287,17 +289,17 @@ docker build \ -t lscr.io/linuxserver/duplicati:latest . ``` -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static` ```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset +docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset ``` Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. ## Versions -* **29.08.24:** - Rebase to Noble, add support for settings DB encryption. +* **29.11.24:** - Rebase to Noble, add support for settings DB encryption. * **15.02.23:** - Rebase to Jammy. * **03.08.22:** - Deprecate armhf. * **25.04.22:** - Rebase to mono:focal. diff --git a/readme-vars.yml b/readme-vars.yml index 2e9f122..bdd5916 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -49,7 +49,7 @@ app_setup_block: | # changelog changelogs: - - { date: "29.08.24:", desc: "Rebase to Noble, add support for settings DB encryption." } + - { date: "29.11.24:", desc: "Rebase to Noble, add support for settings DB encryption." } - { date: "15.02.23:", desc: "Rebase to Jammy." } - { date: "03.08.22:", desc: "Deprecate armhf." } - { date: "25.04.22:", desc: "Rebase to mono:focal." } From 10dc52dce91d8e33f3b1498cb2eeef2649740db7 Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 29 Nov 2024 15:52:44 +0000 Subject: [PATCH 4/7] There is also an arm dockerfile... --- Dockerfile | 2 +- Dockerfile.aarch64 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1f9c652..554e51e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN \ fi && \ mkdir -p \ /app/duplicati && \ - duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" |jq -r '.assets[].browser_download_url' |grep 'linux-x64-gui.zip$') && \ + duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" | jq -r '.assets[].browser_download_url' |grep 'linux-x64-gui.zip$') && \ curl -o \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index f5518c2..8e4eedc 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -32,7 +32,7 @@ RUN \ fi && \ mkdir -p \ /app/duplicati && \ - duplicati_url=$(curl -s https://api.github.com/repos/duplicati/duplicati/releases/tags/"${DUPLICATI_RELEASE}" |jq -r '.assets[].browser_download_url' |grep '.zip$' |grep -v signatures) && \ + duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" | jq -r '.assets[].browser_download_url' |grep 'linux-arm64-gui.zip$') && \ curl -o \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ From 1f457ff311ab077654b107656352913b90a352e0 Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 29 Nov 2024 16:01:47 +0000 Subject: [PATCH 5/7] Move after unzip --- Dockerfile | 1 + Dockerfile.aarch64 | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 554e51e..df6646f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,6 +37,7 @@ RUN \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + mv /app/duplicati* /app/duplicati && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ apt-get clean && \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 8e4eedc..af28b00 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -37,6 +37,7 @@ RUN \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + mv /app/duplicati* /app/duplicati && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ apt-get clean && \ From 77d313201423086419d91e995844b2d5d9e443bd Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 29 Nov 2024 16:05:32 +0000 Subject: [PATCH 6/7] Unzip to correct folder --- Dockerfile | 2 +- Dockerfile.aarch64 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index df6646f..54a84fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN \ curl -o \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ - unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + unzip -q /tmp/duplicati.zip -d /app && \ mv /app/duplicati* /app/duplicati && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index af28b00..1a97735 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -36,7 +36,7 @@ RUN \ curl -o \ /tmp/duplicati.zip -L \ "${duplicati_url}" && \ - unzip -q /tmp/duplicati.zip -d /app/duplicati && \ + unzip -q /tmp/duplicati.zip -d /app && \ mv /app/duplicati* /app/duplicati && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ echo "**** cleanup ****" && \ From 6394d6112639f012c1cd520257861778157e6012 Mon Sep 17 00:00:00 2001 From: thespad Date: Fri, 29 Nov 2024 16:09:55 +0000 Subject: [PATCH 7/7] Remove mkdir --- Dockerfile | 2 -- Dockerfile.aarch64 | 2 -- 2 files changed, 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 54a84fd..617bfb0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,8 +30,6 @@ RUN \ DUPLICATI_RELEASE=$(curl -sX GET "https://api.github.com/repos/duplicati/duplicati/releases" \ | jq -r 'first(.[] | select(.tag_name | contains("beta"))) | .tag_name'); \ fi && \ - mkdir -p \ - /app/duplicati && \ duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" | jq -r '.assets[].browser_download_url' |grep 'linux-x64-gui.zip$') && \ curl -o \ /tmp/duplicati.zip -L \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 1a97735..c062455 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -30,8 +30,6 @@ RUN \ DUPLICATI_RELEASE=$(curl -sX GET "https://api.github.com/repos/duplicati/duplicati/releases" \ | jq -r 'first(.[] | select(.tag_name | contains("beta"))) | .tag_name'); \ fi && \ - mkdir -p \ - /app/duplicati && \ duplicati_url=$(curl -s "https://api.github.com/repos/duplicati/duplicati/releases/tags/${DUPLICATI_RELEASE}" | jq -r '.assets[].browser_download_url' |grep 'linux-arm64-gui.zip$') && \ curl -o \ /tmp/duplicati.zip -L \