mirror of
https://github.com/overleaf/toolkit.git
synced 2025-04-18 14:58:21 +02:00
291 lines
9.9 KiB
Bash
Executable file
291 lines
9.9 KiB
Bash
Executable file
#! /usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
#### Detect Toolkit Project Root ####
|
|
# if realpath is not available, create a semi-equivalent function
|
|
command -v realpath >/dev/null 2>&1 || realpath() {
|
|
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
|
|
}
|
|
SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")"
|
|
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
|
TOOLKIT_ROOT="$(realpath "$SCRIPT_DIR/..")"
|
|
if [[ ! -d "$TOOLKIT_ROOT/bin" ]] || [[ ! -d "$TOOLKIT_ROOT/config" ]]; then
|
|
echo "ERROR: could not find root of overleaf-toolkit project (inferred project root as '$TOOLKIT_ROOT')"
|
|
exit 1
|
|
fi
|
|
|
|
source "$TOOLKIT_ROOT/lib/shared-functions.sh"
|
|
|
|
function usage() {
|
|
echo "Usage: bin/upgrade"
|
|
echo ""
|
|
echo "This script will check for updates to the toolkit code (via git),"
|
|
echo "and offer to pull the new changes. It will then check the latest"
|
|
echo "available version of the docker image, and offer to update the"
|
|
echo "locally configured image (in config/image) if applicable"
|
|
echo ""
|
|
echo "This script will prompt the user for confirmation at"
|
|
echo "each step along the way."
|
|
}
|
|
|
|
function services_up() {
|
|
local top_output
|
|
top_output="$("$TOOLKIT_ROOT/bin/docker-compose" top)"
|
|
if [[ -z "$top_output" ]]; then
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function git_pull_available() {
|
|
local branch="$1"
|
|
local fetch_output
|
|
fetch_output="$(git -C "$TOOLKIT_ROOT" fetch --dry-run origin "$branch" 2>&1)"
|
|
local filtered_fetch_output
|
|
filtered_fetch_output="$(echo "$fetch_output" | grep '\-> origin/'"$branch")"
|
|
if [[ -z "$filtered_fetch_output" ]]; then
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function git_diff() {
|
|
git -C "$TOOLKIT_ROOT" diff "$@"
|
|
}
|
|
|
|
function is_up_to_date_with_remote() {
|
|
local branch="$1"
|
|
git_diff --quiet HEAD "origin/$branch"
|
|
}
|
|
|
|
function show_changes() {
|
|
local branch="$1"
|
|
|
|
if git_diff --quiet HEAD "origin/$branch" -- CHANGELOG.md; then
|
|
echo "No changelog available"
|
|
return 0
|
|
fi
|
|
|
|
# show CHANGELOG.md changes
|
|
# git diff --unified=0 hide diff context
|
|
# tail -n+6 hide the patch header
|
|
|
|
# Example output
|
|
#
|
|
# Changelog:
|
|
# ----------
|
|
# +## 2020-11-19
|
|
# +### Added
|
|
# +- Updated ...
|
|
# ----------
|
|
|
|
echo "Changelog:"
|
|
echo "----------"
|
|
git_diff --color --unified=0 HEAD "origin/$branch" -- CHANGELOG.md \
|
|
| tail -n+6
|
|
echo "----------"
|
|
}
|
|
|
|
function read_seed_image_version() {
|
|
SEED_IMAGE_VERSION="$(head -n 1 "$TOOLKIT_ROOT/lib/config-seed/version")"
|
|
if [[ ! "$SEED_IMAGE_VERSION" =~ ^([0-9]+)\.([0-9]+)\.[0-9]+(-RC[0-9]*)?(-with-texlive-full)?$ ]]; then
|
|
echo "ERROR: invalid config-seed/version '${SEED_IMAGE_VERSION}'"
|
|
exit 1
|
|
fi
|
|
SEED_IMAGE_VERSION_MAJOR=${BASH_REMATCH[1]}
|
|
SEED_IMAGE_VERSION_MINOR=${BASH_REMATCH[2]}
|
|
}
|
|
|
|
function handle_image_upgrade() {
|
|
if [[ ! "$SEED_IMAGE_VERSION" > "$IMAGE_VERSION" ]]; then
|
|
echo "No change to docker image version"
|
|
return 0
|
|
fi
|
|
|
|
echo "New docker image version available ($SEED_IMAGE_VERSION)"
|
|
echo "Current image version is '$IMAGE_VERSION' (from config/version)"
|
|
|
|
local user_image_major_version="$(echo "$IMAGE_VERSION" | awk -F. '{print $1}')"
|
|
local seed_image_major_version="$(echo "$SEED_IMAGE_VERSION" | awk -F. '{print $1}')"
|
|
if [[ "$seed_image_major_version" > "$user_image_major_version" ]]; then
|
|
echo "WARNING: this is a major version update, please check the Release Notes for breaking changes before proceeding:"
|
|
echo "* https://github.com/overleaf/overleaf/wiki#release-notes"
|
|
fi
|
|
|
|
local should_upgrade="n"
|
|
read -r -p "Upgrade image? [y/n] " should_upgrade
|
|
|
|
if [[ ! "$should_upgrade" =~ [Yy] ]]; then
|
|
echo "Keeping image version '$IMAGE_VERSION'"
|
|
check_retracted_version
|
|
return 0
|
|
fi
|
|
|
|
echo "Upgrading config/version from $IMAGE_VERSION to $SEED_IMAGE_VERSION"
|
|
|
|
local docker_compose_override_path="$TOOLKIT_ROOT/config/docker-compose.override.yml"
|
|
if [ -f "$docker_compose_override_path" ]; then
|
|
if grep -q -E '^\s*image: sharelatex/sharelatex.*' "$docker_compose_override_path"; then
|
|
echo "WARNING: you are using a customized docker image, the server may not run on the latest version post upgrade."
|
|
echo "* If you have followed the guide 'Upgrading TexLive', please remove and recreate the modified image."
|
|
echo "* Remove the image: 'docker rm sharelatex/sharelatex:with-texlive-full'"
|
|
echo "* Remove the override file: 'rm config/docker-compose.override.yml'"
|
|
echo "* Recreate the image by following: https://github.com/overleaf/toolkit/blob/master/doc/ce-upgrading-texlive.md"
|
|
fi
|
|
fi
|
|
|
|
|
|
# Skip retraction check in sub-shells
|
|
export OVERLEAF_SKIP_RETRACTION_CHECK="$IMAGE_VERSION"
|
|
local version="$IMAGE_VERSION_MAJOR.$IMAGE_VERSION_MINOR.$IMAGE_VERSION_PATCH"
|
|
if [[ "$version" == "5.0.1" ]]; then
|
|
echo "-------------------------------------------------------"
|
|
echo "--------------------- WARNING -----------------------"
|
|
echo "-------------------------------------------------------"
|
|
echo " You are currently using a retracted version, $version."
|
|
echo ""
|
|
echo " We have identified a critical bug in a database migration that causes data loss in the history system."
|
|
echo " Please follow the steps of the recovery process in the following wiki page:"
|
|
echo " https://github.com/overleaf/overleaf/wiki/Doc-version-recovery"
|
|
echo "-------------------------------------------------------"
|
|
echo "--------------------- WARNING -----------------------"
|
|
echo "-------------------------------------------------------"
|
|
prompt "Are you following the recovery process?"
|
|
fi
|
|
|
|
if [[ "${PULL_BEFORE_UPGRADE:-true}" == "true" ]]; then
|
|
echo "Pulling new images"
|
|
set_server_pro_image_name "$SEED_IMAGE_VERSION"
|
|
docker pull "$IMAGE"
|
|
if [[ $GIT_BRIDGE_ENABLED == "true" ]]; then
|
|
if [[ -n ${GIT_BRIDGE_IMAGE:-} ]]; then
|
|
echo "------------------- WARNING ----------------------"
|
|
echo " You're using the custom git bridge image $GIT_BRIDGE_IMAGE"
|
|
echo " Before continuing you need to tag the updated image separately, making sure that:"
|
|
echo " 1. The Docker image is tagged with the new version: $SEED_IMAGE_VERSION"
|
|
echo " 2. The config/overleaf.rc entry GIT_BRIDGE_IMAGE only contains the image name, and not a tag/version."
|
|
echo " You wont be able to continue with this upgrade until you've tagged your custom image with $SEED_IMAGE_VERSION"
|
|
echo "------------------- WARNING ----------------------"
|
|
prompt "Has the custom image been tagged?"
|
|
fi
|
|
set_git_bridge_image_name "$SEED_IMAGE_VERSION"
|
|
docker pull "$GIT_BRIDGE_IMAGE"
|
|
fi
|
|
fi
|
|
|
|
## Offer to stop docker services
|
|
local services_stopped="false"
|
|
if services_up; then
|
|
echo "docker services are up, stop them first?"
|
|
local should_stop="n"
|
|
read -r -p "Stop docker services? [y/n] " should_stop
|
|
if [[ ! "$should_stop" =~ [Yy] ]]; then
|
|
echo "exiting without stopping services"
|
|
exit 1
|
|
fi
|
|
services_stopped="true"
|
|
echo "Stopping docker services"
|
|
"$TOOLKIT_ROOT/bin/docker-compose" stop
|
|
fi
|
|
|
|
## Advise the user to take a backup
|
|
## (NOTE: we can't do this automatically because it will likely require
|
|
## sudo privileges. We leave it to the user to sort out for now)
|
|
echo "At this point, we recommend backing up your data before proceeding"
|
|
echo "!! WARNING: Only do this while the docker services are stopped!!"
|
|
local should_proceed="n"
|
|
read -r -p "Proceed with the upgrade? [y/n] " should_proceed
|
|
if [[ ! "$should_proceed" =~ [Yy] ]]; then
|
|
echo "Not proceeding with upgrade"
|
|
return 1
|
|
fi
|
|
|
|
## Set the new image version
|
|
echo "Backing up old version file to config/__old-version"
|
|
cp "$TOOLKIT_ROOT/config/version" "$TOOLKIT_ROOT/config/__old-version"
|
|
echo "Over-writing config/version with $SEED_IMAGE_VERSION"
|
|
cp "$TOOLKIT_ROOT/lib/config-seed/version" "$TOOLKIT_ROOT/config/version"
|
|
|
|
if [[ "$IMAGE_VERSION_MAJOR" -le 4 && "$SEED_IMAGE_VERSION_MAJOR" -ge 5 ]]; then
|
|
rebrand_sharelatex_env_variables 'variables.env'
|
|
fi
|
|
|
|
## Maybe offer to start services again
|
|
if [[ "${services_stopped:-null}" == "true" ]]; then
|
|
local should_start="n"
|
|
read -r -p "Start docker services again? [y/n] " should_start
|
|
if [[ "$should_start" =~ [Yy] ]]; then
|
|
echo "Starting docker services"
|
|
"$TOOLKIT_ROOT/bin/docker-compose" up -d
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function handle_git_update() {
|
|
local current_branch
|
|
current_branch="$(git -C "$TOOLKIT_ROOT" rev-parse --abbrev-ref HEAD)"
|
|
local current_commit
|
|
current_commit="$(git -C "$TOOLKIT_ROOT" rev-parse --short HEAD)"
|
|
|
|
if [[ ! "$current_branch" == "master" ]]; then
|
|
echo "Warning: current branch is not master, '$current_branch' instead"
|
|
fi
|
|
|
|
echo "Checking for code update..."
|
|
|
|
if ! git_pull_available "$current_branch"; then
|
|
echo "No code update available for download"
|
|
else
|
|
echo "Code update available for download!"
|
|
git -C "$TOOLKIT_ROOT" fetch origin "$current_branch"
|
|
fi
|
|
|
|
if ! is_up_to_date_with_remote "$current_branch"; then
|
|
show_changes "$current_branch"
|
|
|
|
local should_pull="n"
|
|
read -r -p "Perform code update? [y/n] " should_pull
|
|
|
|
if [[ ! "$should_pull" =~ [Yy] ]]; then
|
|
echo "Continuing without updating code"
|
|
else
|
|
echo "Current commit is $current_commit"
|
|
echo "Updating code..."
|
|
git -C "$TOOLKIT_ROOT" pull origin "$current_branch"
|
|
echo "Relaunching bin/upgrade after code update"
|
|
exec $0 --skip-git-update
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function handle_rc_rebranding() {
|
|
## Rename variables in overleaf.rc SHARELATEX_ -> OVERLEAF_
|
|
rebrand_sharelatex_env_variables 'overleaf.rc' silent_if_no_match
|
|
}
|
|
|
|
function __main__() {
|
|
if [[ "${1:-null}" == "help" ]] \
|
|
|| [[ "${1:-null}" == "--help" ]] ; then
|
|
usage && exit
|
|
fi
|
|
|
|
if [[ "${1:-null}" == "--skip-git-update" ]]; then
|
|
echo "Skipping git update"
|
|
else
|
|
handle_git_update
|
|
fi
|
|
|
|
read_seed_image_version
|
|
read_image_version
|
|
read_config
|
|
handle_rc_rebranding
|
|
handle_image_upgrade
|
|
|
|
echo "Done"
|
|
exit 0
|
|
}
|
|
|
|
__main__ "$@"
|