Merge pull request #2083 from nextcloud/devel

NC 32 and fixes
This commit is contained in:
Tobias Knöppler 2025-11-19 10:03:07 +01:00 committed by GitHub
commit 7be2748648
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 266 additions and 131 deletions

View File

@ -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 }}
@ -355,7 +356,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
@ -364,11 +365,12 @@ 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
@ -386,6 +388,7 @@ jobs:
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: |
@ -419,6 +422,9 @@ 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 }' &
../.venv/bin/python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
echo "Activation test failed!"
@ -444,6 +450,12 @@ jobs:
}
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
}
@ -473,13 +485,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
@ -500,6 +512,8 @@ jobs:
- name: Test LXD Image
working-directory: ./tests
run: |
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:"
@ -579,6 +593,9 @@ 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 }' &
../.venv/bin/python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
echo "Nextcloud test failed!"
@ -619,16 +636,17 @@ 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
@ -646,6 +664,7 @@ jobs:
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: |
@ -682,6 +701,9 @@ 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 }' &
../.venv/bin/python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
echo "Activation test failed!"

View File

@ -155,11 +155,12 @@ jobs:
run: |
set -ex
mkdir -p output
wget -nv "${{ inputs.test_image_url }}" | pv -i 3 > "output/${ARTIFACT_FILE?}"
sudo apt-get install -y pv
wget -nv "${{ inputs.test_image_url }}" -O - | pv -n --bytes --rate --timer -i 3 > "output/${ARTIFACT_FILE?}"
- name: Prepare test
run: |
set -x
mv output/${ARTIFACT_FILE?} ncp.img
mv "output/${ARTIFACT_FILE?}" ncp.img
sudo apt-get install -y systemd-container
python3 -m venv ./.venv
. ./.venv/bin/activate

View File

@ -43,7 +43,7 @@ jobs:
run: |
set -ex
mkdir -p publish
mv artifacts/${{ inputs.artifact_file }} publish/
mv "artifacts/${{ inputs.artifact_file }}" publish/
cd publish
asset="${IMG}"

View File

@ -63,26 +63,17 @@ jobs:
git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
secrets: inherit
raspberrypi-4:
raspberrypi:
if: ${{ 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 }}"
board_id: rpi4b
board_name: RaspberryPi4
secrets: inherit
raspberrypi-5:
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 }}"
board_id: rpi5b
board_name: RaspberryPi5
board_name: RaspberryPi 4+
secrets: inherit
armbian-test-image:
if: ${{ inputs.test_image_url != '' || ( github.event_name != 'workflow_dispatch' && !startsWith(github.ref_name, 'docker-') ) }}
if: ${{ inputs.test_image_url != '' }}
uses: ./.github/workflows/build-sd-images.yml
with:
git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
@ -216,31 +207,19 @@ jobs:
artifact_file: "${{ needs.lxd-arm64.outputs.lxc_artifact_file }}"
dry_run: ${{ (!inputs.release && github.event_name == 'workflow_dispatch') || github.ref_type != 'tag' || !(github.ref_protected || startsWith(github.ref, 'refs/tags/v')) }}
raspberrypi-4-release:
raspberrypi-release:
needs:
- raspberrypi-4
- raspberrypi
- github-release
if: ${{ inputs.sd-images || github.event_name != 'workflow_dispatch' }}
uses: ./.github/workflows/publish-image.yml
with:
git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
artifact_id: "${{ needs.raspberrypi-4.outputs.artifact_name }}"
artifact_file: "${{ needs.raspberrypi-4.outputs.artifact_file }}"
artifact_id: "${{ needs.raspberrypi.outputs.artifact_name }}"
artifact_file: "${{ needs.raspberrypi.outputs.artifact_file }}"
dry_run: ${{ (!inputs.release && github.event_name == 'workflow_dispatch') || github.ref_type != 'tag' || !(github.ref_protected || startsWith(github.ref, 'refs/tags/v')) }}
secrets: inherit
raspberrypi-5-release:
needs:
- raspberrypi-5
- github-release
if: ${{ inputs.sd-images || github.event_name != 'workflow_dispatch' }}
uses: ./.github/workflows/publish-image.yml
with:
git_ref: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
artifact_id: "${{ needs.raspberrypi-5.outputs.artifact_name }}"
artifact_file: "${{ needs.raspberrypi-5.outputs.artifact_file }}"
dry_run: ${{ (!inputs.release && github.event_name == 'workflow_dispatch') || github.ref_type != 'tag' || !(github.ref_protected || startsWith(github.ref, 'refs/tags/v')) }}
secrets: inherit
odroidxu4-release:
needs:
- odroidxu4

View File

@ -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 -->
<!-- COMMUNITY-SCRIPTS -->
[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
<!-- IMAGES -->

View File

@ -82,5 +82,13 @@ EOF
cat /usr/local/etc/instance.cfg
}
systemctl is-enabled -q nextcloud-ai-worker@1.service || {
max="$(nproc || echo '2')"
max="$((max-1))"
for i in $(seq 1 "$max")
do
systemctl enable --now "nextcloud-ai-worker@${i}.service"
done
}
exit 0

View File

