diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 169e12a26..e628e6177 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,15 +20,28 @@ jobs: build-synology: uses: ./.github/workflows/synology.yml + build-qnap: + uses: ./.github/workflows/qnap.yml + + repack-qnap: + uses: ./.github/workflows/qnap-repack.yml + with: + external_call: true + needs: [build-linux] + permissions: + actions: write + generate-signatures: env: PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} runs-on: ubuntu-latest - needs: [build-windows, build-linux, build-osx, build-synology] + needs: [build-windows, build-linux, build-osx, build-synology, build-qnap, repack-qnap] + permissions: + actions: write steps: - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Generate signatures run: | @@ -37,6 +50,8 @@ jobs: mv nzbget-linux-installers/* builds || true mv nzbget-osx-installers/* builds || true mv nzbget-synology-packages/* builds || true + mv nzbget-qnap-packages/* builds || true + mv nzbget-qnap-native-packages/* builds || true cd builds VERSION=$(ls | grep bin-windows-setup | cut -d - -f 2) if [ "$GITHUB_REF_NAME" != "main" ]; then VERSION="$VERSION-testing"; fi @@ -48,7 +63,7 @@ jobs: echo "nzbget_signatures({" | tee $SIGS_FILE echo | tee -a $SIGS_FILE - for FILE in *.exe *.run *.zip *.spk; do + for FILE in *.exe *.run *.zip *.spk *.qpkg; do [ -f $FILE ] || continue MD5=$(openssl dgst -md5 $FILE | cut -d ' ' -f 2) @@ -71,20 +86,22 @@ jobs: echo "Done." - name: Upload build artifacts with signatures - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nzbget-installers path: builds/* retention-days: 5 - name: Delete unneded platform-specific artifacts - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v4 with: name: | nzbget-windows-installers nzbget-linux-installers nzbget-osx-installers nzbget-synology-packages + nzbget-qnap-packages + nzbget-qnap-native-packages make-testing-release: runs-on: [self-hosted, linux] @@ -103,7 +120,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Create latest artifacts run: | diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index be26f7f3a..9e618da22 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -43,7 +43,7 @@ jobs: done - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nzbget-linux-installers path: /build/output/*.run diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml index f67f394c7..f4f1c4909 100644 --- a/.github/workflows/osx.yml +++ b/.github/workflows/osx.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -39,7 +39,7 @@ jobs: done - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nzbget-osx-installers path: osx/build/Release/*.zip diff --git a/.github/workflows/qnap-repack.yml b/.github/workflows/qnap-repack.yml new file mode 100644 index 000000000..a628e9fd2 --- /dev/null +++ b/.github/workflows/qnap-repack.yml @@ -0,0 +1,64 @@ +name: qnap repack + +on: + workflow_call: + inputs: + external_call: + description: 'To distinguish workflow_call from regular push / workflow_dispatch' + type: boolean + required: false + default: false + workflow_dispatch: + +jobs: + build-linux: + uses: ./.github/workflows/linux.yml + if: ${{ inputs.external_call == false }} + + repack: + runs-on: [self-hosted, linux] + needs: [build-linux] + if: always() + permissions: + actions: write + + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + + - name: Repack linux installer for QNAP + run: | + export PATH="$PATH:/usr/share/QDK/bin" + bash qnap/repack-nzbget.sh + + - name: Rename build artifacts + if: github.ref_name != 'main' + run: | + VERSION=$(cat configure.ac | grep AC_INIT | cut -d , -f 2 | xargs) + NEW_VERSION="$VERSION-testing-$(date '+%Y%m%d')" + cd /qnap/nzbget/build/ + for FILE in *.qpkg; do + [ -f $FILE ] || continue + NEW_FILE=${FILE/$VERSION/$NEW_VERSION} + sudo mv $FILE $NEW_FILE + done + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: nzbget-qnap-packages + path: /qnap/nzbget/build/*.qpkg + retention-days: 5 + + - name: Delete unneded linux artifacts + if: ${{ inputs.external_call == false }} + uses: geekyeggo/delete-artifact@v4 + with: + name: | + nzbget-linux-installers diff --git a/.github/workflows/qnap.yml b/.github/workflows/qnap.yml new file mode 100644 index 000000000..896794598 --- /dev/null +++ b/.github/workflows/qnap.yml @@ -0,0 +1,49 @@ +name: qnap build + +on: + workflow_call: + workflow_dispatch: + +jobs: + build: + runs-on: [self-hosted, linux] + + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Save version for non-release to env + if: github.ref_name != 'main' + run: | + VERSION=$(cat configure.ac | grep AC_INIT | cut -d , -f 2 | xargs) + echo VERSION=$VERSION >> $GITHUB_ENV + + - name: Build + run: | + export PATH="$PATH:/usr/share/QDK/bin" + bash qnap/build-nzbget.sh + + - name: Rename build artifacts + if: github.ref_name != 'main' + run: | + cd /qnap/nzbget/build/ + NEW_VERSION="$VERSION-testing-$(date '+%Y%m%d')" + for FILE in *.qpkg; do + [ -f $FILE ] || continue + NEW_FILE=${FILE/$VERSION/$NEW_VERSION} + sudo mv $FILE $NEW_FILE + done + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: nzbget-qnap-native-packages + path: /qnap/nzbget/build/*.qpkg + retention-days: 5 + + - name: Cleanup + run: | + rm -rf /qnap/nzbget/ diff --git a/.github/workflows/synology.yml b/.github/workflows/synology.yml index 70be5cb7f..78b98b08e 100644 --- a/.github/workflows/synology.yml +++ b/.github/workflows/synology.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -32,7 +32,7 @@ jobs: done - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nzbget-synology-packages path: /toolkit/result_spk/nzbget/*.spk diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index 60f5e6159..a449de7ed 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -24,7 +24,7 @@ jobs: "C:\Program Files\CMake\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build run: | @@ -40,7 +40,7 @@ jobs: ctest -C Release - name: Upload test artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: nzbget-windows-test-log diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 690836d31..97b91e6d9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Change version for non-release if: github.ref_name != 'main' @@ -38,7 +38,7 @@ jobs: } - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nzbget-windows-installers path: C:\nzbget\build\output\*.exe diff --git a/README.md b/README.md index 956ba114b..8f1bd7a9c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [![osx build](https://github.com/nzbgetcom/nzbget/actions/workflows/osx.yml/badge.svg)](https://github.com/nzbgetcom/nzbget/actions/workflows/osx.yml) [![docker build](https://github.com/nzbgetcom/nzbget/actions/workflows/docker.yml/badge.svg)](https://github.com/nzbgetcom/nzbget/actions/workflows/docker.yml) [![synology build](https://github.com/nzbgetcom/nzbget/actions/workflows/synology.yml/badge.svg)](https://github.com/nzbgetcom/nzbget/actions/workflows/synology.yml) +[![qnap build](https://github.com/nzbgetcom/nzbget/actions/workflows/qnap.yml/badge.svg)](https://github.com/nzbgetcom/nzbget/actions/workflows/qnap.yml) ![Contributions welcome](https://img.shields.io/badge/contributions-welcome-blue.svg) @@ -38,6 +39,8 @@ We also provide a docker image for popular architectures. [Docker readme](docker Synology packages are available as SynoCommunity packages and SPK packages. [Synology readme](synology/README.md) +QNAP packages are available as native packages and buildroot packages. [QNAP readme](qnap/README.md) + ## Migration from older NZBGet versions [Migrating from NZBGet v21 or older](https://github.com/nzbgetcom/nzbget/discussions/100#discussioncomment-8080102) diff --git a/daemon/extension/ExtensionManager.cpp b/daemon/extension/ExtensionManager.cpp index 21d01cf00..1fe0cad54 100644 --- a/daemon/extension/ExtensionManager.cpp +++ b/daemon/extension/ExtensionManager.cpp @@ -189,8 +189,8 @@ namespace ExtensionManager const char* location = ext.GetLocation(); ptrdiff_t count = std::count_if( - std::cbegin(m_extensions), - std::cend(m_extensions), + std::begin(m_extensions), + std::end(m_extensions), [&location](const auto& ext) { return strcmp(location, ext->GetLocation()) == 0; } ); diff --git a/qnap/README.md b/qnap/README.md new file mode 100644 index 000000000..1d6857f6e --- /dev/null +++ b/qnap/README.md @@ -0,0 +1,30 @@ +# QNAP nzbget packages + +We support QNAP via native qpkg packages, built with QNAP toolchains (only x86/x86_64/arm_64 QNAP architectures) and buildroot qpkg, repacked from linux installer (all QNAP architectures) + +## Installing + +Prerequsites: Enable installation of applications without digital signature (`AppCenter` - `Settings` - `Allow installation of applications without a valid digital signature`) + +To install nzbget for QNAP download qpkg for your architecture, then from QNAP AppCenter select `Install Manually` - browse for downloaded qpkg and press `Install` +For digital signature warning select `I understand the risks and want to install this application` and press `Install`. +After installation - Press `Open` in AppCenter or click NZBGet icon on desktop. Default login/password for WebUI +``` +Login: nzbget +Password: tegbzn6789 +``` + +## Configuring + +Change `PATHS` - `MainDir` to point to shared folder location, for example +``` +/share/CACHEDEV1_DATA/Public/nzbget +``` +By default, nzbget will download all files to package directory, inaccessible from shares. + +## Extensions + +QNAP packaged with python2. To support python3 extensions, need to install Python3 package from QNAP Store, and add to `EXTENSION SCRIPTS` - `ShellOverride` path to python3 executable like this: +``` +.py=/share/CACHEDEV1_DATA/.qpkg/Python3/python3/bin/python3; +``` diff --git a/qnap/build-info.md b/qnap/build-info.md new file mode 100644 index 000000000..2ac8d5778 --- /dev/null +++ b/qnap/build-info.md @@ -0,0 +1,43 @@ +# About + +"build-nzbget.sh" is a bash script which is used to build nzbget QNAP packages. + + +# Prerequisites + +- linux x86_64 host (Ubuntu 22.04 LTS for example) + +We support building nzbget for QNAP for x86 / x86_64 / arm_64 architectures only, because other platforms toolchains is too old (nzbget need gcc 4.9+ for building). + +- download x86/x86_64 toolchains from http://download.qnap.com/dev/Toolchain/QNAP_cross_toolchains_64.20160606.tar +- download arm_64 toolchain from http://download.qnap.com/dev/Toolchain/aarch64-QNAP-linux-gnu.tgz +- extract toolchains to $QNAP_ROOT/toolchain (default - /qnap/toolchain), needed directory structure for script: +``` +/qnap/toolchain +├── aarch64 +│   └── cross-tools +├── i686 +│   ├── cross-tools +│   └── fs +└── x86_64 + ├── cross-tools + └── fs +``` +- install QDK from `https://github.com/qnap-dev/QDK` +``` +git clone https://github.com/qnap-dev/QDK +cd QDK +sed 's|python|python3|' -i InstallToUbuntu.sh +sudo ./InstallToUbuntu.sh install +``` + +# Building NZBGet + +From cloned repository run +``` +bash qnap/build-nzbget.sh +``` + +# Output files + +- /qnap/nzbget/build/*.qpkg - one file per platform diff --git a/qnap/build-nzbget.sh b/qnap/build-nzbget.sh new file mode 100644 index 000000000..3eee6311e --- /dev/null +++ b/qnap/build-nzbget.sh @@ -0,0 +1,251 @@ +#!/bin/bash +set -e + +# config variables +QNAP_ROOT=/qnap +TOOLCHAIN_PATH=$QNAP_ROOT/toolchain +LIB_SRC_PATH=$QNAP_ROOT/source +LIB_PATH=$QNAP_ROOT/lib +ALL_ARCHS="i686 x86_64 aarch64" +UNRAR_VERSION=6.2.12 +P7ZIP_VERSION=16.02 +COREX=4 + +download_lib_source() +{ + LIB=$1 + URL=$2 + LIB_SRC_FILE=${URL##*/} + if [ ! -f "$LIB_SRC_PATH/$LIB_SRC_FILE" ]; then + echo "Downloading $LIB_SRC_FILE ..." + mkdir -p "$LIB_SRC_PATH" + curl -o "$LIB_SRC_PATH/$LIB_SRC_FILE" -lL $URL + fi +} + +build_lib() +{ + URL=$1 + LIB_SRC_FILE=${URL##*/} + LIB=$(echo $LIB_SRC_FILE | cut -d- -f 1) + download_lib_source $LIB $URL + if [ ! -d "$LIB_PATH/$ARCH/$LIB" ]; then + mkdir -p "$LIB_PATH/$ARCH" + cp "$LIB_SRC_PATH/$LIB_SRC_FILE" "$LIB_PATH/$ARCH" + cd "$LIB_PATH/$ARCH" + tar zxf "$LIB_SRC_FILE" + rm $LIB_SRC_FILE + cd ${LIB_SRC_FILE/.tar.gz/} + case $LIB in + "ncurses") + export > /tmp/export.txt + ./configure --with-termlib --without-progs --host=$HOST --prefix="$PWD/../$LIB" + ;; + "zlib") + ./configure --static --prefix="$PWD/../$LIB" + ;; + "libxml2") + ./autogen.sh --host=$HOST --enable-static --disable-shared --without-python --prefix="$PWD/../$LIB" + ;; + "musl") + ./configure --prefix="$PWD/../$LIB" + ;; + "openssl") + case $ARCH in + "i686") + OPENSSL_ARCH=generic32 + ;; + *) + OPENSSL_ARCH=$ARCH + ;; + esac + perl Configure linux-$OPENSSL_ARCH no-shared --prefix="$PWD/../$LIB" + ;; + "boost") + ./bootstrap.sh --with-libraries=json --prefix="$PWD/../$LIB" + echo "using gcc : qnap : $CXX ; " >> project-config.jam + ./b2 --toolset=gcc-qnap cxxstd=14 link=static runtime-link=static install + ;; + esac + if [ "$LIB" != "boost" ]; then + make -j $COREX + make install + fi + cd .. + rm -rf ${LIB_SRC_FILE/.tar.gz/} + fi + if [ "$LIB" == "libxml2" ]; then + export CXXFLAGS="$CXXFLAGS -I$LIB_PATH/$ARCH/$LIB/include/libxml2" + else + export CXXFLAGS="$CXXFLAGS -I$LIB_PATH/$ARCH/$LIB/include" + fi + export CPPFLAGS="$CXXFLAGS" + if [ "$LIB" == "openssl" ]; then + export LDFLAGS="$LDFLAGS -L$LIB_PATH/$ARCH/$LIB/lib -L$LIB_PATH/$ARCH/$LIB/lib64" + else + export LDFLAGS="$LDFLAGS -L$LIB_PATH/$ARCH/$LIB/lib" + fi + cd $NZBGET_ROOT +} + +build_unrar() +{ + if [ ! -d "$LIB_PATH/$ARCH/unrar" ]; then + curl -o /tmp/unrar.tar.gz https://www.rarlab.com/rar/unrarsrc-$UNRAR_VERSION.tar.gz + cd /tmp + tar zxf unrar.tar.gz + rm unrar.tar.gz + cd unrar + sed "s|^CXX=.*|CXX=$CXX|" -i makefile + sed "s|^AR=.*|AR=$AR|" -i makefile + sed "s|^STRIP=.*|STRIP=$STRIP|" -i makefile + sed "s|^LDFLAGS=.*|LDFLAGS=-lm -lpthread|" -i makefile + sed "s|^CXXFLAGS=.*|CXXFLAGS=-std=c++11 -O2|" -i makefile + make clean + make -j $COREX + mkdir -p $LIB_PATH/$ARCH/unrar + cp unrar $LIB_PATH/$ARCH/unrar/unrar + cp license.txt $LIB_PATH/$ARCH/unrar/license-unrar.txt + rm -rf /tmp/unrar + cd $NZBGET_ROOT + fi +} + +build_7zip() +{ + if [ ! -d "$LIB_PATH/$ARCH/7zip" ]; then + curl -o /tmp/p7zip.tar.bz2 -lL https://sourceforge.net/projects/p7zip/files/p7zip/${P7ZIP_VERSION}/p7zip_${P7ZIP_VERSION}_src_all.tar.bz2 + cd /tmp + tar jxf p7zip.tar.bz2 + rm p7zip.tar.bz2 + cd p7zip_$P7ZIP_VERSION + rm makefile.machine + cp makefile.linux_any_cpu_gcc_4.X makefile.machine + sed "s|^CXX=.*|CXX=$CXX|" -i makefile.machine + sed "s|^CC=.*|CC=$CC|" -i makefile.machine + make clean + make -j $COREX + mkdir -p $LIB_PATH/$ARCH/7zip + cp bin/7za $LIB_PATH/$ARCH/7zip/7za + cp DOC/License.txt $LIB_PATH/$ARCH/7zip/license-7zip.txt + rm -rf /tmp/p7zip_$P7ZIP_VERSION + cd $NZBGET_ROOT + fi +} + +# cleanup shared and build directories +rm -rf $QNAP_ROOT/nzbget +cp -r qnap/package $QNAP_ROOT/nzbget +NZBGET_ROOT=$PWD + +# extract version and correct version in qpkg.cfg +VERSION=$(cat configure.ac | grep AC_INIT | cut -d , -f 2 | xargs) +sed "s|^QPKG_VER=.*|QPKG_VER=\"$VERSION\"|" -i $QNAP_ROOT/nzbget/qpkg.cfg +# if running from CI/CD, add testing to builds from non-main branch +if [ -n "$GITHUB_REF_NAME" ]; then + if [ "$GITHUB_REF_NAME" != "main" ]; then + NEW_VERSION="$VERSION-testing-$(date '+%Y%m%d')" + sed -e "s|AC_INIT(nzbget.*|AC_INIT(nzbget, $NEW_VERSION, https://github.com/nzbgetcom/nzbget/issues)|g" -i configure.ac + fi +fi + +for ARCH in $ALL_ARCHS; do + + # toolchain variables + export ARCH=$ARCH + export HOST="$ARCH-QNAP-linux-gnu" + export CC="$TOOLCHAIN_PATH/$ARCH/cross-tools/bin/$HOST-gcc" + export CPP="$TOOLCHAIN_PATH/$ARCH/cross-tools/bin/$HOST-cpp" + export CXX="$TOOLCHAIN_PATH/$ARCH/cross-tools/bin/$HOST-g++" + export AR="$TOOLCHAIN_PATH/$ARCH/cross-tools/bin/$HOST-ar" + export STRIP="$TOOLCHAIN_PATH/$ARCH/cross-tools/bin/$HOST-strip" + + # clean build flags + export CXXFLAGS="" + export CPPFLAGS="" + export LDFLAGS="" + export LIBS="" + + case $ARCH in + "i686") + QPKG_ARCH=x86 + ;; + "aarch64") + QPKG_ARCH=arm_64 + ;; + *) + QPKG_ARCH=$ARCH + ;; + esac + + build_lib "https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.4.tar.gz" + build_lib "https://zlib.net/zlib-1.3.1.tar.gz" + build_lib "https://gitlab.gnome.org/GNOME/libxml2/-/archive/v2.12.4/libxml2-v2.12.4.tar.gz" + build_lib "https://github.com/openssl/openssl/releases/download/openssl-3.1.2/openssl-3.1.2.tar.gz" + build_lib "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz" + + build_7zip + build_unrar + + autoreconf --install + + # we want to static link to all libs except libc + export CXXFLAGS="$CXXFLAGS -std=c++14 -O2" + export LIBS="-lncurses -lxml2 -lz -lm -lcrypto -ldl -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" + ./configure --disable-cpp-check --disable-dependency-tracking --host=$HOST + make clean + make -j $COREX + + SHARED=$QNAP_ROOT/nzbget/shared + if [ ! -d "$SHARED/nzbget" ]; then + # populate shared folder + rm -rf $SHARED/install + make install DESTDIR=$SHARED/install + cd $SHARED + rm -rf nzbget + mkdir -p nzbget + mv install/usr/local/share/doc/nzbget/* nzbget + mv install/usr/local/share/nzbget/webui nzbget + mv install/usr/local/share/nzbget/scripts nzbget + CONFTEMPLATE=nzbget/webui/nzbget.conf.template + mv install/usr/local/share/nzbget/nzbget.conf $CONFTEMPLATE + + rm -rf install + + # adjusting nzbget.conf + sed 's|^MainDir=.*|MainDir=${AppDir}/downloads|' -i $CONFTEMPLATE + sed 's|^DestDir=.*|DestDir=${MainDir}/completed|' -i $CONFTEMPLATE + sed 's|^InterDir=.*|InterDir=${MainDir}/intermediate|' -i $CONFTEMPLATE + sed 's|^WebDir=.*|WebDir=${AppDir}/webui|' -i $CONFTEMPLATE + sed 's|^ScriptDir=.*|ScriptDir=${AppDir}/scripts|' -i $CONFTEMPLATE + sed 's|^LogFile=.*|LogFile=${MainDir}/nzbget.log|' -i $CONFTEMPLATE + sed 's|^ConfigTemplate=.*|ConfigTemplate=${AppDir}/webui/nzbget.conf.template|' -i $CONFTEMPLATE + sed 's|^AuthorizedIP=.*|AuthorizedIP=127.0.0.1|' -i $CONFTEMPLATE + sed 's|^CertCheck=.*|CertCheck=yes|' -i $CONFTEMPLATE + sed 's|^CertStore=.*|CertStore=${AppDir}/cacert.pem|' -i $CONFTEMPLATE + sed 's|^UnrarCmd=.*|UnrarCmd=${AppDir}/unrar|' -i $CONFTEMPLATE + sed 's|^SevenZipCmd=.*|SevenZipCmd=${AppDir}/7za|' -i $CONFTEMPLATE + + cp $CONFTEMPLATE nzbget/nzbget.conf + curl -o nzbget/cacert.pem -L "https://curl.se/ca/cacert.pem" + fi + + cd $NZBGET_ROOT + mkdir -p $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget + # copy main executable + cp nzbget $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget/ + # copy unrar / 7zip + cp nzbget $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget/ + cp $LIB_PATH/$ARCH/7zip/* $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget/ + cp $LIB_PATH/$ARCH/unrar/* $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget/ + cd $QNAP_ROOT/nzbget + qbuild --build-arch $QPKG_ARCH + cd $NZBGET_ROOT +done + +# rename qpkgs +for FILE in $QNAP_ROOT/nzbget/build/*.qpkg; do + [ -f $FILE ] || continue + NEW_FILE=${FILE/.qpkg/_native.qpkg} + mv $FILE $NEW_FILE +done diff --git a/qnap/package/arm-x19/.gitkeep b/qnap/package/arm-x19/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/arm-x31/.gitkeep b/qnap/package/arm-x31/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/arm-x41/.gitkeep b/qnap/package/arm-x41/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/arm_64/.gitkeep b/qnap/package/arm_64/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/build_sign.csv b/qnap/package/build_sign.csv new file mode 100644 index 000000000..5fde18c0d --- /dev/null +++ b/qnap/package/build_sign.csv @@ -0,0 +1 @@ +,/nzbget.sh, diff --git a/qnap/package/config/.gitkeep b/qnap/package/config/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/icons/nzbget.gif b/qnap/package/icons/nzbget.gif new file mode 100644 index 000000000..715f6f9cc Binary files /dev/null and b/qnap/package/icons/nzbget.gif differ diff --git a/qnap/package/icons/nzbget_80.gif b/qnap/package/icons/nzbget_80.gif new file mode 100644 index 000000000..9e54309cb Binary files /dev/null and b/qnap/package/icons/nzbget_80.gif differ diff --git a/qnap/package/icons/nzbget_gray.gif b/qnap/package/icons/nzbget_gray.gif new file mode 100644 index 000000000..4b9a5f339 Binary files /dev/null and b/qnap/package/icons/nzbget_gray.gif differ diff --git a/qnap/package/package_routines b/qnap/package/package_routines new file mode 100644 index 000000000..fd83600d8 --- /dev/null +++ b/qnap/package/package_routines @@ -0,0 +1,140 @@ +###################################################################### +# List of available definitions (it's not necessary to uncomment them) +###################################################################### +###### Command definitions ##### +#CMD_AWK="/bin/awk" +#CMD_CAT="/bin/cat" +#CMD_CHMOD="/bin/chmod" +#CMD_CHOWN="/bin/chown" +#CMD_CP="/bin/cp" +#CMD_CUT="/bin/cut" +#CMD_DATE="/bin/date" +#CMD_ECHO="/bin/echo" +#CMD_EXPR="/usr/bin/expr" +#CMD_FIND="/usr/bin/find" +#CMD_GETCFG="/sbin/getcfg" +#CMD_GREP="/bin/grep" +#CMD_GZIP="/bin/gzip" +#CMD_HOSTNAME="/bin/hostname" +#CMD_LN="/bin/ln" +#CMD_LOG_TOOL="/sbin/log_tool" +#CMD_MD5SUM="/bin/md5sum" +#CMD_MKDIR="/bin/mkdir" +#CMD_MV="/bin/mv" +#CMD_RM="/bin/rm" +#CMD_RMDIR="/bin/rmdir" +#CMD_SED="/bin/sed" +#CMD_SETCFG="/sbin/setcfg" +#CMD_SLEEP="/bin/sleep" +#CMD_SORT="/usr/bin/sort" +#CMD_SYNC="/bin/sync" +#CMD_TAR="/bin/tar" +#CMD_TOUCH="/bin/touch" +#CMD_WGET="/usr/bin/wget" +#CMD_WLOG="/sbin/write_log" +#CMD_XARGS="/usr/bin/xargs" +#CMD_7Z="/usr/local/sbin/7z" +# +###### System definitions ##### +#SYS_EXTRACT_DIR="$(pwd)" +#SYS_CONFIG_DIR="/etc/config" +#SYS_INIT_DIR="/etc/init.d" +#SYS_STARTUP_DIR="/etc/rcS.d" +#SYS_SHUTDOWN_DIR="/etc/rcK.d" +#SYS_RSS_IMG_DIR="/home/httpd/RSS/images" +#SYS_QPKG_DATA_FILE_GZIP="./data.tar.gz" +#SYS_QPKG_DATA_FILE_BZIP2="./data.tar.bz2" +#SYS_QPKG_DATA_FILE_7ZIP="./data.tar.7z" +#SYS_QPKG_DATA_CONFIG_FILE="./conf.tar.gz" +#SYS_QPKG_DATA_MD5SUM_FILE="./md5sum" +#SYS_QPKG_DATA_PACKAGES_FILE="./Packages.gz" +#SYS_QPKG_CONFIG_FILE="$SYS_CONFIG_DIR/qpkg.conf" +#SYS_QPKG_CONF_FIELD_QPKGFILE="QPKG_File" +#SYS_QPKG_CONF_FIELD_NAME="Name" +#SYS_QPKG_CONF_FIELD_VERSION="Version" +#SYS_QPKG_CONF_FIELD_ENABLE="Enable" +#SYS_QPKG_CONF_FIELD_DATE="Date" +#SYS_QPKG_CONF_FIELD_SHELL="Shell" +#SYS_QPKG_CONF_FIELD_INSTALL_PATH="Install_Path" +#SYS_QPKG_CONF_FIELD_CONFIG_PATH="Config_Path" +#SYS_QPKG_CONF_FIELD_WEBUI="WebUI" +#SYS_QPKG_CONF_FIELD_WEBPORT="Web_Port" +#SYS_QPKG_CONF_FIELD_SERVICEPORT="Service_Port" +#SYS_QPKG_CONF_FIELD_SERVICE_PIDFILE="Pid_File" +#SYS_QPKG_CONF_FIELD_AUTHOR="Author" +#SYS_QPKG_CONF_FIELD_RC_NUMBER="RC_Number" +## The following variables are assigned values at run-time. +#SYS_HOSTNAME=$($CMD_HOSTNAME) +## Data file name (one of SYS_QPKG_DATA_FILE_GZIP, SYS_QPKG_DATA_FILE_BZIP2, +## or SYS_QPKG_DATA_FILE_7ZIP) +#SYS_QPKG_DATA_FILE= +## Base location. +#SYS_QPKG_BASE="" +## Base location of QPKG installed packages. +#SYS_QPKG_INSTALL_PATH="" +## Location of installed software. +#SYS_QPKG_DIR="" +## If the QPKG should be enabled or disabled after the installation/upgrade. +#SYS_QPKG_SERVICE_ENABLED="" +## Architecture of the device the QPKG is installed on. +#SYS_CPU_ARCH="" +## Name and location of system shares +#SYS_PUBLIC_SHARE="" +#SYS_PUBLIC_PATH="" +#SYS_DOWNLOAD_SHARE="" +#SYS_DOWNLOAD_PATH="" +#SYS_MULTIMEDIA_SHARE="" +#SYS_MULTIMEDIA_PATH="" +#SYS_RECORDINGS_SHARE="" +#SYS_RECORDINGS_PATH="" +#SYS_USB_SHARE="" +#SYS_USB_PATH="" +#SYS_WEB_SHARE="" +#SYS_WEB_PATH="" +## Path to ipkg or opkg package tool if installed. +#CMD_PKG_TOOL= +# +###################################################################### +# All package specific functions shall call 'err_log MSG' if an error +# is detected that shall terminate the installation. +###################################################################### +# +###################################################################### +# Define any package specific operations that shall be performed when +# the package is removed. +###################################################################### +#PKG_PRE_REMOVE="{ +#}" +# +#PKG_MAIN_REMOVE="{ +#}" +# +#PKG_POST_REMOVE="{ +#}" +# +###################################################################### +# Define any package specific initialization that shall be performed +# before the package is installed. +###################################################################### +#pkg_init(){ +#} +# +###################################################################### +# Define any package specific requirement checks that shall be +# performed before the package is installed. +###################################################################### +#pkg_check_requirement(){ +#} +# +###################################################################### +# Define any package specific operations that shall be performed when +# the package is installed. +###################################################################### +#pkg_pre_install(){ +#} +# +#pkg_install(){ +#} +# +#pkg_post_install(){ +#} diff --git a/qnap/package/qpkg.cfg b/qnap/package/qpkg.cfg new file mode 100644 index 000000000..abcf7feff --- /dev/null +++ b/qnap/package/qpkg.cfg @@ -0,0 +1,103 @@ +# Name of the packaged application. +QPKG_NAME="nzbget" +# Name of the display application. +QPKG_DISPLAY_NAME="NZBGet" +# Version of the packaged application. +QPKG_VER="22.2" +# Author or maintainer of the package +QPKG_AUTHOR="nzbget@nzbget.com" +# License for the packaged application +QPKG_LICENSE="GNU GPLv2" +# One-line description of the packaged application +QPKG_SUMMARY="NZBGet is a binary downloader, which downloads files from Usenet based on information given in nzb-files." + +# Preferred number in start/stop sequence. +QPKG_RC_NUM="1000" +# Init-script used to control the start and stop of the installed application. +QPKG_SERVICE_PROGRAM="nzbget.sh" + +# Optional 1 is enable. Path of starting/ stopping shall script. (no start/stop on App Center) +#QPKG_DISABLE_APPCENTER_UI_SERVICE=1 + +# Specifies any packages required for the current package to operate. +#QPKG_REQUIRE="Python >= 2.7" +# Replace the QPKG_REQUIRE message displayed in the system log +#QPKG_REQUIRE_MSG="" +# Specifies what packages cannot be installed if the current package +# is to operate properly. +#QPKG_CONFLICT="Python" +# Name of configuration file (multiple definitions are allowed). +#QPKG_CONFIG="myApp.conf" +#QPKG_CONFIG="/etc/config/myApp.conf" +# Port number used by service program. +#QPKG_SERVICE_PORT="" +# Location of file with running service's PID +#QPKG_SERVICE_PIDFILE="" +# Relative path to web interface +QPKG_WEBUI="/" +# Port number for the web interface. +QPKG_WEB_PORT="6789" +# Port number for the SSL web interface. +#QPKG_WEB_SSL_PORT="" + +# Use QTS HTTP Proxy and set Proxy_Path in the qpkg.conf. +# When the QPKG has its own HTTP service port, and want clients to connect via QTS HTTP port (default 8080). +# Usually use this option when the QPKG need to connect via myQNAPcloud service. +#QPKG_USE_PROXY="1" +#QPKG_PROXY_PATH="/qpkg_name" + +#Desktop Application (since 4.1) +# Set value to 1 means to open the QPKG's Web UI inside QTS desktop instead of new window. +#QPKG_DESKTOP_APP="1" +# Desktop Application Window default inner width (since 4.1) (not over 1178) +#QPKG_DESKTOP_APP_WIN_WIDTH="" +# Desktop Application Window default inner height (since 4.1) (not over 600) +#QPKG_DESKTOP_APP_WIN_HEIGHT="" + +# Minimum QTS version requirement +QTS_MINI_VERSION="4.1.0" + +# Select volume +# 1: support installation +# 2: support migration +# 3 (1+2): support both installation and migration +QPKG_VOLUME_SELECT="3" + +# Set timeout for QPKG enable and QPKG disable (since 4.1.0) +# Format in seconds (enable, disable) +#QPKG_TIMEOUT="10,30" + +# Visible setting for the QPKG that has web UI, show this QPKG on the Main menu of +# 1(default): administrators, 2: all NAS users. +#QPKG_VISIBLE="2" + +# Make the QPKG be visible only for +# 1: administrators, 2: all NAS users, 3(default): No limit +#QPKG_FORCE_VISIBLE="3" + +# Location of icons for the packaged application. +QDK_DATA_DIR_ICONS="icons" +# Location of files specific to arm-x19 packages. +QDK_DATA_DIR_X19="arm-x19" +# Location of files specific to arm-x31 packages. +QDK_DATA_DIR_X31="arm-x31" +# Location of files specific to arm-x41 packages. +QDK_DATA_DIR_X41="arm-x41" +# Location of files specific to x86 packages. +QDK_DATA_DIR_X86="x86" +# Location of files specific to x86 (64-bit) packages. +QDK_DATA_DIR_X86_64="x86_64" +# Location of files common to all architectures. +QDK_DATA_DIR_SHARED="shared" +# Location of configuration files. +#QDK_DATA_DIR_CONFIG="config" +# Name of local data package. +#QDK_DATA_FILE="" +# Name of extra package (multiple definitions are allowed). +#QDK_EXTRA_FILE="" +# For QNAP code signing (currently can be done only inside QNAP) +# Uncomment the following four options if you want to enable code signing for this QPKG +#QNAP_CODE_SIGNING="0" +#QNAP_CODE_SIGNING_SERVER_IP="codesigning.qnap.com.tw" +#QNAP_CODE_SIGNING_SERVER_PORT="5001" +#QNAP_CODE_SIGNING_CSV="build_sign.csv" diff --git a/qnap/package/shared/nzbget.sh b/qnap/package/shared/nzbget.sh new file mode 100755 index 000000000..0f6a13073 --- /dev/null +++ b/qnap/package/shared/nzbget.sh @@ -0,0 +1,35 @@ +#!/bin/sh +CONF=/etc/config/qpkg.conf +QPKG_NAME="nzbget" +QPKG_ROOT=`/sbin/getcfg $QPKG_NAME Install_Path -f ${CONF}` +APACHE_ROOT=`/sbin/getcfg SHARE_DEF defWeb -d Qweb -f /etc/config/def_share.info` +export QNAP_QPKG=$QPKG_NAME + +case "$1" in + start) + ENABLED=$(/sbin/getcfg $QPKG_NAME Enable -u -d FALSE -f $CONF) + if [ "$ENABLED" != "TRUE" ]; then + echo "$QPKG_NAME is disabled." + exit 1 + fi + cd $QPKG_ROOT/nzbget + $QPKG_ROOT/nzbget/nzbget -c $QPKG_ROOT/nzbget/nzbget.conf -D + ;; + + stop) + $QPKG_ROOT/nzbget/nzbget -c $QPKG_ROOT/nzbget/nzbget.conf -Q + ;; + + restart) + $0 stop + $0 start + ;; + remove) + ;; + + *) + echo "Usage: $0 {start|stop|restart|remove}" + exit 1 +esac + +exit 0 diff --git a/qnap/package/x86/.gitkeep b/qnap/package/x86/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/x86_64/.gitkeep b/qnap/package/x86_64/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/package/x86_ce53xx/.gitkeep b/qnap/package/x86_ce53xx/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/qnap/repack-info.md b/qnap/repack-info.md new file mode 100644 index 000000000..2afa7a56c --- /dev/null +++ b/qnap/repack-info.md @@ -0,0 +1,27 @@ +# About + +"repack-nzbget.sh" is a bash script which is used to repack nzbget linux installer to QNAP packages (all platforms). + + +# Prerequisites + +- linux x86_64 host (Ubuntu 22.04 LTS for example) +- installed QDK from `https://github.com/qnap-dev/QDK` +``` +git clone https://github.com/qnap-dev/QDK +cd QDK +sed 's|python|python3|' -i InstallToUbuntu.sh +sudo ./InstallToUbuntu.sh install +``` +- nzbget linux installer (`nzbget-${VERSION}-bin-linux.run`) + +# Building NZBGet QNAP packages + +From cloned repository run +``` +bash qnap/repack-nzbget.sh +``` + +## Output files + +- /qnap/nzbget/build/*.qpkg - one file per platform diff --git a/qnap/repack-nzbget.sh b/qnap/repack-nzbget.sh new file mode 100644 index 000000000..2ca6282a6 --- /dev/null +++ b/qnap/repack-nzbget.sh @@ -0,0 +1,61 @@ +#!/bin/bash +set -e + +# config variables +QNAP_ROOT=/qnap + +# cleanup shared and build directories +rm -rf $QNAP_ROOT/nzbget +cp -r qnap/package $QNAP_ROOT/nzbget +NZBGET_ROOT=$PWD + +# installer - first param +# if empty - find installer file in artifacts dir +INSTALLER="$1" +if [ -z $INSTALLER ]; then + INSTALLER=$(find $NZBGET_ROOT/nzbget-linux-installers/ -name *linux.run) +fi +if [ -z $INSTALLER ]; then + echo "Cannot find linux installer file. Exitig." + exit 1 +fi + +# extract version +VERSION=$(bash $INSTALLER --help | grep 'Installer for' | cut -d ' ' -f 3 | sed -r 's/nzbget-//' | sed -r 's/-testing-.*//') + +# correct version in qpkg.cfg +sed "s|^QPKG_VER=.*|QPKG_VER=\"$VERSION\"|" -i $QNAP_ROOT/nzbget/qpkg.cfg + +# map of nzbget arch - qnap arch +# arm_64 - aarch64 +# arm-x19 - armel +# arm-x31 - armhf +# arm-x41 - armhf +# x86_64 - x86_64 +# x86 - i686 +for QPKG_ARCH in arm_64 arm-x19 arm-x31 arm-x41 x86_64 x86; do + case $QPKG_ARCH in + arm_64) + ARCH=aarch64; + ;; + arm-x19) + ARCH=armel; + ;; + arm-x31) + ARCH=armhf; + ;; + arm-x41) + ARCH=armhf; + ;; + x86) + ARCH=i686; + ;; + *) + ARCH=$QPKG_ARCH; + ;; + esac + bash $INSTALLER --destdir $QNAP_ROOT/nzbget/$QPKG_ARCH/nzbget --arch $ARCH --silent + cd $QNAP_ROOT/nzbget + qbuild --build-arch $QPKG_ARCH + cd $NZBGET_ROOT +done