From 27ead520785550fb7027ced9bd7c7510c92348a3 Mon Sep 17 00:00:00 2001 From: Steven Briscoe Date: Mon, 28 Nov 2022 23:26:33 +1000 Subject: [PATCH] Nextcloud: Migrate from v22 to v25 (#311) --- nextcloud/docker-compose.yml | 5 +- nextcloud/hooks/pre-start | 150 +++++++++++++++++++++++++++++++++++ nextcloud/umbrel-app.yml | 7 +- 3 files changed, 158 insertions(+), 4 deletions(-) create mode 100755 nextcloud/hooks/pre-start diff --git a/nextcloud/docker-compose.yml b/nextcloud/docker-compose.yml index 804caaa..5f3ec9b 100644 --- a/nextcloud/docker-compose.yml +++ b/nextcloud/docker-compose.yml @@ -34,7 +34,7 @@ services: ipv4_address: $APP_NEXTCLOUD_REDIS_IP web: - image: nextcloud:22.2.10-apache@sha256:71c4fb75d7c035ea2c840ebc1adf0da144b0c69e39ce925f4a2ea84b7c06db18 + image: nextcloud:25.0.1-apache@sha256:a200319b132c01ec3486e0dcaf052092b560ec30ac9b78115607696dd201f704 # Currently needs to be run as root, if we run as uid 1000 this fails # https://github.com/nextcloud/docker/blob/05026b029d37fc5cd488d4a4a2a79480e39841ba/21.0/apache/entrypoint.sh#L53-L77 # user: "1000:1000" @@ -47,6 +47,7 @@ services: - MYSQL_PASSWORD=moneyprintergobrrr - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud + - TRUSTED_PROXIES="${NETWORK_IP}/16" - NEXTCLOUD_ADMIN_USER=umbrel - NEXTCLOUD_ADMIN_PASSWORD=${APP_PASSWORD} - NEXTCLOUD_TRUSTED_DOMAINS=${APP_DOMAIN}:${APP_NEXTCLOUD_PORT} ${APP_HIDDEN_SERVICE} ${DEVICE_HOSTNAME}:${APP_NEXTCLOUD_PORT} ${APP_NEXTCLOUD_LOCAL_IPS} @@ -59,7 +60,7 @@ services: ipv4_address: $APP_NEXTCLOUD_IP cron: - image: nextcloud:22.2.10-apache@sha256:71c4fb75d7c035ea2c840ebc1adf0da144b0c69e39ce925f4a2ea84b7c06db18 + image: nextcloud:25.0.1-apache@sha256:a200319b132c01ec3486e0dcaf052092b560ec30ac9b78115607696dd201f704 # Currently needs to be run as root, if we run as uid 1000 this fails # https://github.com/nextcloud/docker/blob/05026b029d37fc5cd488d4a4a2a79480e39841ba/21.0/apache/entrypoint.sh#L53-L77 # user: "1000:1000" diff --git a/nextcloud/hooks/pre-start b/nextcloud/hooks/pre-start new file mode 100755 index 0000000..67f1c17 --- /dev/null +++ b/nextcloud/hooks/pre-start @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +set -euo pipefail + +APP_DATA_DIR="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/..)" +UMBREL_ROOT="${APP_DATA_DIR}/../.." + +CONFIG_PHP_FILE="${APP_DATA_DIR}/data/nextcloud/config/config.php" + +APP_COMPOSE_FILE="${APP_DATA_DIR}/docker-compose.yml" +APP_COMPOSE_BACKUP_FILE="${APP_DATA_DIR}/docker-compose.yml.bak" + +# Supported list of Nextcloud migrations +VERSIONS=() +VERSIONS+=( "22.1.1.2" ) +VERSIONS+=( "22.2.10.2" ) +VERSIONS+=( "23.0.11.1" ) +VERSIONS+=( "24.0.7.1" ) +VERSIONS+=( "25.0.1.1" ) + +IMAGES=() +IMAGES+=( "nextcloud:22.1.1-apache@sha256:99d94124b2024c9f7f38dc12144a92bc0d68d110bcfd374169ebb7e8df0adf8e" ) +IMAGES+=( "nextcloud:22.2.10-apache@sha256:71c4fb75d7c035ea2c840ebc1adf0da144b0c69e39ce925f4a2ea84b7c06db18" ) +IMAGES+=( "nextcloud:23.0.11-apache@sha256:671ed70c7b204c63cb56d5c0d5dd624abec5eadeacd492191e65e834ddffef26" ) +IMAGES+=( "nextcloud:24.0.7-apache@sha256:f95a21b598b7470b788251db5b0bbe9516992fdb865e7a8978980585e36eb715" ) +IMAGES+=( "nextcloud:25.0.1-apache@sha256:a200319b132c01ec3486e0dcaf052092b560ec30ac9b78115607696dd201f704" ) + +find_index() { + local -r value="${1}" + shift + local -r array=("$@") + + for i in "${!array[@]}"; do + if [[ "${array[$i]}" == "${value}" ]]; then + echo $i + exit + fi + done + + echo -1 +} + +wait_for_value_in_file () { + local -r file="${1}" + local -r str="${2}" + local -r max_seconds="${3}" + + echo "Searching for '${str}' inside: ${file}" + + for i in $(seq 1 "${max_seconds}"); do + echo "Attempt: ${i}" + if cat "${file}" | grep --quiet "${str}"; then + return + fi + sleep 1 + done + + echo "Failed after ${max_seconds} seconds to find '${str}' inside: ${file}" + exit 1 +} + +check_compose_file () { + local -r image="${1}" + + web_image=$(cat "${APP_COMPOSE_FILE}" 2> /dev/null | yq '.services.web.image' || true) + cron_image=$(cat "${APP_COMPOSE_FILE}" 2> /dev/null | yq '.services.cron.image' || true) + + if [[ "${web_image}" != "${image}" ]] || [[ "${cron_image}" != "${image}" ]]; then + echo "The docker-compose.yml now looks bad. Restoring..." + + mv "${APP_COMPOSE_BACKUP_FILE}" "${APP_COMPOSE_FILE}" + + exit + fi +} + +get_version() { + cat "${CONFIG_PHP_FILE}" | grep "'version'[[:space:]]=>[[:space:]]" | awk -F"'" '{print $4}' +} + +# If a Nextcloud config file does not yet exist +# Then it's likely a new install +# Therefore there is nothing to do +if [[ ! -f "${CONFIG_PHP_FILE}" ]]; then + exit +fi + +nextcloud_version=$(get_version) + +echo "Active Nextcloud Version: ${nextcloud_version}" + +# Check if active version is in migration list +active_version_idx=$(find_index "${nextcloud_version}" "${VERSIONS[@]}") +if [[ "${active_version_idx}" == "-1" ]]; then + echo "Active version is not supported in the list of migrations" + exit +fi + +# Check if already up to date +if [[ "${VERSIONS[-1]}" == "${nextcloud_version}" ]]; then + echo "Nextcloud is up-to-date" + exit +fi + +# Loop through versions, ignoring past versions +for i in "${!VERSIONS[@]}"; do + [[ "${i}" -le "${active_version_idx}" ]] && continue + + version="${VERSIONS[$i]}" + image="${IMAGES[$i]}" + + echo "Migrating to: ${version} (${image})" + echo + + cp --archive "${APP_COMPOSE_FILE}" "${APP_COMPOSE_BACKUP_FILE}" + + yq -i ".services.web.image = \"${image}\"" "${APP_COMPOSE_FILE}" + yq -i ".services.cron.image = \"${image}\"" "${APP_COMPOSE_FILE}" + + check_compose_file "${image}" + + nextcloud_version=$(get_version) + sed -i "s/${nextcloud_version}/${nextcloud_version}-patch/" "${CONFIG_PHP_FILE}" + + "${UMBREL_ROOT}/scripts/app" start nextcloud + + echo "Waiting for update to complete..." + + # Wait for Nextcloud to enter maintenance mode + # Indicating their update process has started + wait_for_value_in_file "${CONFIG_PHP_FILE}" "'maintenance'[[:space:]]=>[[:space:]]true" 300 + + # Wait for Nextcloud to exit maintenance mode + # Indicating their update process has finished + wait_for_value_in_file "${CONFIG_PHP_FILE}" "'maintenance'[[:space:]]=>[[:space:]]false" 300 + + "${UMBREL_ROOT}/scripts/app" stop nextcloud + + # Delete image of intermediate version + # Unless it's the latest image + # Otherwise it will have to be re-downloaded + if [[ "${version}" != "${VERSIONS[-1]}" ]]; then + echo "Deleting intermediary image: ${image}" + + docker rmi "${image}" || true + fi +done + +rm -rf "${APP_COMPOSE_BACKUP_FILE}" + +echo "Migration completed successfully" diff --git a/nextcloud/umbrel-app.yml b/nextcloud/umbrel-app.yml index 084a4a2..e996ef6 100644 --- a/nextcloud/umbrel-app.yml +++ b/nextcloud/umbrel-app.yml @@ -2,7 +2,7 @@ manifestVersion: 1.1 id: nextcloud category: Files name: Nextcloud -version: "22.2.10-build-2" +version: "25.0.1" tagline: Productivity platform that keeps you in control description: >- Nextcloud puts your data at your fingertips, under your control. @@ -25,7 +25,10 @@ description: >- Note: After logging in to Nextcloud please change the password to something secure before sharing the address with anyone. releaseNotes: >- - - Increase upload limit to 1TB + ⚠️ This update may take a while. It migrates Nextcloud from v22 to v25 and can take several minutes depending on your Internet connection speed, your server hardware, and how many files you have stored in Nextcloud. + + + - Full changelog can be found here: https://nextcloud.com/changelog/ developer: Nextcloud GmbH website: https://nextcloud.com dependencies: []