diff --git a/etc/library.sh b/etc/library.sh index 7e124638a..ca73142fa 100644 --- a/etc/library.sh +++ b/etc/library.sh @@ -230,6 +230,33 @@ function persistent_cfg() ln -s "$DST" "$SRC" } +function is_more_recent_than() +{ + local version_A="$1" + local version_B="$2" + + local major_a=$( cut -d. -f1 <<<"$version_A" ) + local minor_a=$( cut -d. -f2 <<<"$version_A" ) + local patch_a=$( cut -d. -f3 <<<"$version_A" ) + + local major_b=$( cut -d. -f1 <<<"$version_B" ) + local minor_b=$( cut -d. -f2 <<<"$version_B" ) + local patch_b=$( cut -d. -f3 <<<"$version_B" ) + + # Compare version A with version B + # Return true if A is more recent than B + + if [ "$major_b" -gt "$major_a" ]; then + return 1 + elif [ "$major_b" -eq "$major_a" ] && [ "$minor_b" -gt "$minor_a" ]; then + return 1 + elif [ "$major_b" -eq "$major_a" ] && [ "$minor_b" -eq "$minor_a" ] && [ "$patch_b" -gt "$patch_a" ]; then + return 1 + fi + + return 0 +} + # License # # This script is free software; you can redistribute it and/or modify it diff --git a/run_update_history.sh b/run_update_history.sh new file mode 100644 index 000000000..0770a3b14 --- /dev/null +++ b/run_update_history.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +# Backward updates mechanism + +set -e + +source /usr/local/etc/library.sh + +# Updates folder contains the "history" of updates +updates="$1" +[ -d "$updates" ] || { echo "$updates does not exist. Abort" >&2; exit 1; } + +# Get the array of updates dir +# The files in updates dir are sorted by tag number +# Files names follow the syntax of a tag: x.y.z.sh +while read line ; do + updates_list+=("$line") +done < <( ls -1 "$updates" | sort -V) + +starting_checkpoint=0 +len=${#updates_list[@]} +end_of_list=$((len - 1)) + +# The latest checkpoint is the newer version in updates dir +latest_checkpoint=${updates_list[$end_of_list]} +latest_checkpoint_version=$( basename "$latest_checkpoint" .sh ) +current_version=$( grep -oP "\d+\.\d+\.\d+" /usr/local/etc/ncp-version | cut -d'v' -f1 ) + +# Compare current version with latest checkpoint +# If the current version is more recent than the latest checkpoint there is no need for backward updates + +if is_more_recent_than "$latest_checkpoint_version" "$current_version" ; then + + # Execute a series of updates of older versions + + # Binary search to find the right checkpoint to begin the updates + # Checkpoints are considered the updates files + # An update file will update the system to the version it has as a tag + # .sh will update ncp to version + + # An update is *applicable* when it is more recent than the current version + # An older update/checkpoint is not *applicable* to our system + + lower_bound=0 + upper_bound=$end_of_list + while [ $lower_bound -le $upper_bound ]; do + x=$((upper_bound + lower_bound)) + mid=$((x / 2)) + + #Compare mid's version with current version + + mid_version=$( basename ${updates_list[$mid]} .sh ) + + if is_more_recent_than "$mid_version" "$current_version" ; then + # Mid's version update is applicable to the current version + # Check if the previous checkpoint (mid-1) is applicable + + previous=$((mid - 1)) + previous_version=$( basename ${updates_list[$previous]} .sh ) + if [ "$mid" -gt 0 ] ; then + #Compare previous's version with current version + # If the previous checkpoint is not applicable then mid is the starting checkpoint + # Otherwise keep on binary searching + if is_more_recent_than "$current_version" "$previous_version" ; then + starting_checkpoint=$mid + break + fi + else + # mid is at 0, so this is the starting checkpoint + starting_checkpoint=$mid + break + fi + # Continue searching for starting checkpoint + upper_bound=$((mid - 1)) + + else + # Mid's version update is not applicable to the current version + # Check if the next checkpoint (mid+1) is applicable + + next=$((mid + 1)) + next_version=$( basename ${updates_list[$next]} .sh ) + + #Compare next's version with current version + # If next checkpoint is not applicable then next is the starting checkpoint + # Otherwise keep on binary searching + if is_more_recent_than "$current_version" "$next_version" ; then + # Continue searching for starting checkpoint + lower_bound=$((mid + 1)) + else + # The next version is the starting checkpoint + starting_checkpoint=$next + break + fi + fi + done + + # Starting checkpoint has been found so update the system for the rest updates + + for(( i="$starting_checkpoint"; i<="$end_of_list"; i++)); do + update_file=${updates_list[i]} + tag_update=$( basename "$update_file" .sh ) + echo -e "Updating system to version $tag_update . . ." + ./"$updates"/"$update_file" || exit 1 + echo -e "System updated successfully to version $tag_update" + echo "v$tag_update" > /usr/local/etc/ncp-version + done +fi + diff --git a/update.sh b/update.sh index 2c185a09f..07b0a82aa 100755 --- a/update.sh +++ b/update.sh @@ -49,6 +49,8 @@ cp etc/library.sh /usr/local/etc/ source /usr/local/etc/library.sh +./run_update_history.sh "updates" + mkdir -p "$CONFDIR" # prevent installing some ncp-apps in the docker version @@ -123,190 +125,6 @@ cp -r ncp-app /var/www/ } -## BACKWARD FIXES ( for older images ) - -# not for image builds, only live updates -[[ ! -f /.ncp-image ]] && { - - # docker images only - [[ -f /.docker-image ]] && { - : - } - - # for non docker images - [[ ! -f /.docker-image ]] && { - cat > /etc/fail2ban/filter.d/ufwban.conf <<'EOF' -[INCLUDES] -before = common.conf -[Definition] -failregex = UFW BLOCK.* SRC= -ignoreregex = -EOF - : - } - - # update to the latest version - is_active_app nc-autoupdate-nc && run_app nc-autoupdate-nc - - # previews settings - ncc config:app:set previewgenerator squareSizes --value="32" - ncc config:app:set previewgenerator widthSizes --value="128 256 512" - ncc config:app:set previewgenerator heightSizes --value="128 256" - ncc config:system:set jpeg_quality --value 60 - - # update unattended labels - is_active_app unattended-upgrades && run_app unattended-upgrades - - # update sury keys - wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg - - # fix cron path - is_active_app nc-backup-auto && run_app nc-backup-auto - is_active_app nc-scan-auto && run_app nc-scan-auto - is_active_app nc-autoupdate-ncp && run_app nc-autoupdate-ncp - is_active_app nc-notify-updates && run_app nc-notify-updates - is_active_app nc-previews-auto && run_app nc-previews-auto - is_active_app nc-update-nc-apps-auto && run_app nc-update-nc-apps-auto - - # rework letsencrypt notification - USER="$(jq -r '.params[2].value' "$CONFDIR"/letsencrypt.cfg)" - mkdir -p /etc/letsencrypt/renewal-hooks/deploy/ - cat > /etc/letsencrypt/renewal-hooks/deploy/ncp </dev/null - - # armbian fix uu - rm -f /etc/apt/apt.conf.d/02-armbian-periodic - - # switch back to the apt LE version - which letsencrypt &>/dev/null || install_app letsencrypt - - # update launchers - apt-get update - apt-get install -y --no-install-recommends file - cat > /home/www/ncp-launcher.sh <<'EOF' -#!/bin/bash -grep -q '[\\&#;`|*?~<>^()[{}$&[:space:]]' <<< "$*" && exit 1 -source /usr/local/etc/library.sh -run_app $1 -EOF - chmod 700 /home/www/ncp-launcher.sh - - cat > /home/www/ncp-backup-launcher.sh <<'EOF' -#!/bin/bash -action="${1}" -file="${2}" -compressed="${3}" -grep -q '[\\&#;`|*?~<>^()[{}$&]' <<< "$*" && exit 1 -[[ "$file" =~ ".." ]] && exit 1 -[[ "${action}" == "chksnp" ]] && { - btrfs subvolume show "$file" &>/dev/null || exit 1 - exit -} -[[ "${action}" == "delsnp" ]] && { - btrfs subvolume delete "$file" || exit 1 - exit -} -[[ -f "$file" ]] || exit 1 -[[ "$file" =~ ".tar" ]] || exit 1 -[[ "${action}" == "del" ]] && { - [[ "$(file "$file")" =~ "tar archive" ]] || [[ "$(file "$file")" =~ "gzip compressed data" ]] || exit 1 - rm "$file" || exit 1 - exit -} -[[ "$compressed" != "" ]] && pigz="-I pigz" -tar $pigz -tf "$file" data &>/dev/null -EOF - chmod 700 /home/www/ncp-backup-launcher.sh - sed -i 's|www-data ALL = NOPASSWD: .*|www-data ALL = NOPASSWD: /home/www/ncp-launcher.sh , /home/www/ncp-backup-launcher.sh, /sbin/halt, /sbin/reboot|' /etc/sudoers - - # fix logrotate files - chmod 0444 /etc/logrotate.d/* - - # adjust preview sizes - [[ "$(ncc config:system:get preview_max_x)" == "" ]] && { - ncc config:app:set previewgenerator squareSizes --value="32 256" - ncc config:app:set previewgenerator widthSizes --value="256 384" - ncc config:app:set previewgenerator heightSizes --value="256" - ncc config:system:set preview_max_x --value 2048 - ncc config:system:set preview_max_y --value 2048 - ncc config:system:set jpeg_quality --value 60 - } - - # adjust local IPv6 - cat > /etc/apache2/sites-available/ncp.conf < - DocumentRoot /var/www/ncp-web - SSLEngine on - SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem - SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key - - # 2 days to avoid very big backups requests to timeout - TimeOut 172800 - - - DefineExternalAuth pwauth pipe /usr/sbin/pwauth - - - - - - AuthType Basic - AuthName "ncp-web login" - AuthBasicProvider external - AuthExternal pwauth - - SetEnvIf Request_URI "^" noauth - SetEnvIf Request_URI "^index\.php$" !noauth - SetEnvIf Request_URI "^/$" !noauth - SetEnvIf Request_URI "^/wizard/index.php$" !noauth - SetEnvIf Request_URI "^/wizard/$" !noauth - - - - - Require host localhost - Require local - Require ip 192.168 - Require ip 172 - Require ip 10 - Require ip fd00::/8 - Require ip fe80::/10 - - - - Require env noauth - Require user ncp - - - - - -EOF - - # remove redundant opcache configuration. Leave until update bug is fixed -> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815968 - # Bug #416 reappeared after we moved to php7.2 and debian buster packages. (keep last) - [[ "$( ls -l /etc/php/7.2/fpm/conf.d/*-opcache.ini | wc -l )" -gt 1 ]] && rm "$( ls /etc/php/7.2/fpm/conf.d/*-opcache.ini | tail -1 )" - [[ "$( ls -l /etc/php/7.2/cli/conf.d/*-opcache.ini | wc -l )" -gt 1 ]] && rm "$( ls /etc/php/7.2/cli/conf.d/*-opcache.ini | tail -1 )" - -} # end - only live updates - exit 0 # License diff --git a/updates/1.10.11.sh b/updates/1.10.11.sh new file mode 100755 index 000000000..e074ad09c --- /dev/null +++ b/updates/1.10.11.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +## BACKWARD FIXES ( for older images ) + +source /usr/local/etc/library.sh + +# not for image builds, only live updates +[[ ! -f /.ncp-image ]] && { + + # docker images only + [[ -f /.docker-image ]] && { + : + } + + # for non docker images + [[ ! -f /.docker-image ]] && { + cat > /etc/fail2ban/filter.d/ufwban.conf <<'EOF' +[INCLUDES] +before = common.conf +[Definition] +failregex = UFW BLOCK.* SRC= +ignoreregex = +EOF + : + } + + # update to the latest version + is_active_app nc-autoupdate-nc && run_app nc-autoupdate-nc + + # previews settings + ncc config:app:set previewgenerator squareSizes --value="32" + ncc config:app:set previewgenerator widthSizes --value="128 256 512" + ncc config:app:set previewgenerator heightSizes --value="128 256" + ncc config:system:set jpeg_quality --value 60 + + # update unattended labels + is_active_app unattended-upgrades && run_app unattended-upgrades + + # update sury keys + wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg + + # fix cron path + is_active_app nc-backup-auto && run_app nc-backup-auto + is_active_app nc-scan-auto && run_app nc-scan-auto + is_active_app nc-autoupdate-ncp && run_app nc-autoupdate-ncp + is_active_app nc-notify-updates && run_app nc-notify-updates + is_active_app nc-previews-auto && run_app nc-previews-auto + is_active_app nc-update-nc-apps-auto && run_app nc-update-nc-apps-auto + + # rework letsencrypt notification + USER="$(jq -r '.params[2].value' "$CONFDIR"/letsencrypt.cfg)" + mkdir -p /etc/letsencrypt/renewal-hooks/deploy/ + cat > /etc/letsencrypt/renewal-hooks/deploy/ncp </dev/null + + # armbian fix uu + rm -f /etc/apt/apt.conf.d/02-armbian-periodic + + # switch back to the apt LE version + which letsencrypt &>/dev/null || install_app letsencrypt + + # update launchers + apt-get update + apt-get install -y --no-install-recommends file + cat > /home/www/ncp-launcher.sh <<'EOF' +#!/bin/bash +grep -q '[\\&#;`|*?~<>^()[{}$&[:space:]]' <<< "$*" && exit 1 +source /usr/local/etc/library.sh +run_app $1 +EOF + chmod 700 /home/www/ncp-launcher.sh + + cat > /home/www/ncp-backup-launcher.sh <<'EOF' +#!/bin/bash +action="${1}" +file="${2}" +compressed="${3}" +grep -q '[\\&#;`|*?~<>^()[{}$&]' <<< "$*" && exit 1 +[[ "$file" =~ ".." ]] && exit 1 +[[ "${action}" == "chksnp" ]] && { + btrfs subvolume show "$file" &>/dev/null || exit 1 + exit +} +[[ "${action}" == "delsnp" ]] && { + btrfs subvolume delete "$file" || exit 1 + exit +} +[[ -f "$file" ]] || exit 1 +[[ "$file" =~ ".tar" ]] || exit 1 +[[ "${action}" == "del" ]] && { + [[ "$(file "$file")" =~ "tar archive" ]] || [[ "$(file "$file")" =~ "gzip compressed data" ]] || exit 1 + rm "$file" || exit 1 + exit +} +[[ "$compressed" != "" ]] && pigz="-I pigz" +tar $pigz -tf "$file" data &>/dev/null +EOF + chmod 700 /home/www/ncp-backup-launcher.sh + sed -i 's|www-data ALL = NOPASSWD: .*|www-data ALL = NOPASSWD: /home/www/ncp-launcher.sh , /home/www/ncp-backup-launcher.sh, /sbin/halt, /sbin/reboot|' /etc/sudoers + + # fix logrotate files + chmod 0444 /etc/logrotate.d/* + + # remove redundant opcache configuration. Leave until update bug is fixed -> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815968 + # Bug #416 reappeared after we moved to php7.2 and debian buster packages. (keep last) + [[ "$( ls -l /etc/php/7.2/fpm/conf.d/*-opcache.ini | wc -l )" -gt 1 ]] && rm "$( ls /etc/php/7.2/fpm/conf.d/*-opcache.ini | tail -1 )" + [[ "$( ls -l /etc/php/7.2/cli/conf.d/*-opcache.ini | wc -l )" -gt 1 ]] && rm "$( ls /etc/php/7.2/cli/conf.d/*-opcache.ini | tail -1 )" + +} # end - only live updates