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