From 66b575dc3ad1ed5412913f29e25369e7ef041c5b Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Wed, 31 Aug 2022 19:32:51 +0200 Subject: [PATCH] new: [vps] add ``nextcloud upgrade`` command to manage full automatic migration Signed-off-by: Valentin Lab --- bin/vps | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/bin/vps b/bin/vps index 8598cea..7d09f71 100755 --- a/bin/vps +++ b/bin/vps @@ -85,7 +85,7 @@ compose:get-compose-yml() { echo "$path" } decorator._mangle_fn compose:get-compose-yml - +export -f compose:get-compose-yml compose:has-container-project-myc() { local projects @@ -93,6 +93,48 @@ compose:has-container-project-myc() { [[ $'\n'"$projects"$'\n' == *$'\n'"myc"$'\n'* ]] } +compose:file:value-change() { + local key="$1" value="$2" first=1 count=0 diff="" + ( + COMPOSE_YML_FILE=$(compose:get-compose-yml) || exit 1 + export COMPOSE_YML_FILE + cd "${COMPOSE_YML_FILE%/*}" + while read-0 hunk; do + if [ -n "$first" ]; then + diff+="$hunk" + first= + continue + fi + [[ "$hunk" =~ $'\n'"+"[[:space:]]+"${key##*.}:" ]] && { + ((count++)) + diff+="$hunk" >&2 + } + done < <( + export DEBUG= + settmpdir YQ_TEMP + cp "${COMPOSE_YML_FILE}" "$YQ_TEMP/compose.yml" && + yq -i ".${key} = \"${value}\"" "$YQ_TEMP/compose.yml" && + diff -u1 "${COMPOSE_YML_FILE}" "$YQ_TEMP/compose.yml" | + sed -r "s/^(@@.*)$/\x00\1/g;s%^(\+\+\+) [^\t]+%\1 ${COMPOSE_YML_FILE}%g" + ) + if [[ "$count" == 0 ]]; then + err "No change made to 'compose.yml'." + return 1 + fi + if [[ "$count" != 1 ]]; then + err "compose file change request seems dubious and was refused." + if [ -n "$DEBUG" ]; then + e "$diff" | prefix " | " + fi + return 1 + fi + echo Applying: >&2 + e "$diff" | prefix " | " >&2 + patch <<<"$diff" + ) || exit 1 +} +export -f compose:file:value-change + type:is-mailcow() { mailcow:get-root >/dev/null || @@ -858,6 +900,22 @@ mailcow:recover-target() { } +nextcloud:src:version() { + local version + if ! version=$(cat "/srv/datastore/data/${nextcloud_service}/var/www/html/version.php" 2>/dev/null); then + err "Can't find version.php file to get last version installed." + exit 1 + fi + version=$(e "$version" | grep 'VersionString =' | cut -f 3 -d ' ' | cut -f 2 -d "'") + if [ -z "$version" ]; then + err "Can't figure out version from version.php content." + exit 1 + fi + echo "$version" +} + + + [ "$SOURCED" ] && return 0 @@ -1446,4 +1504,56 @@ cmdline.spec:rocketchat:cmd:drop-indexes:run() { } +cmdline.spec.gnu nextcloud + +cmdline.spec::cmd:nextcloud:run() { + : +} + +cmdline.spec.gnu upgrade +cmdline.spec:nextcloud:cmd:upgrade:run() { + + : :posarg: [TARGET_VERSION] "Source cyclos dump file to restore" + : :optval: --service,-s "The nexcloud service name (defaults to 'nextcloud')" + + local URL + + nextcloud_service="${opt_service:-nextcloud}" + project_name=$(compose:project_name) || exit 1 + containers=$(compose:service:containers "${project_name}" "${nextcloud_service}") || exit 1 + + container_stopped=() + if [ -n "$containers" ]; then + for container in $containers; do + Wrap -d "stop ${DARKYELLOW}${nextcloud_service}${NORMAL}'s container" -- \ + docker stop "$container" || { + err "Failed to stop container '$container'." + exit 1 + } + container_stopped+=("$container") + done + fi + before_version=$(nextcloud:src:version) || exit 1 + + compose upgrade "$nextcloud_service" || exit 1 + errlvl="$?" + + after_version=$(nextcloud:src:version) + if [ "$after_version" != "$before_version" ]; then + desc="update \`compose.yml\` to set ${DARKYELLOW}$nextcloud_service${NORMAL}'s " + desc+="docker image to actual code version ${WHITE}${after_version}${NORMAL}" + Wrap -d "$desc" -- \ + compose:file:value-change \ + "${nextcloud_service}.docker-compose.image" \ + "docker.0k.io/nextcloud:${after_version}-myc" || exit 1 + fi + + if [ "$errlvl" == 0 ]; then + echo "${WHITE}Launching final compose${NORMAL}" + compose up || exit 1 + fi + + exit "$errlvl" +} + cmdline::parse "$@"