@ -142,11 +142,12 @@ cp nextcloud-old/config/config.php nextcloud/config/
####################
cp -raT nextcloud-old/themes/ nextcloud/themes/
# copy old NCP apps
# copy old NC apps
####################
for app in nextcloudpi previewgenerator; do
if [[ -d nextcloud-old/apps/"${app}" ]]; then
cp -r -L nextcloud-old/apps/"${app}" /var/www/nextcloud/apps/
for app in nextcloud-old/apps/*; do
if ! [[ -d /var/www/nextcloud/apps/"$(basename "$app")" ]]
then
cp -r -L "${app}" /var/www/nextcloud/apps/
fi
done
@ -195,7 +196,12 @@ $ncc | grep -q db:add-missing-indices && $ncc db:add-missing-indices -n
$ncc | grep -q db:add-missing-columns && $ncc db:add-missing-columns -n
$ncc | grep -q db:add-missing-primary-keys && $ncc db:add-missing-primary-keys -n
$ncc | grep -q db:convert-filecache-bigint && $ncc db:convert-filecache-bigint -n
$ncc | grep -q db:convert-mysql-charset && $ncc db:convert-mysql-charset -n
$ncc maintenance:repair --help | grep -q -e '--include-expensive' && $ncc maintenance:repair --include-expensive
if $ncc app_api:daemon:list | grep 'No registered daemon configs.' > /dev/null 2>&1
then
$ncc app:disable app_api
fi
# use the correct version for custom apps
NCVER="$(nc_version)"

View File

@ -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 }')"

View File

@ -83,6 +83,25 @@ EOF
update-rc.d redis-server enable
clear_opcache
# NC service workers
cat > /etc/systemd/system/nextcloud-ai-worker@.service <<'EOF'
[Unit]
Description=Nextcloud AI worker %i
After=network.target
[Service]
ExecStart=php occ background-job:worker -t 60 'OC\\TaskProcessing\\SynchronousBackgroundJob'
Restart=always
StartLimitInterval=60
StartLimitBurst=10
WorkingDirectory=/var/www/nextcloud
User=www-data
[Install]
WantedBy=multi-user.target
EOF
# service to randomize passwords on first boot
mkdir -p /usr/lib/systemd/system
cat > /usr/lib/systemd/system/nc-provisioning.service <<'EOF'

View File

@ -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)"
[[ -z "$pub_ipv4" ]] || ncc config:system:set trusted_domains 11 --value="$pub_ipv4"
[[ -z "$pub_ipv6" ]] || ncc config:system:set trusted_domains 12 --value="[$pub_ipv6]"
[[ "$local_ip" != "" ]] && break
sleep 3

View File

@ -9,7 +9,7 @@
{
"id": "VER",
"name": "Version",
"value": "31.0.2"
"value": "32.0.1"
},
{
"id": "MAXFILESIZE",

View File

@ -1,5 +1,5 @@
{
"nextcloud_version": "31.0.2",
"nextcloud_version": "32.0.1",
"php_version": "8.3",
"release": "bookworm"
}

View File

@ -12,7 +12,7 @@
<category>tools</category>
<bugs>https://github.com/nextcloud/nextcloudpi/issues</bugs>
<dependencies>
<nextcloud min-version="22" max-version="31"/>
<nextcloud min-version="22" max-version="32"/>
</dependencies>
<navigations>
<navigation>

View File

@ -25,7 +25,7 @@ The first time you install this app, before using a cron job, you properly want
</types>
<dependencies>
<php min-version="7.2"/>
<nextcloud min-version="20" max-version="31" />
<nextcloud min-version="20" max-version="32" />
</dependencies>
<commands>

View File

@ -23,6 +23,7 @@ import signal
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 @@ if __name__ == "__main__":
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 @@ if __name__ == "__main__":
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
#

View File

@ -23,6 +23,7 @@ from pathlib import Path
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,66 +180,12 @@ 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 * 3)
wait = WebDriverWait(driver, 60 * wait_multiplier * 5)
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):
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'1 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)
except Exception as e:
print(driver.find_element(By.CSS_SELECTOR, "#security-warning").get_attribute("innerHTML"))
test.check(e)
wait.until(VisibilityOfElementLocatedByAnyLocator([(By.CSS_SELECTOR, "#security-warning.settings-section")]))
settings_config_check(wait, test)
except TimeoutException:
settings_config_check_pre32(wait, test)
close_first_run_wizard(driver, wait_multiplier)
@ -319,6 +266,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)
@ -332,6 +371,13 @@ if __name__ == "__main__":
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'):
@ -381,7 +427,10 @@ if __name__ == "__main__":
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)

View File

@ -1,2 +1,2 @@
robotframework
selenium
selenium>=3.0.0,<4.0.0

View File

@ -51,7 +51,7 @@ binaries_no_docker = [
'btrfs',
'fail2ban-server',
'udiskie',
'ufw'
'ufw',
'samba',
]

31
updates/1.56.0.sh Normal file
View File

@ -0,0 +1,31 @@
#!/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
cat > /etc/systemd/system/nextcloud-ai-worker@.service <<'EOF'
[Unit]
Description=Nextcloud AI worker %i
After=network.target
[Service]
ExecStart=php occ background-job:worker -t 60 'OC\\TaskProcessing\\SynchronousBackgroundJob'
Restart=always
StartLimitInterval=60
StartLimitBurst=10
WorkingDirectory=/var/www/nextcloud
User=www-data
[Install]
WantedBy=multi-user.target
EOF
max="$(nproc || echo '2')"
max="$((max-1))"
for i in $(seq 1 "$max")
do
systemctl enable --now "nextcloud-ai-worker@${i}.service"
done
exit 0