diff --git a/.github/ISSUE_TEMPLATE/problem-report.yml b/.github/ISSUE_TEMPLATE/problem-report.yml index 5587952..a93151f 100644 --- a/.github/ISSUE_TEMPLATE/problem-report.yml +++ b/.github/ISSUE_TEMPLATE/problem-report.yml @@ -1,46 +1,46 @@ name: 🐞 Problem Report description: Tell us about something that's not working the way you expect. body: - type: input id: version attributes: label: Version placeholder: 21.7.0 ← should look like this (check the footer) description: What version of self-hosted Sentry are you running? validations: required: true - type: textarea id: repro attributes: label: Steps to Reproduce description: How can we see what you're seeing? Specific is terrific. placeholder: |- 1. foo 2. bar 3. baz validations: required: true - type: textarea id: expected attributes: label: Expected Result validations: required: true - type: textarea id: actual attributes: label: Actual Result description: Logs? Screenshots? Yes, please. placeholder: |- e.g.: - latest install logs: `ls -1 sentry_install_log-*.txt | tail -1 | xargs cat` - - `docker-compose logs` output + - `docker compose logs` output validations: required: true - type: markdown attributes: value: |- ## Thanks Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. validations: required: false diff --git a/install/_lib.sh b/install/_lib.sh index a957e96..fb7b920 100644 --- a/install/_lib.sh +++ b/install/_lib.sh @@ -1,55 +1,56 @@ set -euo pipefail test "${DEBUG:-}" && set -x # Thanks to https://unix.stackexchange.com/a/145654/108960 log_file="sentry_install_log-`date +'%Y-%m-%d_%H-%M-%S'`.txt" exec &> >(tee -a "$log_file") # Work from /install/ for install.sh, project root otherwise if [[ "$(basename $0)" = "install.sh" ]]; then cd "$(dirname $0)/install/" else cd "$(dirname $0)" # assume we're a test script or some such fi # Allow `.env` overrides using the `.env.custom` file if [[ -f "../.env.custom" ]]; then _ENV="$(realpath ../.env.custom)" else _ENV="$(realpath ../.env)" fi # Read .env for default values with a tip o' the hat to https://stackoverflow.com/a/59831605/90297 t=$(mktemp) && export -p > "$t" && set -a && . $_ENV && set +a && . "$t" && rm "$t" && unset t if [ "${GITHUB_ACTIONS:-}" = "true" ]; then _group="::group::" _endgroup="::endgroup::" else _group="▶ " _endgroup="" fi +# Some environments still use `docker-compose` even for Docker Compose v2. dc_base="$(docker compose version &> /dev/null && echo 'docker compose' || echo 'docker-compose')" dc="$dc_base --ansi never --env-file ${_ENV}" dcr="$dc run --rm" # A couple of the config files are referenced from other subscripts, so they # get vars, while multiple subscripts call ensure_file_from_example. function ensure_file_from_example { if [[ -f "$1" ]]; then echo "$1 already exists, skipped creation." else echo "Creating $1..." cp -n $(echo "$1" | sed 's/\.[^.]*$/.example&/') "$1" # sed from https://stackoverflow.com/a/25123013/90297 fi } SENTRY_CONFIG_PY='../sentry/sentry.conf.py' SENTRY_CONFIG_YML='../sentry/config.yml' # Increase the default 10 second SIGTERM timeout # to ensure celery queues are properly drained # between upgrades as task signatures may change across # versions STOP_TIMEOUT=60 # seconds diff --git a/install/check-minimum-requirements.sh b/install/check-minimum-requirements.sh index 6b43d18..42689bf 100644 --- a/install/check-minimum-requirements.sh +++ b/install/check-minimum-requirements.sh @@ -1,54 +1,54 @@ echo "${_group}Checking minimum requirements ..." source "$(dirname $0)/_min-requirements.sh" -DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') -# Get semantic version of Docker Compose v2 -if docker compose version &>/dev/null; then - COMPOSE_VERSION=$(docker compose version --short | sed 's/v\{0,1\}\(.\{1,\}\)/\1/') -else - # Do NOT use $dc instead of `docker-compose` below as older versions don't support certain options and fail - COMPOSE_VERSION=$(docker-compose --version | sed 's/docker-compose version \(.\{1,\}\),.*/\1/') -fi -RAM_AVAILABLE_IN_DOCKER=$(docker run --rm busybox free -m 2>/dev/null | awk '/Mem/ {print $2}'); -CPU_AVAILABLE_IN_DOCKER=$(docker run --rm busybox nproc --all); - # Compare dot-separated strings - function below is inspired by https://stackoverflow.com/a/37939589/808368 function ver () { echo "$@" | awk -F. '{ printf("%d%03d%03d", $1,$2,$3); }'; } +DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') if [[ "$(ver $DOCKER_VERSION)" -lt "$(ver $MIN_DOCKER_VERSION)" ]]; then echo "FAIL: Expected minimum Docker version to be $MIN_DOCKER_VERSION but found $DOCKER_VERSION" exit 1 fi -if [[ "$(ver $COMPOSE_VERSION)" -lt "$(ver $MIN_COMPOSE_VERSION)" ]]; then - echo "FAIL: Expected minimum docker-compose version to be $MIN_COMPOSE_VERSION but found $COMPOSE_VERSION" - exit 1 +if docker compose version &>/dev/null; then + # If `docker compose` exists then it's guaranteed to be Docker Compose v2, which is good enough for us. + true +else + # If we have `docker-compose` instead then it could be either v1 or v2 (also, use portable sed). + # See https://github.com/getsentry/self-hosted/issues/1132#issuecomment-982823712 ff. for regex testing. + COMPOSE_VERSION=$(docker-compose version | head -n1 | sed -E 's/^.* version:? v?([0-9.]+),?.*$/\1/') + if [[ "$(ver $COMPOSE_VERSION)" -lt "$(ver $MIN_COMPOSE_VERSION)" ]]; then + echo "FAIL: Expected minimum docker-compose version to be $MIN_COMPOSE_VERSION but found $COMPOSE_VERSION" + exit 1 + fi fi +CPU_AVAILABLE_IN_DOCKER=$(docker run --rm busybox nproc --all); if [[ "$CPU_AVAILABLE_IN_DOCKER" -lt "$MIN_CPU_HARD" ]]; then echo "FAIL: Required minimum CPU cores available to Docker is $MIN_CPU_HARD, found $CPU_AVAILABLE_IN_DOCKER" exit 1 elif [[ "$CPU_AVAILABLE_IN_DOCKER" -lt "$MIN_CPU_SOFT" ]]; then echo "WARN: Recommended minimum CPU cores available to Docker is $MIN_CPU_SOFT, found $CPU_AVAILABLE_IN_DOCKER" fi +RAM_AVAILABLE_IN_DOCKER=$(docker run --rm busybox free -m 2>/dev/null | awk '/Mem/ {print $2}'); if [[ "$RAM_AVAILABLE_IN_DOCKER" -lt "$MIN_RAM_HARD" ]]; then echo "FAIL: Required minimum RAM available to Docker is $MIN_RAM_HARD MB, found $RAM_AVAILABLE_IN_DOCKER MB" exit 1 elif [[ "$RAM_AVAILABLE_IN_DOCKER" -lt "$MIN_RAM_SOFT" ]]; then echo "WARN: Recommended minimum RAM available to Docker is $MIN_RAM_SOFT MB, found $RAM_AVAILABLE_IN_DOCKER MB" fi #SSE4.2 required by Clickhouse (https://clickhouse.yandex/docs/en/operations/requirements/) # On KVM, cpuinfo could falsely not report SSE 4.2 support, so skip the check. https://github.com/ClickHouse/ClickHouse/issues/20#issuecomment-226849297 IS_KVM=$(docker run --rm busybox grep -c 'Common KVM processor' /proc/cpuinfo || :) if [[ "$IS_KVM" -eq 0 ]]; then SUPPORTS_SSE42=$(docker run --rm busybox grep -c sse4_2 /proc/cpuinfo || :) if [[ "$SUPPORTS_SSE42" -eq 0 ]]; then echo "FAIL: The CPU your machine is running on does not support the SSE 4.2 instruction set, which is required for one of the services Sentry uses (Clickhouse). See https://git.io/JvLDt for more info." exit 1 fi fi echo "${_endgroup}" diff --git a/install/error-handling.sh b/install/error-handling.sh index d25ee01..9121bba 100644 --- a/install/error-handling.sh +++ b/install/error-handling.sh @@ -1,35 +1,35 @@ echo "${_group}Setting up error handling ..." # Courtesy of https://stackoverflow.com/a/2183063/90297 trap_with_arg() { func="$1" ; shift for sig ; do trap "$func $sig "'$LINENO' "$sig" done } DID_CLEAN_UP=0 # the cleanup function will be the exit point cleanup () { if [[ "$DID_CLEAN_UP" -eq 1 ]]; then return 0; fi DID_CLEAN_UP=1 if [[ "$1" != "EXIT" ]]; then echo "An error occurred, caught SIG$1 on line $2"; if [[ -n "$MINIMIZE_DOWNTIME" ]]; then - echo "*NOT* cleaning up, to clean your environment run \"docker-compose stop\"." + echo "*NOT* cleaning up, to clean your environment run \"docker compose stop\"." else echo "Cleaning up..." fi fi if [[ -z "$MINIMIZE_DOWNTIME" ]]; then $dc stop -t $STOP_TIMEOUT &> /dev/null fi } trap_with_arg cleanup ERR INT TERM EXIT echo "${_endgroup}" diff --git a/install/parse-cli.sh b/install/parse-cli.sh index f1b6218..cf4c391 100644 --- a/install/parse-cli.sh +++ b/install/parse-cli.sh @@ -1,32 +1,32 @@ echo "${_group}Parsing command line ..." show_help() { cat <stdout -# redirection below and pass it through grep, ignoring all lines having this -# '-onpremise-local' suffix. +# We tag locally built images with an '-onpremise-local' suffix. `docker +# compose pull` tries to pull these too and shows a 404 error on the console +# which is confusing and unnecessary. To overcome this, we add the +# stderr>stdout redirection below and pass it through grep, ignoring all lines +# having this '-onpremise-local' suffix. + $dc pull -q --ignore-pull-failures 2>&1 | grep -v -- -onpremise-local || true # We may not have the set image on the repo (local images) so allow fails docker pull ${SENTRY_IMAGE} || true; echo "${_endgroup}" diff --git a/reset.sh b/reset.sh index e188686..8802b35 100755 --- a/reset.sh +++ b/reset.sh @@ -1,62 +1,62 @@ #!/usr/bin/env bash # The purpose of this script is to make it easy to reset a local onpremise # install to a clean state, optionally targeting a particular version. set -euo pipefail if [ -n "${DEBUG:-}" ]; then set -x fi cd "$(dirname $0)" function confirm () { read -p "$1 [y/n] " confirmation if [ "$confirmation" != "y" ]; then echo "Canceled. 😅" exit fi } # If we have a version given, validate it. # ---------------------------------------- # Note that arbitrary git refs won't work, because the *_IMAGE variables in # .env will almost certainly point to :latest. Tagged releases are generally # the only refs where these component versions are pinned, so enforce that # we're targeting a valid tag here. Do this early in order to fail fast. version="${1:-}" if [ -n "$version" ]; then set +e git rev-parse --verify --quiet "refs/tags/$version" > /dev/null if [ $? -gt 0 ]; then echo "Bad version: $version" exit fi set -e fi # Make sure they mean it. confirm "☠️ Warning! 😳 This is highly destructive! 😱 Are you sure you wish to proceed?" echo "Okay ... good luck! 😰" # Hit the reset button. -docker-compose down --volumes --remove-orphans --rmi local +docker compose down --volumes --remove-orphans --rmi local # Remove any remaining (likely external) volumes with name matching 'sentry-.*'. for volume in $(docker volume list --format '{{ .Name }}' | grep '^sentry-'); do docker volume remove $volume > /dev/null \ && echo "Removed volume: $volume" \ || echo "Skipped volume: $volume" done # If we have a version given, switch to it. if [ -n "$version" ]; then git checkout "$version" fi # Install. ./install.sh