Skip to content

Instantly share code, notes, and snippets.

@agrawalsuneet
Created March 1, 2023 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agrawalsuneet/9357c83d977d6131a6fc19296dd32ea9 to your computer and use it in GitHub Desktop.
Save agrawalsuneet/9357c83d977d6131a6fc19296dd32ea9 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# NB: local trial script has to be self-contained
# See https://sipb.mit.edu/doc/safe-shell/
set -euf -o pipefail
if [[ "$OSTYPE" == "linux-gnu" ]]; then
export MAYBE_SUDO="sudo"
else
export MAYBE_SUDO=""
fi
if [ -t 1 ]; then
export NORMAL="$(tput sgr0)"
export RED="$(tput setaf 1)"
export GREEN="$(tput setaf 2)"
export MAGENTA="$(tput setaf 5)"
export CYAN="$(tput setaf 6)"
export WHITE="$(tput setaf 7)"
export BOLD="$(tput bold)"
else
export NORMAL=""
export RED=""
export GREEN=""
export MAGENTA=""
export CYAN=""
export WHITE=""
export BOLD=""
fi
error_exit() {
echo "${RED}${BOLD}ERROR${NORMAL}${BOLD}: $1${NORMAL}"
shift
while [ "$#" -gt "0" ]; do
echo " - $1"
shift
done
exit 1
}
log_step() {
echo ''
echo "${GREEN}${BOLD}INFO${NORMAL}${BOLD}: $1${NORMAL}"
shift
while [ "$#" -gt "0" ]; do
echo " - $1"
shift
done
}
log_warn() {
echo ''
echo "${GREEN}${BOLD}INFO${NORMAL}${BOLD}: $1${NORMAL}"
shift
while [ "$#" -gt "0" ]; do
echo " - $1"
shift
done
}
export DISTRO=$( (lsb_release -ds || cat /etc/*release || uname -om) 2>/dev/null | head -n1)
command_present() {
type "$1" >/dev/null 2>&1
}
retool_containers_present() {
# NB: awk is to remove whitespace from `wc`
RETOOL_IMAGES="$($MAYBE_SUDO docker image ls | grep 'retool.*onpremise' | wc -l | awk '{print $1}')"
test "$RETOOL_IMAGES" -gt '0'
}
retool_trial_running() {
# NB: awk is to remove whitespace from `wc`
CONTAINERS="$($MAYBE_SUDO docker-compose ps -q | wc -l | awk '{print $1}')"
test "$CONTAINERS" -gt '0'
}
# NB: trim trailing slash on $TMPDIR as different OS's do it differently
INSTALL_DIRECTORY="$HOME/retool"
DOCKER_CONTEXT="$INSTALL_DIRECTORY/retool-onpremise"
cd "$HOME"
if [ ! -d "$DOCKER_CONTEXT" ]; then
if [ -d "$INSTALL_DIRECTORY" ]; then
log_step 'found a partial install, cleaning it up...'
rm -rf "$INSTALL_DIRECTORY"
fi
log_step 'setting up install location...' "$INSTALL_DIRECTORY"
mkdir retool && cd retool
if ! command_present unzip; then
log_warn '`unzip` not found!'
log_warn 'Attempting to git clone instead'
if command_present git; then
log_step 'cloning...'
git clone https://github.com/tryretool/retool-onpremise.git
elif command_present yum; then
log_warn 'You did not have git so installing'
sudo yum install git
git clone https://github.com/tryretool/retool-onpremise.git
else
error_exit "Please install git or unzip before continuing"
fi
else
log_step 'downloading...'
curl -L -XGET -o master.zip https://github.com/tryretool/retool-onpremise/archive/refs/heads/ssop.zip # TODO(hirday): change back to master
log_step 'unpacking...'
unzip master.zip
mv retool-onpremise-ssop retool-onpremise # TODO(hirday): change back to master
fi
# NB: this is to make onprem containers to all get named the same.
cd retool-onpremise
if ! command_present unzip; then
git checkout ssop # TODO(hirday): delete this.
fi
DOCKER_CONTEXT="$(pwd)"
log_step 'setting environment variables'
cp ./docker.env.trial docker.env
read -p "Enter your license key: " licenseKey
echo "LICENSE_KEY=$licenseKey" >> docker.env
else
cd "$DOCKER_CONTEXT" || error_exit "Couldn't \`cd\` into '$DOCKER_CONTEXT'" \
"if you are having repeat issues, you can \`rm -rf $INSTALL_DIRECTORY\`" \
"if you're still having issues, you can stop all docker containers using the \`docker\` command"
fi
if ! command_present docker; then
# shellcheck disable=2016
log_warn '`docker` not found! Attempting to install. This may take a few minutes.'
./get-docker.sh
if ! command_present docker; then
if [[ "$OSTYPE" == "darwin"* ]]; then
error_exit "please install \`docker\` manually" \
"Instructions can be found at ${WHITE}${BOLD}https://docs.docker.com/${NORMAL}" \
"${BOLD}Remember${NORMAL} to start the \`Docker\` app from the UI."
else
error_exit "please install \`docker\` manually" \
"Instructions can be found at ${WHITE}${BOLD}https://docs.docker.com/${NORMAL}" \
"${BOLD}Remember${NORMAL} to start the \`docker\` daemon/service."
fi
fi
else
# shellcheck disable=2016
log_step '`docker` found!'
fi
if [[ $DISTRO == *"CentOS"* ]]; then
echo 'Starting docker service and making compose accessible by root user'
sudo systemctl enable docker.service
sudo systemctl start docker.service
fi
if retool_containers_present; then
log_step 'noticed you have tried Retool before, cleaning up...'
$MAYBE_SUDO docker-compose rm -fsv
fi
if (! $MAYBE_SUDO docker stats --no-stream) && [ "$OSTYPE" == "linux-gnu" ] && [ "$DISTRO" != "*centos*" ]; then
sudo docker service start
fi
if retool_trial_running; then
log_step 'stopping Retool for update...'
$MAYBE_SUDO docker-compose down
fi
if [ ! -f ./docker-compose-ssl.yml ]; then
mv docker-compose.yml docker-compose-ssl.yml
fi
if [ -f ./docker-compose-local-trial.yml ]; then
mv docker-compose-local-trial.yml docker-compose.yml
fi
log_step 'updating Retool!'
$MAYBE_SUDO docker-compose pull
log_step "running Retool! ${WHITE}${BOLD}This can take up to 5 minutes${NORMAL}"
$MAYBE_SUDO docker-compose up -d
echo ""
echo " -- ${GREEN}${BOLD}!! RETOOL IS BOOTING !!${NORMAL} --"
# NB: the API doesn't start up the first time, this is why the below is complex
WAITED=0
API_CONTAINER_ID=""
api_container_up() {
API_DOCKER_CONTAINER_UP=$($MAYBE_SUDO docker-compose ps --filter "status=running" | grep 'retool.*api'| wc -l | awk '{print $1}')
test "$API_DOCKER_CONTAINER_UP" -gt '0'
}
api_running() {
healthcheck_response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/checkHealth)
test $healthcheck_response -eq 200
}
printf "%s%s%s%s" "Waiting for Retool to start up... " "${RED}${BOLD}" "<Pressing Ctrl-C may prevent proper start-up>" "$NORMAL"
while [ $WAITED -lt 20 ] && api_container_up; do
WAITED=$((WAITED + 1))
sleep 1
done
if ! api_container_up; then
$MAYBE_SUDO docker-compose up -d > /dev/null 2>&1
WAITED=0
while [ $WAITED -lt 10 ] && ! api_container_up; do
WAITED=$((WAITED + 1))
sleep 1
done
fi
# Due to a race condition with migration runner, check if api container stays up for 20 seconds.
WAITED=0
while [ $WAITED -lt 20 ]; do
if ! api_container_up; then
$MAYBE_SUDO docker-compose up -d > /dev/null 2>&1
fi
WAITED=$((WAITED + 1))
sleep 1
done
if ! api_container_up; then
echo "ERROR: Failed starting the Retool api container"
exit 1
else
API_CONTAINER_ID=$( $MAYBE_SUDO docker inspect --format="{{.Id}}" $($MAYBE_SUDO docker-compose ps | grep 'retool.*api' | cut -d ' ' -f 1)
)
fi
WAITED=0
# one request every three seconds. It takes about 40 seconds for the api to get ready so 2 minute should be enough margin
while [ $WAITED -lt 40 ] && ! api_running; do
WAITED=$((WAITED + 1))
# Breaking early if the container already failed due to error.
if ! $($MAYBE_SUDO docker container inspect -f {{.State.Running}} $API_CONTAINER_ID ); then
break
fi
sleep 3
done
if ! api_running; then
echo "There was an issue starting the Retool container"
echo "You can view the logs by running: docker logs $API_CONTAINER_ID')"
exit 1
fi
# NB: empty stuff to fully wipe out previous line completely
printf "\r%s%s%s%s%s%s%s%s" "$MAGENTA" 'Check out your ' "$BOLD" 'BROWSER' "${NORMAL}${MAGENTA}" ' for some awesomeness!!!' "$NORMAL" ' '
echo
echo ""
echo " ${CYAN}Navigate to${NORMAL}: ${WHITE}${BOLD}http://localhost:3000/auth/signup${NORMAL} or ${WHITE}${BOLD}[publically_accessible_ip]:3000/auth/signup${NORMAL}"
echo " ${CYAN}To STOP Retool, run${NORMAL}: ${WHITE}${BOLD}${DOCKER_CONTEXT}/stop-local-trial${NORMAL}"
echo " ${CYAN}To RESTART Retool, run${NORMAL}: ${WHITE}${BOLD}${DOCKER_CONTEXT}/local-trial${NORMAL}"
echo ""
echo "Retool was installed in ~/retool. It will run in the background until you manually stop it. If Retool stops you can restart it without losing your data. "
if command_present open; then
open 'http://localhost:3000/auth/signup'
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment