#! /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 SPACES_PER_INDENT=4 WARNINGS_FILE="$(mktemp)" function add_warning() { echo "$@" >> "$WARNINGS_FILE" } function indent_to_level() { levels="$1" number_of_spaces=$(( levels * SPACES_PER_INDENT )) spaces="$(printf %${number_of_spaces}s)" echo -n "${spaces}" } function print_section_separator() { echo "====== $* ======" } function print_point() { indent_level="0" if [[ "${1:-null}" =~ [0-9]{1} ]]; then indent_level="$1" shift fi # shellcheck disable=SC2086 echo "$(indent_to_level $indent_level)- $*" } function check_host_information() { print_point 0 "Host Information" # Linux or not? if [[ $(uname -a) =~ .*Linux.* ]]; then print_point 1 "Linux" else print_point 1 "Not Linux !" add_warning "This system seems to not be Linux" fi # LSB Information (particular distribution of Linux, and version) if [[ -n $(command -v lsb_release) ]]; then print_point 1 "Output of 'lsb_release -a':" lsb_release -a 2>&1 | while read -r _line; do echo "$(indent_to_level 3)$_line" done else print_point 1 "lsb_release not found !" fi } function check_dependencies() { function get_version() { binary_name="$1" if [[ "bash" == "$binary_name" ]]; then bash -c 'echo $BASH_VERSION' elif [[ "perl" == "$binary_name" ]]; then perl -e 'print $];' else $binary_name --version | head -n 1 fi } function check_for_binary() { binary_name="$1" print_point 1 "$binary_name" if [[ -n $(command -v "$binary_name") ]]; then print_point 2 "status: present" version=$(get_version "$binary_name") print_point 2 "version info: $version" if [[ "$binary_name" == "realpath" ]] \ && [[ "$(command -V "$binary_name")" =~ .*function.* ]]; then message="Could not find 'realpath' binary, falling back to custom function" print_point 2 "WARNING: $message" add_warning "$message" fi else print_point 2 "status: MISSING !" add_warning "$binary_name not found" fi } print_point 0 "Dependencies" declare -a binaries=( bash docker docker-compose realpath perl awk ) for binary in "${binaries[@]}"; do check_for_binary "$binary" done } function check_docker_daemon() { print_point 0 "Docker Daemon" if docker ps &>/dev/null; then print_point 1 "status: up" else print_point 1 "status: DOWN !" add_warning "Docker daemon is not running" fi } function print_warnings() { print_section_separator "Warnings" if [[ -n $(head -n 1 "$WARNINGS_FILE") ]]; then while read -r _line; do echo "! $_line" done < "$WARNINGS_FILE" else echo "- None, all good" fi } function check_config_files() { print_section_separator "Configuration" config_files=( "config/version" "config/overleaf.rc" "config/variables.env" ) for config_file in "${config_files[@]}" do print_point 0 "$config_file" if [[ ! -f "$TOOLKIT_ROOT/$config_file" ]]; then print_point 1 "status: MISSING !" add_warning "configuration file $config_file not found" else print_point 1 "status: present" if [[ "$config_file" == "config/version" ]]; then print_point 1 "version: $(head -n 1 "$TOOLKIT_ROOT/$config_file")" elif [[ "$config_file" == "config/overleaf.rc" ]]; then print_point 1 "values" # Load vars from the rc file # shellcheck disable=SC1090 source "$TOOLKIT_ROOT/$config_file" # Check some vars from the RC file if [[ "${SHARELATEX_DATA_PATH:-null}" != "null" ]]; then print_point 2 "SHARELATEX_DATA_PATH: $SHARELATEX_DATA_PATH" else print_point 2 "SHARELATEX_DATA_PATH: MISSING !" add_warning "rc file, SHARELATEX_DATA_PATH not set" fi print_point 2 "SERVER_PRO: $SERVER_PRO" if [[ "${SERVER_PRO:-null}" == "true" ]]; then local logged_in logged_in="$(grep -q quay.io ~/.docker/config.json && echo 'true' || echo 'false')" print_point 3 "logged in to quay.io: $logged_in" if [[ "${logged_in}" == "false" ]]; then local warning_message=( "Server Pro enabled, but not logged in to quay.io repository." "These credentials are supplied by Overleaf with a Server Pro" "license. See https://www.overleaf.com/for/enterprises/features" "for more details about Server Pro, or contact support@overleaf.com" "if you have any questions." ) add_warning "${warning_message[@]}" fi print_point 2 "SIBLING_CONTAINERS_ENABLED: $SIBLING_CONTAINERS_ENABLED" fi print_point 2 "MONGO_ENABLED: $MONGO_ENABLED" if [[ "${MONGO_URL:-null}" != "null" ]]; then print_point 2 "MONGO_URL: [set here]" fi if [[ "${MONGO_IMAGE:-null}" != "null" ]]; then print_point 2 "MONGO_IMAGE: $MONGO_IMAGE" fi print_point 2 "REDIS_ENABLED: $REDIS_ENABLED" if [[ "${REDIS_HOST:-null}" != "null" ]]; then print_point 2 "REDIS_HOST: [set here]" fi if [[ "${REDIS_PORT:-null}" != "null" ]]; then print_point 2 "REDIS_PORT: [set here]" fi if [[ "${REDIS_IMAGE:-null}" != "null" ]]; then print_point 2 "REDIS_IMAGE: $REDIS_IMAGE" fi fi fi done } function cleanup() { rm "$WARNINGS_FILE" } function __main__() { print_section_separator "Overleaf Doctor" check_host_information check_dependencies check_docker_daemon check_config_files print_warnings print_section_separator "End" cleanup } __main__ "$@"