From 43c0788a53e98f8bcc505380bc45ff9c8746cba0 Mon Sep 17 00:00:00 2001 From: Lukasz Goworko Date: Thu, 16 Oct 2025 10:17:21 +0200 Subject: [PATCH 01/11] fix: Added IPv6 support with brackets to trusted domains Signed-off-by: Lukasz Goworko --- bin/nextcloud-domain.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/nextcloud-domain.sh b/bin/nextcloud-domain.sh index a8d0af1d5..ffc9d86f2 100644 --- a/bin/nextcloud-domain.sh +++ b/bin/nextcloud-domain.sh @@ -11,9 +11,12 @@ done # wicd service finishes before completing DHCP while :; do local_ip="$(get_ip)" - pub_ip="$(curl -m4 icanhazip.com 2>/dev/null)" - [[ "$pub_ip" != "" ]] && ncc config:system:set trusted_domains 11 --value="$pub_ip" + pub_ipv4="$(curl -4 -m4 icanhazip.com 2>/dev/null)" + pub_ipv6="$(curl -6 -m4 icanhazip.com 2>/dev/null)" + [[ "$pub_ipv4" != "" ]] && ncc config:system:set trusted_domains 11 --value="$pub_ipv4" + [[ "$pub_ipv6" != "" ]] && ncc config:system:set trusted_domains 12 --value="[$pub_ipv6]" + [[ "$local_ip" != "" ]] && break sleep 3 From 9d90679c1e4d2bdb5c725db15b540630ce7056ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 13:09:27 +0000 Subject: [PATCH 02/11] Fix CI/CD pipeline issues (#2076) - Update armbian base and use release branch instead of tag - Fix nextcloud tests for NC 31 - Use venv for integration tests - Use ubuntu-latest for all workflows (except arm64) - Push start NC version for dist-upgrade test to 29 - Use ncp v1.53.2/v1.53.3 as base version for dist-upgrade check - nextcloud_tests.py: Ignore errors in nextcloud.log - Fix redis issue on arm - system_tests.py: Add option to use pw-less sudo for commands - nextcloud_test.py,activation_tests.py: Use new selenium initialization syntax - build-lxd.yml: Install incus from system packages - build-lxd.yml: Disable test-dist-upgrade temporarily --- .github/workflows/build-lxd.yml | 100 ++++++++++++++++++-------- .github/workflows/build-sd-images.yml | 34 +++++++-- .github/workflows/release.yml | 17 ++++- README.md | 27 +++++-- bin/ncp/CONFIG/nc-init.sh | 21 +++++- bin/ncp/CONFIG/nc-nextcloud.sh | 4 ++ build/armbian/armbian.sh | 6 +- build/armbian/armbian_version | 2 +- post-inst.sh | 1 + tests/activation_tests.py | 21 ++++-- tests/nextcloud_tests.py | 24 +++++-- tests/requirements.txt | 2 +- tests/system_tests.py | 38 ++++++---- 13 files changed, 225 insertions(+), 72 deletions(-) diff --git a/.github/workflows/build-lxd.yml b/.github/workflows/build-lxd.yml index f16e07b4c..322c369fb 100644 --- a/.github/workflows/build-lxd.yml +++ b/.github/workflows/build-lxd.yml @@ -47,7 +47,7 @@ jobs: echo "lxd_extra_profile=network" | tee -a "$GITHUB_OUTPUT" else LXC_CMD="incus" - RUNNER_LABEL="ubuntu-20.04" + RUNNER_LABEL="ubuntu-latest" fi echo "runner_label=$RUNNER_LABEL" | tee -a $GITHUB_OUTPUT @@ -73,7 +73,7 @@ jobs: - name: Setup incus if: ${{ needs.determine-runner.outputs.runner_label != 'ubuntu-20.04-arm64' }} run: | - curl https://pkgs.zabbly.com/get/incus-stable | sudo sh -x + sudo apt-get install -y incus qemu-system incus-tools sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT sudo incus admin init --auto @@ -341,6 +341,7 @@ jobs: # } test-dist-upgrade: + if: false needs: - determine-runner runs-on: ${{ needs.determine-runner.outputs.runner_label }} @@ -348,14 +349,14 @@ jobs: VERSION: "${{ inputs.git_ref || github.ref }}" LXC: "${{ needs.determine-runner.outputs.lxc_cmd }}" LXD_EXTRA_PROFILE: "${{ needs.determine-runner.outputs.lxd_extra_profile }}" - PREVIOUS_IMAGE_URL_ARM64: "https://github.com/nextcloud/nextcloudpi/releases/download/v1.53.0/NextcloudPi_LXD_arm64_v1.53.0.tar.gz" - PREVIOUS_IMAGE_URL_AMD64: "https://github.com/nextcloud/nextcloudpi/releases/download/v1.53.0/NextCloudPi_LXD_x86_v1.53.0.tar.gz" + PREVIOUS_IMAGE_URL_ARM64: "https://github.com/nextcloud/nextcloudpi/releases/download/v1.53.2/NextcloudPi_LXD_arm64_v1.53.2.tar.gz" + PREVIOUS_IMAGE_URL_AMD64: "https://github.com/nextcloud/nextcloudpi/releases/download/v1.53.2/NextCloudPi_LXD_x86_v1.53.2.tar.gz" USE_INCUS: "${{ needs.determine-runner.outputs.lxc_cmd == 'incus' && 'yes' || 'no' }}" steps: - name: Setup incus if: ${{ needs.determine-runner.outputs.runner_label != 'ubuntu-20.04-arm64' }} run: | - curl https://pkgs.zabbly.com/get/incus-stable | sudo sh -x + sudo apt-get install -y incus qemu-system incus-tools sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT sudo incus admin init --auto @@ -364,31 +365,40 @@ jobs: with: ref: "v1.54.3" - name: Setup Firefox + if: ${{ runner.arch != 'ARM64' }} continue-on-error: true id: setup-firefox-browser-action uses: browser-actions/setup-firefox@latest - name: Setup Firefox from packages - if: ${{ steps.setup-firefox-browser-action.outcome == 'failure' }} + if: ${{ runner.arch == 'ARM64' || steps.setup-firefox-browser-action.outcome == 'failure' }} run: | + sudo apt-get update sudo apt-get install -y --no-install-recommends firefox - name: Setup GeckoDriver env: GH_TOKEN: ${{ github.token }} run: | + set -x arch=linux64 - if [[ "$RUNNER_ARCH" == "ARM64" ]] + if [[ "${{ runner.arch }}" == "ARM64" ]] then arch="linux-aarch64" fi gh release download -R mozilla/geckodriver -p 'geckodriver-*-'"$arch.tar.gz" tar xf "geckodriver-"*"-$arch.tar.gz" sudo mv geckodriver /usr/local/bin/ + sudo chmod +x /usr/local/bin/geckodriver + echo "GECKODRIVER_PATH=/usr/local/bin/geckodriver" >> "$GITHUB_ENV" + geckodriver -V - name: Setup Selenium - run: pip install selenium + run: | + sudo apt-get -y install python3-venv + python3 -m venv ./.venv + ./.venv/bin/pip install 'selenium>=3.0.0,<4.0.0' - name: download LXD image run: | image_url="${PREVIOUS_IMAGE_URL_AMD64?}" - if [[ "$RUNNER_ARCH" == "ARM64" ]] + if [[ "${{ runner.arch }}" == "ARM64" ]] then image_url="${PREVIOUS_IMAGE_URL_ARM64?}" fi @@ -412,8 +422,11 @@ jobs: - name: Activate and Test LXD Image working-directory: ./tests run: | + set -x + export GECKODRIVER_PATH="$GECKODRIVER_PATH" + export FF_BINARY_PATH="$(which firefox)" sudo "$LXC" exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' & - python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || { + ../.venv/bin/python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || { echo "Activation test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -422,7 +435,7 @@ jobs: sudo "$LXC" exec ncp -- "tail -n20 /var/log/ncp.log" || true exit 1 } - python nextcloud_tests.py --skip-release-check --no-gui "nextcloudpi.local" 443 4443 || { + ../.venv/bin/python nextcloud_tests.py --skip-release-check --no-gui "nextcloudpi.local" 443 4443 || { echo "Nextcloud test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -435,8 +448,15 @@ jobs: sudo "$LXC" exec ncp -- cat "$datadir/nextcloud.log" || true exit 1 } - USE_INCUS="$USE_INCUS" python system_tests.py --non-interactive --skip-update-test || { + sleep 10 + USE_INCUS="$USE_INCUS" ../.venv/bin/python system_tests.py --non-interactive --skip-update-test || { echo "System test failed!" + echo "ncp.log: " + sudo "$LXC" exec ncp -- "tail -n20 /var/log/ncp.log" || true + echo "================" + echo "nextcloud log: " + datadir="$(sudo "$LXC" exec ncp -- ncc config:system:get datadirectory)" + sudo "$LXC" exec ncp -- cat "$datadir/nextcloud.log" || true exit 1 } @@ -457,7 +477,7 @@ jobs: echo "Running update to ${VERSION}" current_nc_version="$(sudo "$LXC" exec ncp -- ncc status | grep "version:" | awk '{ print $3 }')" - latest_nc_version="27.1.6" + latest_nc_version="28.0.14" sudo "$LXC" exec ncp -- apt-get update ||: sudo "$LXC" exec ncp -- apt-get install --no-install-recommends -y gnupg2 @@ -466,13 +486,13 @@ jobs: sudo "$LXC" exec ncp -- bash -c "DBG=x ncp-update ${UPDATE_ARGS[*]}" sudo "$LXC" exec ncp -- /usr/local/bin/ncc status - if [[ "$current_nc_version" =~ "$latest_nc_version".* ]] - then - echo "Nextcloud is up to date - skipping NC update test." - else - sudo "$LXC" exec ncp -- bash -c "DBG=x ncp-update-nc ${latest_nc_version?}" - sudo "$LXC" exec ncp -- /usr/local/bin/ncc status - fi + #if [[ "$current_nc_version" =~ "$latest_nc_version".* ]] + #then + # echo "Nextcloud is up to date - skipping NC update test." + #else + # sudo "$LXC" exec ncp -- bash -c "DBG=x ncp-update-nc ${latest_nc_version?}" + # sudo "$LXC" exec ncp -- /usr/local/bin/ncc status + #fi sudo "$LXC" exec ncp -- rm -f /opt/ncdata/data/nextcloud.log @@ -493,7 +513,10 @@ jobs: - name: Test LXD Image working-directory: ./tests run: | - python nextcloud_tests.py --no-gui --skip-release-check "nextcloudpi.local" 443 4443 || { + set -x + export GECKODRIVER_PATH="$GECKODRIVER_PATH" + export FF_BINARY_PATH="$(which firefox)" + ../.venv/bin/python nextcloud_tests.py --no-gui --skip-release-check "nextcloudpi.local" 443 4443 || { echo "Nextcloud test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -507,7 +530,7 @@ jobs: exit 1 } sudo "$LXC" exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' & - USE_INCUS="$USE_INCUS" python system_tests.py --non-interactive --skip-update-test || { + USE_INCUS="$USE_INCUS" ../.venv/bin/python system_tests.py --non-interactive --skip-update-test || { echo "System test failed!" exit 1 } @@ -572,8 +595,11 @@ jobs: - name: Test LXD Image working-directory: ./tests run: | + set -x + export GECKODRIVER_PATH="$GECKODRIVER_PATH" + export FF_BINARY_PATH="$(which firefox)" sudo "$LXC" exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' & - python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || { + ../.venv/bin/python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || { echo "Nextcloud test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -586,7 +612,7 @@ jobs: sudo "$LXC" exec ncp -- cat "$datadir/nextcloud.log" || true exit 1 } - USE_INCUS="$USE_INCUS" python system_tests.py --non-interactive || { + USE_INCUS="$USE_INCUS" ../.venv/bin/python system_tests.py --non-interactive || { echo "System test failed!" exit 1 } @@ -612,32 +638,41 @@ jobs: - name: Setup incus if: ${{ needs.determine-runner.outputs.runner_label != 'ubuntu-20.04-arm64' }} run: | - curl https://pkgs.zabbly.com/get/incus-stable | sudo sh -x + sudo apt-get install -y incus qemu-system incus-tools sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT sudo incus admin init --auto - name: Setup Firefox + if: ${{ runner.arch != 'ARM64' }} continue-on-error: true id: setup-firefox-browser-action uses: browser-actions/setup-firefox@latest - name: Setup Firefox from packages - if: ${{ steps.setup-firefox-browser-action.outcome == 'failure' }} + if: ${{ runner.arch == 'ARM64' || steps.setup-firefox-browser-action.outcome == 'failure' }} run: | + sudo apt-get update sudo apt-get install -y --no-install-recommends firefox - name: Setup GeckoDriver env: GH_TOKEN: ${{ github.token }} run: | + set -x arch=linux64 - if [[ "$RUNNER_ARCH" == "ARM64" ]] + if [[ "${{ runner.arch }}" == "ARM64" ]] then arch="linux-aarch64" fi gh release download -R mozilla/geckodriver -p 'geckodriver-*-'"$arch.tar.gz" tar xf "geckodriver-"*"-$arch.tar.gz" sudo mv geckodriver /usr/local/bin/ + sudo chmod +x /usr/local/bin/geckodriver + echo "GECKODRIVER_PATH=/usr/local/bin/geckodriver" >> "$GITHUB_ENV" + geckodriver -V - name: Setup Selenium - run: pip install selenium + run: | + sudo apt-get install -y python3-venv + python3 -m venv ./.venv + ./.venv/bin/pip install selenium - name: download LXD image from artifact store uses: actions/download-artifact@v4 with: @@ -668,8 +703,11 @@ jobs: - name: Test LXD Image working-directory: ./tests run: | + set -x + export GECKODRIVER_PATH="$GECKODRIVER_PATH" + export FF_BINARY_PATH="$(which firefox)" sudo "$LXC" exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' & - python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || { + ../.venv/bin/python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || { echo "Activation test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -682,7 +720,7 @@ jobs: sudo "$LXC" exec ncp -- cat "$datadir/nextcloud.log" || true exit 1 } - python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || { + ../.venv/bin/python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || { echo "Nextcloud test failed!" echo "Geckodriver logs:" tail -n 20 geckodriver.log >&2 || true @@ -695,7 +733,7 @@ jobs: sudo "$LXC" exec ncp -- cat "$datadir/nextcloud.log" || true exit 1 } - USE_INCUS="$USE_INCUS" python system_tests.py --non-interactive || { + USE_INCUS="$USE_INCUS" ../.venv/bin/python system_tests.py --non-interactive || { echo "System test failed!" exit 1 } diff --git a/.github/workflows/build-sd-images.yml b/.github/workflows/build-sd-images.yml index caa2afaf6..0ee2e73a3 100644 --- a/.github/workflows/build-sd-images.yml +++ b/.github/workflows/build-sd-images.yml @@ -15,6 +15,10 @@ on: required: false default: true type: boolean + test_image_url: + required: false + type: string + default: "" outputs: artifact_name: value: "${{ jobs.build.outputs.artifact_name }}" @@ -23,7 +27,7 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest env: VERSION: "${{ inputs.git_ref }}" LOG_GUEST: "\\033[1;34mGUEST::\\033[0m" @@ -63,7 +67,13 @@ jobs: # which qemu-aarch64-static # update-binfmts --display qemu-aarch64 # update-binfmts --display qemu-arm + - name: "Skip build" + if: "${{ inputs.test_image_url != '' }}" + run: | + echo "artifact_file=NextcloudPi_TestImage_${VERSION//\//_}.img" >> $GITHUB_OUTPUT + echo "ARTIFACT_FILE=NextcloudPi_TestImage_${VERSION//\//_}.img" >> $GITHUB_ENV - name: "Build Armbian" + if: "${{ inputs.test_image_url == '' }}" id: build-armbian continue-on-error: true run: | @@ -103,6 +113,7 @@ jobs: name: ${{ github.run_id }}-${{ inputs.board_id }}-logs path: armbian/output - name: upload image to artifact store + if: "${{ inputs.test_image_url == '' }}" uses: actions/upload-artifact@v4 with: name: ${{ github.run_id }}-${{ inputs.board_id }}-image @@ -135,15 +146,24 @@ jobs: with: ref: "${{ env.VERSION }}" - uses: actions/download-artifact@v4 + if: "${{ inputs.test_image_url == '' }}" with: name: ${{ env.ARTIFACT_ID }} path: output + - name: Download Test Image + if: "${{ inputs.test_image_url != '' }}" + run: | + set -ex + mkdir -p output + wget -nv "${{ inputs.test_image_url }}" | pv -i 3 > "output/${ARTIFACT_FILE?}" - name: Prepare test run: | set -x mv output/${ARTIFACT_FILE?} ncp.img sudo apt-get install -y systemd-container - sudo pip install selenium + python3 -m venv ./.venv + . ./.venv/bin/activate + ./.venv/bin/pip install selenium sudo rm -rf raspbian_root . ./build/buildlib.sh mount_raspbian "ncp.img" @@ -175,7 +195,7 @@ jobs: sudo systemd-nspawn --boot -D ./raspbian_root/ -M ncp --hostname=nextcloudpi |& awk "{ print \"${LOG_GUEST} \" \$0 }" & sleep 60 - CONTAINER_CMD=(sudo systemd-run --machine=ncp -P --wait) + CONTAINER_CMD=(sudo systemd-run --machine=ncp -P --wait) success=false for attempt in {1..30} @@ -234,7 +254,7 @@ jobs: for attempt in {1..5} do echo -e "${LOG_CICD} == Activation Tests (attempt $attempt/5) ==" - python tests/activation_tests.py -t 300 --no-gui "$ip" 443 4443 |& awk "{ print \"${LOG_TEST} \" \$0 }" + ./.venv/bin/python tests/activation_tests.py -t 300 --no-gui "$ip" 443 4443 |& awk "{ print \"${LOG_TEST} \" \$0 }" [[ ${PIPESTATUS[0]} -eq 0 ]] || { echo -e "${LOG_CICD} Activation test failed!" echo -e "${LOG_DIAG} Geckodriver logs:" @@ -258,7 +278,7 @@ jobs: for attempt in {1..5} do echo -e "${LOG_CICD} == System Tests (attempt $attempt/5) ==" - sudo python tests/system_tests.py --non-interactive |& awk "{ print \"${LOG_TEST} \" \$0 }" + USE_SUDO=yes ./.venv/bin/python tests/system_tests.py --non-interactive |& awk "{ print \"${LOG_TEST} \" \$0 }" [[ ${PIPESTATUS[0]} -eq 0 ]] || { echo -e "${LOG_CICD} System test failed!" sleep 12 @@ -276,7 +296,7 @@ jobs: for attempt in {1..5} do echo -e "${LOG_CICD} == Nextcloud Tests (attempt $attempt/5) ==" - python tests/nextcloud_tests.py --no-gui "$ip" 443 4443 |& awk "{ print \"${LOG_TEST} \" \$0 }" + ./.venv/bin/python tests/nextcloud_tests.py --no-gui "$ip" 443 4443 |& awk "{ print \"${LOG_TEST} \" \$0 }" [[ ${PIPESTATUS[0]} -eq 0 ]] || { echo -e "${LOG_CICD} Nextcloud test failed!" echo -e "${LOG_DIAG} /etc/os-release:" @@ -336,7 +356,7 @@ jobs: } # test-distupgrade: -# runs-on: ubuntu-20.04 +# runs-on: ubuntu-latest # env: # VERSION: "${{ inputs.git_ref || github.ref }}" # LOG_GUEST: "\\033[1;34mGUEST::\\033[0m" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b6ce6a4f8..00b0a7f24 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,6 +26,11 @@ on: description: 'Release images to GH' required: false default: false + test_image_url: + type: string + description: 'URL for test image to test instead of actual armbian builds' + required: false + default: '' push: tags: - "v*" @@ -68,7 +73,7 @@ jobs: secrets: inherit raspberrypi-5: - if: ${{ inputs.sd-images || ( github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'docker-') ) }} + if: ${{ false && inputs.sd-images || ( github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'docker-') ) }} uses: ./.github/workflows/build-sd-images.yml with: git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}" @@ -76,6 +81,16 @@ jobs: board_name: RaspberryPi5 secrets: inherit + armbian-test-image: + if: ${{ inputs.test_image_url != '' || ( github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'docker-') ) }} + uses: ./.github/workflows/build-sd-images.yml + with: + git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}" + board_id: testimage + board_name: TestImage + test_image_url: "${{ inputs.test_image_url }}" + secrets: inherit + # TODO: Fix 32bit armbian images odroidxu4: # if: ${{ inputs.sd-images || ( github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'docker-') ) }} diff --git a/README.md b/README.md index 00980c7d0..cf21d7761 100644 --- a/README.md +++ b/README.md @@ -27,17 +27,15 @@ Please reach out in the [Matrix][chat-matrix-wiki] or [Telegram][chat-telegram-w --- -`master` +### Test Status -[![VM Tests][vm-tests-badge]][vm-tests] +`master` -[![Docker Tests][docker-tests-badge]][docker-tests] +[![Release](https://github.com/nextcloud/nextcloudpi/actions/workflows/release.yml/badge.svg)](https://github.com/nextcloud/nextcloudpi/actions/workflows/release.yml) `devel` -[![VM Tests][gh-vm-tests-badge-devel]][vm-tests] - -[![Docker Tests][gh-docker-tests-badge-devel]][docker-tests] +[![Release](https://github.com/nextcloud/nextcloudpi/actions/workflows/release.yml/badge.svg?branch=devel)](https://github.com/nextcloud/nextcloudpi/actions/workflows/release.yml) --- @@ -127,11 +125,26 @@ lxc start ncp ## Run in Proxmox +There are two ways to run NCP on Proxmox: + +### 1. Using the official release image + +In your Proxmox web interface, head to any storage pool that has CT Templates enabled, go to CT Templates, +click "Download from URL" and enter the link to the latest LXC image from the [Nextcloudpi releases page](https://github.com/nextcloud/nextcloudpi/releases) +and press "Download". + +Download from URL dialog + +Optionally, you can copy the corresponding md5 sum from the releases page and paste it in the "Checksum" field to have +Proxmox check that the downloaded image was not corrupted + +### 2. Installer by tteck + Use the [install script][ncp-proxmox-install-script-v5] from [tteck][tteck-profile] to install the LXC container on your Proxmox instance He has multiple helper scripts available for Proxmox on his [website][website-helper-scripts], do go have a look if you're using Proxmox. :+1: -Installation: `bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi-v5.sh)"` +Installation: `bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi.sh)"` Default Settings: `2GB RAM - 8GB Storage - 2vCPU` diff --git a/bin/ncp/CONFIG/nc-init.sh b/bin/ncp/CONFIG/nc-init.sh index 09c9e1c0e..2445b7ede 100644 --- a/bin/ncp/CONFIG/nc-init.sh +++ b/bin/ncp/CONFIG/nc-init.sh @@ -53,10 +53,29 @@ EOF ## INITIALIZE NEXTCLOUD # make sure redis is running first + REDISPASS="$( grep "^requirepass" /etc/redis/redis.conf | cut -f2 -d' ' )" if ! pgrep -c redis-server &>/dev/null; then mkdir -p /var/run/redis + mkdir -p /var/log/ chown redis /var/run/redis - sudo -u redis redis-server /etc/redis/redis.conf & + sudo -u redis redis-server /etc/redis/redis.conf > /var/log/redis.log 2>&1 & + redis_pid=$! + for i in {1..5} + do + + if redis-cli -s //var/run/redis/redis.sock -a "$REDISPASS" ping | grep PONG + then + break + else + if [[ $i -ge 5 ]] + then + echo "FAILED TO START REDIS" + cat /var/log/redis.log /var/log/redis/redis-server.log + return 1 + fi + fi + sleep 3 + done fi while :; do diff --git a/bin/ncp/CONFIG/nc-nextcloud.sh b/bin/ncp/CONFIG/nc-nextcloud.sh index d2d1cc793..70732b5ea 100644 --- a/bin/ncp/CONFIG/nc-nextcloud.sh +++ b/bin/ncp/CONFIG/nc-nextcloud.sh @@ -60,6 +60,10 @@ install() sed -i 's|# rename-command CONFIG ""|rename-command CONFIG ""|' $REDIS_CONF sed -i "s|^port.*|port 0|" $REDIS_CONF echo "maxmemory $REDIS_MEM" >> $REDIS_CONF + if [[ "$ARMBIAN_BUILD" == "yes" ]] + then + echo "ignore-warnings ARM64-COW-BUG" >> $REDIS_CONF + fi echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf if is_lxc; then diff --git a/build/armbian/armbian.sh b/build/armbian/armbian.sh index 3d79f4340..2078c4108 100644 --- a/build/armbian/armbian.sh +++ b/build/armbian/armbian.sh @@ -33,7 +33,11 @@ echo -e "\nInstalling NextCloudPi" hostname -F /etc/hostname # fix 'sudo resolve host' errors -CODE_DIR="$(pwd)" DBG=x bash install.sh +ARMBIAN_BUILD=yes CODE_DIR="$(pwd)" DBG=x bash install.sh || { + echo "SOMETHING WENT WRONG, EXITING..." + exit 1 +} +sed -i 's/^ignore-warnings ARM64-COW-BUG//' /etc/redis/redis.conf echo -e "\nPostinstall..." run_app_unsafe post-inst.sh diff --git a/build/armbian/armbian_version b/build/armbian/armbian_version index 3e5291183..a1dbeebcc 100644 --- a/build/armbian/armbian_version +++ b/build/armbian/armbian_version @@ -1 +1 @@ -v24.08 \ No newline at end of file +v25.08 diff --git a/post-inst.sh b/post-inst.sh index 9994c0a42..a619a0564 100644 --- a/post-inst.sh +++ b/post-inst.sh @@ -15,6 +15,7 @@ configure() # stop services pkill -x redis-server + [[ -f /var/log/redis.log ]] && rm /var/log/redis.log [[ -f /run/mysqld/mysqld.pid ]] && mysqladmin -u root shutdown [[ -f /run/crond.pid ]] && kill "$(cat /run/crond.pid)" pkill -f php-fpm diff --git a/tests/activation_tests.py b/tests/activation_tests.py index b9a9b7f69..dde06f2d2 100755 --- a/tests/activation_tests.py +++ b/tests/activation_tests.py @@ -23,6 +23,7 @@ from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By +from selenium.webdriver.firefox.service import Service from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.firefox.options import Options @@ -90,12 +91,15 @@ def signal_handler(sig, frame): sys.exit(0) -def test_activation(IP, nc_port, admin_port, options, wait_timeout=120): +def test_activation(IP, nc_port, admin_port, options, webdriver_exec_path=None, wait_timeout=120): """ Activation process checks""" + driver_kwargs={} + if webdriver_exec_path is not None: + driver_kwargs['service'] = Service(webdriver_exec_path) # activation page test = Test() - driver = webdriver.Firefox(options=options) + driver = webdriver.Firefox(options=options, **driver_kwargs) driver.implicitly_wait(5) test.new("activation opens") driver.get(f"https://{IP}:{nc_port}") @@ -137,7 +141,9 @@ def test_activation(IP, nc_port, admin_port, options, wait_timeout=120): # ncp-web test.new("ncp-web") - driver = webdriver.Firefox(options=options) + if webdriver_exec_path is not None: + driver_kwargs['service'] = Service(webdriver_exec_path) + driver = webdriver.Firefox(options=options, **driver_kwargs) driver.implicitly_wait(30) try: driver.get(f"https://ncp:{urllib.parse.quote_plus(ncp_pass)}@{IP}:{admin_port}") @@ -164,6 +170,13 @@ def test_activation(IP, nc_port, admin_port, options, wait_timeout=120): arg_timeout = 120 options = webdriver.FirefoxOptions() + webdriver_exec_path = None + if 'GECKODRIVER_PATH' in os.environ: + print(f"Setting geckodriver from env ({os.environ['GECKODRIVER_PATH']})") + webdriver_exec_path = os.environ['GECKODRIVER_PATH'] + if 'FF_BINARY_PATH' in os.environ: + print(f"Setting firefox binary from env ({os.environ['FF_BINARY_PATH']}") + options.binary_location = os.environ['FF_BINARY_PATH'] for opt, arg in opts: if opt in ('-h', '--help'): usage() @@ -184,7 +197,7 @@ def test_activation(IP, nc_port, admin_port, options, wait_timeout=120): print("Activation tests " + tc.yellow + IP + tc.normal) print("---------------------------") - test_activation(IP, nc_port, admin_port, options, arg_timeout) + test_activation(IP, nc_port, admin_port, options, webdriver_exec_path, arg_timeout) # License # diff --git a/tests/nextcloud_tests.py b/tests/nextcloud_tests.py index dffd4041f..30ba9bdc6 100755 --- a/tests/nextcloud_tests.py +++ b/tests/nextcloud_tests.py @@ -23,6 +23,7 @@ from selenium import webdriver from selenium.webdriver.common.by import By +from selenium.webdriver.firefox.service import Service from selenium.webdriver.firefox.webdriver import WebDriver from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support.ui import WebDriverWait @@ -179,7 +180,7 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: test.report("password", "Wrong password" not in driver.page_source, msg="Failed to login with provided password") test.new("settings config") - wait = WebDriverWait(driver, 60 * wait_multiplier) + wait = WebDriverWait(driver, 60 * wait_multiplier * 3) try: wait.until(VisibilityOfElementLocatedByAnyLocator([(By.CSS_SELECTOR, "#security-warning-state-ok"), (By.CSS_SELECTOR, "#security-warning-state-warning"), @@ -193,7 +194,8 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: warnings = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .warnings > li") for warning in warnings: - if re.match(r'.*Server has no maintenance window start time configured.*', warning.text): + if re.match(r'.*Server has no maintenance window start time configured.*', warning.text) \ + or re.match(r'.*Server has no maintenance window start time configured.*', warning.text): continue elif re.match(r'.*Could not check for JavaScript support.*', warning.text): continue @@ -213,7 +215,9 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: infos = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .info > li") for info in infos: if re.match(r'.*Your installation has no default phone region set.*', info.text) \ - or re.match(r'The PHP module "imagick" is not enabled', info.text): + or re.match(r'The PHP module "imagick" is not enabled', info.text) \ + or re.match(r'The PHP module "imagick" in this instance has no SVG support.*', info.text) \ + or re.match(r'\d+ warning in the logs since.*', info.text): continue else: print(f'INFO: {info.text}') @@ -234,6 +238,8 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: test.check(True) except Exception as e: + + print(driver.find_element(By.CSS_SELECTOR, "#security-warning").get_attribute("innerHTML")) test.check(e) close_first_run_wizard(driver, wait_multiplier) @@ -328,6 +334,13 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: skip_release_check = False options = webdriver.FirefoxOptions() + webdriver_exec_path = None + if 'GECKODRIVER_PATH' in os.environ: + print(f"Setting geckodriver from env ({os.environ['GECKODRIVER_PATH']})") + webdriver_exec_path = os.environ['GECKODRIVER_PATH'] + if 'FF_BINARY_PATH' in os.environ: + print(f"Setting firefox binary from env ({os.environ['FF_BINARY_PATH']}") + options.binary_location = os.environ['FF_BINARY_PATH'] wait_multiplier = 1 for opt, arg in opts: if opt in ('-h', '--help'): @@ -377,7 +390,10 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: print("Nextcloud tests " + tc.yellow + IP + tc.normal) print("---------------------------") - driver = webdriver.Firefox(options=options) + if webdriver_exec_path is None: + driver = webdriver.Firefox(options=options) + else: + driver = webdriver.Firefox(options=options, service=Service(webdriver_exec_path)) failed=False try: test_nextcloud(IP, nc_port, driver, skip_release_check, wait_multiplier) diff --git a/tests/requirements.txt b/tests/requirements.txt index f83fedc29..6f8089261 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,2 +1,2 @@ robotframework -selenium +selenium>=3.0.0,<4.0.0 diff --git a/tests/system_tests.py b/tests/system_tests.py index 9664c0fdf..2632369e1 100755 --- a/tests/system_tests.py +++ b/tests/system_tests.py @@ -20,9 +20,13 @@ import getopt import os import signal -from subprocess import run, getstatusoutput, PIPE, CompletedProcess +from subprocess import run as sp_run, getstatusoutput, PIPE, CompletedProcess from typing import Optional +def run(*args, **kwargs): + print("running command: " + " ".join(args[0])) + return sp_run(*args, **kwargs) + processes_must_be_running = [ 'apache2', 'cron', @@ -252,6 +256,8 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: if __name__ == "__main__": + sudo_prefix = ['sudo'] if os.environ.get('USE_SUDO', 'no') == 'yes' else [] + signal.signal(signal.SIGINT, signal_handler) # parse options @@ -290,23 +296,27 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: # detect if we are running this in a NCP instance try: - dockers_running = run(['docker', 'ps', '--format', '{{.Names}}'], stdout=PIPE).stdout.decode('utf-8') + dockers_running = run(sudo_prefix + ['docker', 'ps', '--format', '{{.Names}}'], stdout=PIPE).stdout.decode('utf-8') except: dockers_running = '' - lxc_command = ['lxc'] if 'USE_INCUS' not in os.environ or os.environ['USE_INCUS'] != 'yes' else ['incus'] + lxc_command = sudo_prefix + ['lxc'] if os.environ.get('USE_INCUS', 'no') != 'yes' else ['incus'] try: lxc_test = run(lxc_command + ['info'], stdout=PIPE, check=True) if lxc_test.returncode != 0: raise Exception(f"failed to execute {lxc_command} info") except: - try: - lxc_test = run(['sudo'] + lxc_command + ['info'], stdout=PIPE, check='True') - lxc_command = ['sudo'] + lxc_command - except: + if os.environ.get('USE_SUDO', 'no') == 'yes': lxc_command = None lxc_running = False + else: + try: + lxc_test = run(['sudo'] + lxc_command + ['info'], stdout=PIPE, check='True') + lxc_command = ['sudo'] + lxc_command + except: + lxc_command = None + lxc_running = False # detect if we are running this in a LXC instance if lxc_command is not None: @@ -316,7 +326,7 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: lxc_running = False try: - systemd_container_running = run(['machinectl', 'show', 'ncp'], stdout=PIPE, check = True) + systemd_container_running = run(sudo_prefix + ['machinectl', 'show', 'ncp'], stdout=PIPE, check = True) except: systemd_container_running = False @@ -326,12 +336,12 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: print(tc.brown + "* local NCP instance detected" + tc.normal) if not is_lxc(): binaries_must_be_installed = binaries_must_be_installed + binaries_no_docker - pre_cmd = [] + pre_cmd = sudo_prefix # docker method elif 'nextcloudpi' in dockers_running: print( tc.brown + "* local NCP docker instance detected" + tc.normal) - pre_cmd = ['docker', 'exec'] + pre_cmd = sudo_prefix + ['docker', 'exec'] if interactive: pre_cmd.append('-ti') pre_cmd.append('nextcloudpi') @@ -342,7 +352,7 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: pre_cmd = lxc_command + ['exec', 'ncp', '--'] elif systemd_container_running: - pre_cmd = ['systemd-run', '--wait', '-P', '--machine=ncp'] + pre_cmd = sudo_prefix + ['systemd-run', '--wait', '-P', '--machine=ncp'] # SSH method else: @@ -350,20 +360,20 @@ def set_cohorte_id(cohorte_id: int) -> CompletedProcess: print( tc.brown + "* No local NCP instance detected, trying SSH with " + tc.yellow + ssh_cmd + tc.normal + "...") binaries_must_be_installed = binaries_must_be_installed + binaries_no_docker - pre_cmd = ['ssh', '-o UserKnownHostsFile=/dev/null' , '-o PasswordAuthentication=no', + pre_cmd = sudo_prefix + ['ssh', '-o UserKnownHostsFile=/dev/null' , '-o PasswordAuthentication=no', '-o StrictHostKeyChecking=no', '-o ConnectTimeout=10', ssh_cmd[4:]] if not skip_ping: at_char = ssh_cmd.index('@') ip = ssh_cmd[at_char+1:] - ping_cmd = run(['ping', '-c1', '-w10', ip], stdout=PIPE, stderr=PIPE) + ping_cmd = run(sudo_prefix + ['ping', '-c1', '-w10', ip], stdout=PIPE, stderr=PIPE) if ping_cmd.returncode != 0: print(tc.red + "No connectivity to " + tc.yellow + ip + tc.normal) #sys.exit(1) ssh_test = run(pre_cmd + [':'], stdout=PIPE, stderr=PIPE) if ssh_test.returncode != 0: - ssh_copy = run(['ssh-copy-id', ssh_cmd[4:]], stderr=PIPE) + ssh_copy = run(sudo_prefix + ['ssh-copy-id', ssh_cmd[4:]], stderr=PIPE) if ssh_copy.returncode != 0: print(tc.red + "SSH connection failed" + tc.normal) sys.exit(1) From a7622ed9dcd516c2b373d8a0b83f67a2af75b264 Mon Sep 17 00:00:00 2001 From: Tobias <96661824+CrazyWolf13@users.noreply.github.com> Date: Sat, 18 Oct 2025 15:12:38 +0200 Subject: [PATCH 03/11] Update README to reflect community-scripts changes (#2068) --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cf21d7761..20567a9eb 100644 --- a/README.md +++ b/README.md @@ -138,21 +138,22 @@ and press "Download". Optionally, you can copy the corresponding md5 sum from the releases page and paste it in the "Checksum" field to have Proxmox check that the downloaded image was not corrupted -### 2. Installer by tteck +### 2. Installer by community-scripts (formerly tteck) -Use the [install script][ncp-proxmox-install-script-v5] from [tteck][tteck-profile] to install the LXC container on your Proxmox instance +Use the [install script][ncp-proxmox-install-script-v5] from [community-scripts][community-scripts-profile] to install the LXC container on your Proxmox instance -He has multiple helper scripts available for Proxmox on his [website][website-helper-scripts], do go have a look if you're using Proxmox. :+1: +[community-scripts][community-scripts-profile] has multiple helper scripts available for Proxmox on their [website][website-helper-scripts], go have a look if you're using Proxmox. :+1: -Installation: `bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nextcloudpi.sh)"` + +Installation: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/nextcloudpi.sh)"` Default Settings: `2GB RAM - 8GB Storage - 2vCPU` -_(Check his [website][website-helper-scripts] if this has changed and we haven't had the time to update it here yet, it's located under: Media - Photo > NextcloudPi LXC)_ +_(Check their [website][website-helper-scripts] if this has changed and we haven't had the time to update it here yet, it's located under: Operating-Systems > NextcloudPi LXC)_ -Thenk you [tteck][tteck-profile] :heart: for making the helper script & letting us use this for Proxmox installations :pray: +Thank you to the [community-scripts][community-scripts-profile] organisation :heart: for making the helper script & letting us use this for Proxmox installations :pray: -You can find his GitHub repository with his helper scripts [here][gh-helper-scripts-repo]. +You can find the GitHub repository with the helper scripts here: [here][gh-helper-scripts-repo]. ## How to build @@ -293,15 +294,15 @@ You can find us on the [Forum][nc-forum], [Telegram][chat-telegram] or [Matrix][ [nc-badge]: https://img.shields.io/badge/Nextcloud-0082C9?style=for-the-badge&logo=Nextcloud&logoColor=white - + -[tteck-profile]: https://github.com/tteck +[community-scripts-profile]: https://github.com/community-scripts/ -[gh-helper-scripts-repo]: https://github.com/tteck/Proxmox +[gh-helper-scripts-repo]: https://github.com/community-scripts/ProxmoxVE -[website-helper-scripts]: https://tteck.github.io/Proxmox/ +[website-helper-scripts]: https://community-scripts.github.io/ProxmoxVE/ -[ncp-proxmox-install-script-v5]: https://github.com/tteck/Proxmox/blob/main/install/nextcloudpi-v5-install.sh +[ncp-proxmox-install-script-v5]: https://github.com/community-scripts/ProxmoxVE/blob/main/install/nextcloudpi-install.sh From 934039e28b869cf93f9a3df67b8cc65e7aea0cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 15:25:10 +0200 Subject: [PATCH 04/11] nextcloud-domain.sh: Minor syntax improvment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Knöppler <6317548+theCalcaholic@users.noreply.github.com> --- bin/nextcloud-domain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nextcloud-domain.sh b/bin/nextcloud-domain.sh index ffc9d86f2..e66729953 100644 --- a/bin/nextcloud-domain.sh +++ b/bin/nextcloud-domain.sh @@ -14,7 +14,7 @@ while :; do pub_ipv4="$(curl -4 -m4 icanhazip.com 2>/dev/null)" pub_ipv6="$(curl -6 -m4 icanhazip.com 2>/dev/null)" - [[ "$pub_ipv4" != "" ]] && ncc config:system:set trusted_domains 11 --value="$pub_ipv4" + [[ -z "$pub_ipv4" ]] || ncc config:system:set trusted_domains 11 --value="$pub_ipv4" [[ "$pub_ipv6" != "" ]] && ncc config:system:set trusted_domains 12 --value="[$pub_ipv6]" [[ "$local_ip" != "" ]] && break From 6a02ab45defa16f7b9c9eee04a2bb806c7bb7968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 15:25:26 +0200 Subject: [PATCH 05/11] nextcloud-domain.sh: Minor syntax improvment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Knöppler <6317548+theCalcaholic@users.noreply.github.com> --- bin/nextcloud-domain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nextcloud-domain.sh b/bin/nextcloud-domain.sh index e66729953..718b7fac0 100644 --- a/bin/nextcloud-domain.sh +++ b/bin/nextcloud-domain.sh @@ -15,7 +15,7 @@ while :; do pub_ipv4="$(curl -4 -m4 icanhazip.com 2>/dev/null)" pub_ipv6="$(curl -6 -m4 icanhazip.com 2>/dev/null)" [[ -z "$pub_ipv4" ]] || ncc config:system:set trusted_domains 11 --value="$pub_ipv4" - [[ "$pub_ipv6" != "" ]] && ncc config:system:set trusted_domains 12 --value="[$pub_ipv6]" + [[ -z "$pub_ipv6" ]] || ncc config:system:set trusted_domains 12 --value="[$pub_ipv6]" [[ "$local_ip" != "" ]] && break From 6d0f9bc7901195301faa3737cb4b6afe0e2d8d8a Mon Sep 17 00:00:00 2001 From: Tommy He Date: Sat, 20 Sep 2025 16:43:09 +0800 Subject: [PATCH 06/11] #2069: Apply fix for notify_push reinstall during Nextcloud updates --- bin/ncp-update-nc.d/update-nc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ncp-update-nc.d/update-nc.sh b/bin/ncp-update-nc.d/update-nc.sh index ade4393e7..5f057c9d4 100755 --- a/bin/ncp-update-nc.d/update-nc.sh +++ b/bin/ncp-update-nc.d/update-nc.sh @@ -144,7 +144,7 @@ cp -raT nextcloud-old/themes/ nextcloud/themes/ # copy old NCP apps #################### -for app in nextcloudpi previewgenerator; do +for app in nextcloudpi previewgenerator notify_push; do if [[ -d nextcloud-old/apps/"${app}" ]]; then cp -r -L nextcloud-old/apps/"${app}" /var/www/nextcloud/apps/ fi From be9d8d58979b6b68cdcffe3c365649e1f9ea4eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 18:50:04 +0200 Subject: [PATCH 07/11] Add support for NC 32 --- etc/ncp-config.d/nc-nextcloud.cfg | 2 +- etc/ncp.cfg | 2 +- ncp-app/appinfo/info.xml | 2 +- ncp-previewgenerator/ncp-previewgenerator-nc21/appinfo/info.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/ncp-config.d/nc-nextcloud.cfg b/etc/ncp-config.d/nc-nextcloud.cfg index aaa39fb97..40ed11158 100644 --- a/etc/ncp-config.d/nc-nextcloud.cfg +++ b/etc/ncp-config.d/nc-nextcloud.cfg @@ -9,7 +9,7 @@ { "id": "VER", "name": "Version", - "value": "31.0.2" + "value": "32.0.0" }, { "id": "MAXFILESIZE", diff --git a/etc/ncp.cfg b/etc/ncp.cfg index 5c30ba3d5..3e681bbcb 100644 --- a/etc/ncp.cfg +++ b/etc/ncp.cfg @@ -1,5 +1,5 @@ { - "nextcloud_version": "31.0.2", + "nextcloud_version": "32.0.0", "php_version": "8.3", "release": "bookworm" } diff --git a/ncp-app/appinfo/info.xml b/ncp-app/appinfo/info.xml index a3040d3a1..167b8371d 100644 --- a/ncp-app/appinfo/info.xml +++ b/ncp-app/appinfo/info.xml @@ -12,7 +12,7 @@ tools https://github.com/nextcloud/nextcloudpi/issues - + diff --git a/ncp-previewgenerator/ncp-previewgenerator-nc21/appinfo/info.xml b/ncp-previewgenerator/ncp-previewgenerator-nc21/appinfo/info.xml index e7a25109f..84b3abfb6 100644 --- a/ncp-previewgenerator/ncp-previewgenerator-nc21/appinfo/info.xml +++ b/ncp-previewgenerator/ncp-previewgenerator-nc21/appinfo/info.xml @@ -25,7 +25,7 @@ The first time you install this app, before using a cron job, you properly want - + From 9c8414d7858251476a272abbd3ead2546944ad5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 19:04:35 +0200 Subject: [PATCH 08/11] Temporarily skip installation of tasks app --- bin/ncp/CONFIG/nc-init.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/ncp/CONFIG/nc-init.sh b/bin/ncp/CONFIG/nc-init.sh index 2445b7ede..f467b3220 100644 --- a/bin/ncp/CONFIG/nc-init.sh +++ b/bin/ncp/CONFIG/nc-init.sh @@ -165,8 +165,8 @@ EOF ncc app:enable contacts ncc app:install notes ncc app:enable notes - ncc app:install tasks - ncc app:enable tasks + #ncc app:install tasks + #ncc app:enable tasks # we handle this ourselves ncc app:disable updatenotification From 546904d221a988ffe892841644012b409fda9a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 21:03:22 +0200 Subject: [PATCH 09/11] Disable app_api unless configured --- bin/ncp/CONFIG/nc-init.sh | 3 +++ updates/1.56.0.sh | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 updates/1.56.0.sh diff --git a/bin/ncp/CONFIG/nc-init.sh b/bin/ncp/CONFIG/nc-init.sh index f467b3220..bfe8ca81d 100644 --- a/bin/ncp/CONFIG/nc-init.sh +++ b/bin/ncp/CONFIG/nc-init.sh @@ -171,6 +171,9 @@ EOF # we handle this ourselves ncc app:disable updatenotification + # Not supported in Nextcloudpi without manual setup + ncc app:disable app_api + # ncp-previewgenerator local ncver ncver="$(ncc status 2>/dev/null | grep "version:" | awk '{ print $3 }')" diff --git a/updates/1.56.0.sh b/updates/1.56.0.sh new file mode 100644 index 000000000..6466a2d94 --- /dev/null +++ b/updates/1.56.0.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +if ncc app_api:daemon:list | grep 'No registered daemon configs.' > /dev/null 2>&1 +then + ncc app:disable app_api +fi + +exit 0 \ No newline at end of file From 5fde45991c15571911ca9e156bf7afa8e1a581b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 21:03:39 +0200 Subject: [PATCH 10/11] nextcloud_tests.py: Fix config checks for NC32 --- tests/nextcloud_tests.py | 156 ++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 59 deletions(-) diff --git a/tests/nextcloud_tests.py b/tests/nextcloud_tests.py index 30ba9bdc6..7c4b65cea 100755 --- a/tests/nextcloud_tests.py +++ b/tests/nextcloud_tests.py @@ -181,66 +181,12 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: test.new("settings config") wait = WebDriverWait(driver, 60 * wait_multiplier * 3) - try: - wait.until(VisibilityOfElementLocatedByAnyLocator([(By.CSS_SELECTOR, "#security-warning-state-ok"), - (By.CSS_SELECTOR, "#security-warning-state-warning"), - (By.CSS_SELECTOR, "#security-warning-state-error"), - (By.CSS_SELECTOR, "#security-warning-state-failure")])) - - element_ok = driver.find_element(By.ID, "security-warning-state-ok") - element_warn = driver.find_element(By.ID, "security-warning-state-warning") - - if element_warn.is_displayed(): - - warnings = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .warnings > li") - for warning in warnings: - if re.match(r'.*Server has no maintenance window start time configured.*', warning.text) \ - or re.match(r'.*Server has no maintenance window start time configured.*', warning.text): - continue - elif re.match(r'.*Could not check for JavaScript support.*', warning.text): - continue - # TODO: Solve redis error logs at the source - elif re.match(r'.*\d+ errors? in the logs since.*', warning.text): - continue - else: - raise ConfigTestFailure(f"WARN: {warning.text}") - - if driver.find_element(By.CSS_SELECTOR, "#postsetupchecks > .errors").is_displayed(): - try: - first_error = driver.find_element(By.CSS_SELECTOR, "#postsetupchecks > .errors > li") - except NoSuchElementException: - first_error = None - raise ConfigTestFailure(f"ERROR: {first_error.text if first_error is not None else 'unexpected error'}") - - infos = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .info > li") - for info in infos: - if re.match(r'.*Your installation has no default phone region set.*', info.text) \ - or re.match(r'The PHP module "imagick" is not enabled', info.text) \ - or re.match(r'The PHP module "imagick" in this instance has no SVG support.*', info.text) \ - or re.match(r'\d+ warning in the logs since.*', info.text): - continue - else: - print(f'INFO: {info.text}') - php_modules = info.find_elements(By.CSS_SELECTOR, "li") - if len(php_modules) != 1: - raise ConfigTestFailure(f"Could not find the list of php modules within the info message " - f"'{infos[0].text}'") - if php_modules[0].text != "imagick": - raise ConfigTestFailure("The list of php_modules does not equal [imagick]") - - elif not element_ok.is_displayed(): - errors = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .errors > li") - for error in errors: - print(f'ERROR: {error.text}') - raise ConfigTestFailure("Neither the warnings nor the ok status is displayed " - "(so there are probably errors or the page is broken)") - - test.check(True) + secwarn = driver.find_element(By.CSS_SELECTOR, "#security-warning.settings-section") + if secwarn is None: + settings_config_check_pre32(wait, test) + else: + settings_config_check(wait, test) - except Exception as e: - - print(driver.find_element(By.CSS_SELECTOR, "#security-warning").get_attribute("innerHTML")) - test.check(e) close_first_run_wizard(driver, wait_multiplier) @@ -321,6 +267,98 @@ def test_nextcloud(IP: str, nc_port: str, driver: WebDriver, skip_release_check: except Exception as e: test.check(e) +def settings_config_check_warnings(warnings): + for warning in warnings: + if re.match(r'.*Server has no maintenance window start time configured.*', warning.text) \ + or re.match(r'.*Server has no maintenance window start time configured.*', warning.text): + continue + elif re.match(r'.*Could not check for JavaScript support.*', warning.text): + continue + # TODO: Solve redis error logs at the source + elif re.match(r'.*\d+ errors? in the logs since.*', warning.text): + continue + else: + raise ConfigTestFailure(f"WARN: {warning.text}") + +def settings_config_check_infos(infos): + for info in infos: + if re.match(r'.*Your installation has no default phone region set.*', info.text) \ + or re.match(r'The PHP module "imagick" is not enabled', info.text) \ + or re.match(r'The PHP module "imagick" in this instance has no SVG support.*', info.text) \ + or re.match(r'\d+ warnings? in the logs since.*', info.text): + continue + else: + print(f'INFO: {info.text}') + php_modules = info.find_elements(By.CSS_SELECTOR, "li") + if len(php_modules) != 1: + raise ConfigTestFailure(f"Could not find the list of php modules within the info message " + f"'{infos[0].text}'") + if php_modules[0].text != "imagick": + raise ConfigTestFailure("The list of php_modules does not equal [imagick]") + + +def settings_config_check_errors(errors): + if len(errors) == 0: + return + for error in errors: + print(f'ERROR: {error.text}') + raise ConfigTestFailure("Neither the warnings nor the ok status is displayed " + "(so there are probably errors or the page is broken)") + + +def settings_config_check(wait, test): + try: + wait.until_not(VisibilityOfElementLocatedByAnyLocator([(By.CSS_SELECTOR, "#security-warning .loading-icon")])) + warnings = driver.find_elements(By.CSS_SELECTOR, "#security-warning li.settings-setup-checks-item--warning .settings-setup-checks-item__description") + settings_config_check_warnings(warnings) + infos = driver.find_elements(By.CSS_SELECTOR, "#security-warning li.settings-setup-checks-item--info .settings-setup-checks-item__description") + settings_config_check_infos(infos) + errors = driver.find_elements(By.CSS_SELECTOR, "#security-warning li.settings-setup-checks-item--error .settings-setup-checks-item__description") + settings_config_check_errors(errors) + + test.check(True) + except Exception as e: + print(driver.find_element(By.CSS_SELECTOR, "#security-warning").get_attribute("innerHTML")) + test.check(e) + + +def settings_config_check_pre32(wait, test): + try: + wait.until(VisibilityOfElementLocatedByAnyLocator([(By.CSS_SELECTOR, "#security-warning-state-ok"), + (By.CSS_SELECTOR, "#security-warning-state-warning"), + (By.CSS_SELECTOR, "#security-warning-state-error"), + (By.CSS_SELECTOR, "#security-warning-state-failure")])) + + element_ok = driver.find_element(By.ID, "security-warning-state-ok") + element_warn = driver.find_element(By.ID, "security-warning-state-warning") + + if element_warn.is_displayed(): + + warnings = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .warnings > li") + settings_config_check_warnings(warnings) + + if driver.find_element(By.CSS_SELECTOR, "#postsetupchecks > .errors").is_displayed(): + try: + first_error = driver.find_element(By.CSS_SELECTOR, "#postsetupchecks > .errors > li") + except NoSuchElementException: + first_error = None + raise ConfigTestFailure(f"ERROR: {first_error.text if first_error is not None else 'unexpected error'}") + + infos = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .info > li") + settings_config_check_infos(infos) + + + elif not element_ok.is_displayed(): + errors = driver.find_elements(By.CSS_SELECTOR, "#postsetupchecks > .errors > li") + settings_config_check_errors(errors) + + test.check(True) + + except Exception as e: + + print(driver.find_element(By.CSS_SELECTOR, "#security-warning").get_attribute("innerHTML")) + test.check(e) + if __name__ == "__main__": signal.signal(signal.SIGINT, signal_handler) From fdcd06ade5edae0c73135338846536a0083d5b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6ppler?= <6317548+theCalcaholic@users.noreply.github.com> Date: Sat, 18 Oct 2025 21:27:23 +0200 Subject: [PATCH 11/11] Set supported NC version to 32.0.1 and reenable tasks app --- bin/ncp/CONFIG/nc-init.sh | 4 ++-- etc/ncp-config.d/nc-nextcloud.cfg | 2 +- etc/ncp.cfg | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/ncp/CONFIG/nc-init.sh b/bin/ncp/CONFIG/nc-init.sh index bfe8ca81d..3d7503e34 100644 --- a/bin/ncp/CONFIG/nc-init.sh +++ b/bin/ncp/CONFIG/nc-init.sh @@ -165,8 +165,8 @@ EOF ncc app:enable contacts ncc app:install notes ncc app:enable notes - #ncc app:install tasks - #ncc app:enable tasks + ncc app:install tasks + ncc app:enable tasks # we handle this ourselves ncc app:disable updatenotification diff --git a/etc/ncp-config.d/nc-nextcloud.cfg b/etc/ncp-config.d/nc-nextcloud.cfg index 40ed11158..7117926fc 100644 --- a/etc/ncp-config.d/nc-nextcloud.cfg +++ b/etc/ncp-config.d/nc-nextcloud.cfg @@ -9,7 +9,7 @@ { "id": "VER", "name": "Version", - "value": "32.0.0" + "value": "32.0.1" }, { "id": "MAXFILESIZE", diff --git a/etc/ncp.cfg b/etc/ncp.cfg index 3e681bbcb..53f461542 100644 --- a/etc/ncp.cfg +++ b/etc/ncp.cfg @@ -1,5 +1,5 @@ { - "nextcloud_version": "32.0.0", + "nextcloud_version": "32.0.1", "php_version": "8.3", "release": "bookworm" }