From 809ad7aa9d63ca7d21375874660fe56385938bfc Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 25 Oct 2020 14:55:11 +0100 Subject: [PATCH] __nextcloud: migrate if the database type change This adds a migration progess if the database type changes automaticly. --- type/__nextcloud/man.rst | 16 +++++- type/__nextcloud/map-conf-changes.sh | 81 +++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/type/__nextcloud/man.rst b/type/__nextcloud/man.rst index 2bff614..2a6ec9d 100644 --- a/type/__nextcloud/man.rst +++ b/type/__nextcloud/man.rst @@ -113,13 +113,22 @@ database-type **This parameter defaults to the SQLite database backend, as it is the simplest one to setup and do not require extra parameters.** + If this parameter change, the type will migrate to the new database type. + It will not work for SQLite because the upstream migration script does not + support it. **Be aware that migrations take there time, plan at minimum + 40 seconds of migration for a stock installation.** + database-host The database host to connect to. Possible are hostnames, ip addresses or UNIX sockets. UNIX sockets must set in the format of ``localhost:/path/to/socket``. If an non-standard port is used, set it - after the hostname or ip address seperated by an colon (``:``). + after the hostname or ip address seperated by an colon (``:``). If this + value is not set, nextcloud defaults to the value ``localhost``. - If this value is not set, nextcloud defaults to the value ``localhost``. + This type will not migrate data if the type does not change. You must do + this manually by setting the maintainer mode (to avoid data changes) and + then cloning the database to the new destination. After that, run cdist to + apply the config changes. It should automaticly remove the maintainer mode. database-name The name of the database to connect to. Required if MariaDB or PostgreSQL @@ -173,6 +182,9 @@ nextcloud configuration is broken and must be resolved manually: Move the data directory to the correct location or change the configuration to point to the old destination and retry. +It aborts if it should migrate to a SQLite database. This will be done before +the upstream migration script is executed, as it would throw the same error. + EXAMPLES -------- diff --git a/type/__nextcloud/map-conf-changes.sh b/type/__nextcloud/map-conf-changes.sh index caea3bd..3c98c3b 100755 --- a/type/__nextcloud/map-conf-changes.sh +++ b/type/__nextcloud/map-conf-changes.sh @@ -7,6 +7,21 @@ # explorer. +# Print the value of the given configuration. +# +# Arguments: +# 1: the nextcloud configuration name +# +# Returns with a unsuccessful return code if no parameter found. +getparam() { + awk -v FS=" = " -v name="$1" ' + function ntostring(n) { ret=""; for(i=n; i<=NF; i++) ret=ret $i (i/dev/null || printf "localhost")" + database_name="$(cat "$__object/parameter/database-name")" + database_user="$(cat "$__object/parameter/database-user")" + database_pass="$(cat "$__object/parameter/database-password")" + + # Extract the port from the host + # this is required for pgsql, but mysql can do it itself, too + if printf "%s" "$database_host" | grep -q ":[[:digit:]]\+$"; then + # extract the last part, which is the port number + database_port="${database_host##*:}" + else + # set default port because the tool can not do this for pgsql + case "$database_type" in + mysql) + database_port=3306 + ;; + pgsql) + database_port=5432 + ;; + esac + fi + + # print out the correct command + printf "php occ db:convert-type --no-interaction --no-ansi --clear-schema --all-apps \ + '%s' '%s' --password '%s' '%s' --port '%u' '%s'\n" \ + "$database_type" "$database_user" "$database_pass" "$database_host" "$database_port" "$database_name" +} + + # Set the install variable if nextcloud was not installed before this type. if ! testparam installed 1; then install="yes" @@ -210,19 +263,35 @@ conf_array host trusted_domains # Already set via the installer # set default values from the nextcloud installer to do not override them if [ -z "$install" ]; then - # database + # Database to check if the type changed + # use the current type if no old type found to match instead of migrate database_type="$(cat "$__object/parameter/database-type")" + old_db_type="$(getparam dbtype || printf "%s" "$database_type")" + case "$database_type" in sqlite3) + if [ "$old_db_type" != "sqlite3" ]; then + echo "Migrating to a SQLite database is not supported by upstream!" >&2 + echo "Do it manually or reinstall nextcloud .." >&2 + exit 1 + fi conf_string database-type dbtype ;; mysql|pgsql) - conf_string database-type dbtype - conf_string database-host dbhost installdef "localhost" - conf_string database-name dbname required - conf_string database-user dbuser required - conf_string database-password dbpassword required + if [ "$old_db_type" != "$database_type" ]; then + # the migration will change all database parameters itself + migrate_db "$database_type" + else + # no change of dbtype cause it will cause a migration + conf_string database-host dbhost installdef "localhost" + conf_string database-name dbname required + conf_string database-user dbuser required + conf_string database-password dbpassword required + fi + + # It may not be a good idea to change this parameter, but do what + # the user want to do. conf_string database-prefix dbtableprefix ;;