Browse Source
new: [nextcloud] add ``upgrade`` action.
new: [nextcloud] add ``upgrade`` action.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>pull/29/head
Valentin Lab
2 years ago
1 changed files with 270 additions and 0 deletions
@ -0,0 +1,270 @@ |
|||
#!/bin/bash |
|||
## compose: no-hooks |
|||
|
|||
|
|||
if [ -z "$SERVICE_DATASTORE" ]; then |
|||
echo "This script is meant to be run through 'compose' to work properly." >&2 |
|||
exit 1 |
|||
fi |
|||
|
|||
version=0.1 |
|||
usage="$exname [-h|--help] [--force|-f] [TARGET_VERSION]" |
|||
help=" |
|||
USAGE: |
|||
|
|||
$usage |
|||
|
|||
DESCRIPTION: |
|||
|
|||
Migrate the current nextcloud service to given target version. Don't |
|||
forget to change your =compose.yml= accordingly afterwards. |
|||
|
|||
EXAMPLES: |
|||
|
|||
$exname 21.0.0 |
|||
|
|||
" |
|||
|
|||
no_hint= |
|||
force= |
|||
target= |
|||
while [ "$1" ]; do |
|||
case "$1" in |
|||
"--help"|"-h") |
|||
print_help >&2 |
|||
exit 0 |
|||
;; |
|||
"--force"|"-f") |
|||
force=yes |
|||
;; |
|||
"--no-hint") |
|||
no_hint=yes |
|||
;; |
|||
--*|-*) |
|||
err "Unexpected optional argument '$1'" |
|||
print_usage >&2 |
|||
exit 1 |
|||
;; |
|||
*) |
|||
[ -z "$target" ] && { target=$1 ; shift ; continue ; } |
|||
err "Unexpected positional argument '$1'" |
|||
print_usage >&2 |
|||
exit 1 |
|||
;; |
|||
esac |
|||
shift |
|||
done |
|||
|
|||
nextcloud:config:version() { |
|||
cat "$SERVICE_CONFIGSTORE/var/www/html/config/config.php" | |
|||
grep "'version' =>" | |
|||
cut -f 4 -d \' | |
|||
cut -f 1-3 -d . |
|||
} |
|||
|
|||
nextcloud:code:version() { |
|||
cat "$SERVICE_DATASTORE/var/www/html/version.php" | |
|||
grep 'VersionString =' | |
|||
cut -f 3 -d ' ' | |
|||
cut -f 2 -d \' |
|||
} |
|||
|
|||
current_image_version="${DOCKER_BASE_IMAGE#*:}" |
|||
current_image_version="${current_image_version%-myc}" |
|||
|
|||
|
|||
if ! [[ "$current_image_version" =~ ^[0-9]+.[0-9]+.[0-9]+$ ]]; then |
|||
err "Current nextcloud version '$current_image_version' is unsupported yet." |
|||
exit 1 |
|||
fi |
|||
|
|||
|
|||
if ! [ -e "$SERVICE_DATASTORE/var/www/html/version.php" ]; then |
|||
err "No code seem to have been deployed yet in datastore." \ |
|||
"This is not supported yet." |
|||
exit 1 |
|||
fi |
|||
|
|||
current_code_version=$(nextcloud:code:version) |
|||
|
|||
if [ "$current_code_version" != "$current_image_version" ]; then |
|||
err "Current code version ${WHITE}$current_code_version${NORMAL}" \ |
|||
"mismatch with current image version" \ |
|||
"${WHITE}$current_image_version${NORMAL}" |
|||
exit 1 |
|||
fi |
|||
|
|||
current_config_version=$(nextcloud:config:version) |
|||
|
|||
info "Current config version: ${WHITE}$current_config_version${NORMAL}" |
|||
if [ "$current_config_version" != "$current_code_version" ]; then |
|||
warn "Current config version ${WHITE}$current_config_version${NORMAL}" \ |
|||
"mismatch with current code version" \ |
|||
"${WHITE}$current_code_version${NORMAL}" |
|||
echo " Will use the config version as reference for upgrade." >&2 |
|||
fi |
|||
|
|||
last_available_versions=( |
|||
$(DEBUG= docker:tags:fetch docker.0k.io/nextcloud 30 '[0-9]+\.[0-9+]\.[0-9]+-myc$' | |
|||
sed -r 's/-myc$//g' | |
|||
sort -rV) |
|||
) |
|||
|
|||
## XXXvlab: put this in kal-shlib-common |
|||
version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } |
|||
|
|||
last_upgradable_versions=() |
|||
for v in "${last_available_versions[@]}"; do |
|||
if version_gt "$v" "$current_config_version"; then |
|||
last_upgradable_versions+=("$v") |
|||
fi |
|||
done |
|||
|
|||
if [ "${#last_upgradable_versions[@]}" == 0 ]; then |
|||
info "${DARKYELLOW}nextcloud${NORMAL} is already ${GREEN}up-to-date${NORMAL}." |
|||
exit 0 |
|||
fi |
|||
|
|||
if [ -z "$target" ]; then |
|||
info "Target latest version: ${WHITE}${last_available_versions[0]}${NORMAL}" |
|||
target=${last_upgradable_versions[0]} |
|||
else |
|||
if [[ "* $target *" != " ${last_available_versions[*]} " ]]; then |
|||
err "Invalid version $target selected, please specify one of:" |
|||
for v in "${last_upgradable_versions[@]}"; do |
|||
echo " - $v" |
|||
done >&2 |
|||
exit 1 |
|||
fi |
|||
info "Target version ${WHITE}$target${NORMAL}" |
|||
fi |
|||
|
|||
|
|||
upgrade_path=($(echo "${last_upgradable_versions[*]}" | tr ' ' '\n' | uniq -w 3 | sort -V)) |
|||
|
|||
containers="$(get_running_containers_for_service "$SERVICE_NAME")" |
|||
|
|||
container_stopped=() |
|||
if [ -n "$containers" ]; then |
|||
#err "Running container(s) for $DARKYELLOW$SERVICE_NAME$NORMAL are still running:" |
|||
for container in $containers; do |
|||
docker stop "$container" >/dev/null || { |
|||
err "Failed to stop container '$container'." |
|||
exit 1 |
|||
} |
|||
container_stopped+=("$container") |
|||
done |
|||
fi |
|||
|
|||
## XXXvlab: taking first container is probably not a good idea |
|||
container="$(echo "$containers" | head -n 1)" |
|||
|
|||
settmpdir MIGRATION_TMPDIR |
|||
set -o pipefail |
|||
for image_version in "${upgrade_path[@]}"; do |
|||
|
|||
while true; do |
|||
patched=() |
|||
|
|||
current_code_version=$(nextcloud:code:version) |
|||
current_config_version=$(nextcloud:config:version) |
|||
if [ "$current_config_version" == "$image_version" ]; then |
|||
err "Unexpected step where config version ${WHITE}$current_config_version${NORMAL} is same than image version" |
|||
exit 1 |
|||
fi |
|||
if ! version_gt "$image_version" "$current_config_version"; then |
|||
err "Unexpected step where config version ${WHITE}$current_config_version${NORMAL} is greater than image version ${WHITE}$image_version${NORMAL}" |
|||
exit 1 |
|||
fi |
|||
if (( ${image_version%%.*} - ${current_config_version%%.*} > 1 )); then |
|||
err "Unexpected step where config version ${WHITE}$current_config_version${NORMAL} is more than one major version less than image version ${WHITE}$image_version${NORMAL}" |
|||
exit 1 |
|||
fi |
|||
if [ "$current_code_version" == "$image_version" ]; then |
|||
## Code already setup, we need to call ``occ upgrade`` by our selves |
|||
info "Upgrading ${WHITE}$current_config_version${NORMAL} => ${WHITE}$image_version${NORMAL} (db)" |
|||
compose --no-hooks \ |
|||
--add-compose-content="$SERVICE_NAME: |
|||
docker-compose: |
|||
image: docker.0k.io/nextcloud:${image_version}-myc" \ |
|||
run --rm \ |
|||
-u www-data --entrypoint /var/www/html/occ "$SERVICE_NAME" \ |
|||
upgrade 2>&1 | |
|||
tee "$MIGRATION_TMPDIR/migration.log" |
|||
errlvl="$?" |
|||
else |
|||
## Code will be upgraded |
|||
info "Upgrading ${WHITE}$current_config_version${NORMAL} => ${WHITE}$image_version${NORMAL} (code, db)" |
|||
compose --no-hooks \ |
|||
--add-compose-content="$SERVICE_NAME: |
|||
docker-compose: |
|||
image: docker.0k.io/nextcloud:${image_version}-myc" \ |
|||
run --rm \ |
|||
-v "$CHARM_PATH"/src/fake-apache:/usr/bin/apache \ |
|||
--entrypoint /entrypoint.sh "$SERVICE_NAME" apache 2>&1 | |
|||
tee "$MIGRATION_TMPDIR/migration.log" |
|||
errlvl="$?" |
|||
fi |
|||
|
|||
[ "$errlvl" == 0 ] && continue 2 |
|||
|
|||
## |
|||
## Damage control, there are some things we can solve |
|||
## |
|||
if grep "^Update failed" "$MIGRATION_TMPDIR/migration.log" >/dev/null 2>&1; then |
|||
|
|||
## XXXvlab: this comes from and should move to onlyoffice charm in |
|||
## some way. |
|||
if grep "Update app onlyoffice" "$MIGRATION_TMPDIR/migration.log" >/dev/null 2>&1 && |
|||
grep "SQLSTATE" "$MIGRATION_TMPDIR/migration.log" >/dev/null 2>&1; then |
|||
|
|||
if [ -e "$DATASTORE"/"$SERVICE_NAME/var/www/html/custom_apps/onlyoffice/lib/Migration/Version070400Date20220607111111.php" ]; then |
|||
patch="$CHARM_PATH/../onlyoffice/src/patch/00-onlyoffice-nextcloud.patch" |
|||
if ! [[ " ${patched[*]} " == *" $patch "* ]]; then |
|||
if ( |
|||
cd "$DATASTORE"/"$SERVICE_NAME/var/www/html/custom_apps/onlyoffice/"; |
|||
patch -Np1 --dry-run < "$patch" ); then |
|||
info "Found OnlyOffice issue, correcting it, and retrying." |
|||
( |
|||
cd "$DATASTORE"/"$SERVICE_NAME/var/www/html/custom_apps/onlyoffice/"; |
|||
patch -Np1 < "$patch" |
|||
) || exit 1 |
|||
patched+=("$patch") |
|||
continue |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
err "Upgrade to ${WHITE}$image_version${NORMAL} ${DARKRED}failed${NORMAL}. Aborting." |
|||
exit 1 |
|||
|
|||
done |
|||
done |
|||
if grep "^Nextcloud is in maintenance mode" "$MIGRATION_TMPDIR/migration.log" >/dev/null 2>&1; then |
|||
info "Forcing maintenance mode off" |
|||
compose --no-hooks \ |
|||
--add-compose-content="$SERVICE_NAME: |
|||
docker-compose: |
|||
image: docker.0k.io/nextcloud:${target}-myc" \ |
|||
run --rm \ |
|||
-u www-data --entrypoint /var/www/html/occ "$SERVICE_NAME" \ |
|||
maintenance:mode --off |
|||
fi |
|||
info "Successfully upgraded from ${WHITE}$current_config_version${NORMAL} to ${WHITE}$target${NORMAL}" |
|||
|
|||
if [ -z "no_hint" ]; then |
|||
cat <<EOF >&2 |
|||
Don't forget to force the version in your \`\`compose.yml\`\`. For instance: |
|||
|
|||
${DARKYELLOW}$SERVICE_NAME${NORMAL}: |
|||
|
|||
${DARKGRAY}# ...${NORMAL} |
|||
|
|||
${WHITE}docker-compose${NORMAL}: |
|||
${WHITE}image${NORMAL}: docker.0k.io/nextcloud:${target}-myc |
|||
|
|||
${DARKGRAY}# ...${NORMAL} |
|||
|
|||
EOF |
|||
fi |
Write
Preview
Loading…
Cancel
Save
Reference in new issue