diaspora/script/diaspora-dev
Benjamin Neff ee593933a1
Add a pull command to update docker images to diaspora-dev script
Before the images were only pulled once and then never updated which
lead to really outdated images and OS dependencies. Now all images
(including the base image for the diaspora container) are pulled when
running `setup`. So the idea is to run the `setup` command from time to
time to bring everything up to date again.
2022-10-06 02:08:02 +02:00

627 lines
17 KiB
Bash
Executable file

#!/bin/bash
# ----- Usage information -----
print_usage() {
# Print help for the first argument
case "$1" in
# management
setup)
echo; echo "Set up the environment for diaspora*"
echo; echo "This command is an alias for the execution of the commands"
echo "build, config, pull, bundle, setup-rails and setup-tests, in that order."
echo; echo "This command can also be used to update the environment again."
print_usage_header "setup [options]" \
" --force Rebuild image without using Docker's cache;" \
" overwrite existing configuration" \
" --mysql Use MySQL as database (PostgreSQL is default)"
;;
start)
echo; echo "Start diaspora* (includes database)"
print_usage_header "start [options]" \
"-d Run in background"
;;
stop)
echo; echo "Stop diaspora* (includes database)"
print_usage_header "stop"
;;
restart)
echo; echo "Restart diaspora* using bin/eye (fast restart)"
print_usage_header "restart [options]" \
" --full Restart entire container"
;;
logs)
echo; echo "Follow log output of the running diaspora* instance"
print_usage_header "logs [options]" \
"-a, --all Follow all containers, including databases"
;;
status)
echo; echo "Show currently running diaspora* Docker container(s) and related image(s)"
print_usage_header "status"
;;
clean)
echo; echo "Delete diaspora* Docker containers and volumes (includes database)"
print_usage_header "clean [options]" \
" --config Delete configuration files as well"
;;
docker-compose)
echo; echo "Run docker-compose commands with the required environment variables"
print_usage_header "docker-compose [options]"
;;
# test & development
cucumber)
echo; echo "Run cucumber tests"
echo; echo "The specified cucumber tests will be executed. If none are given, all"
echo "tests are executed."
print_usage_header "cucumber [TEST...]"
;;
jasmine)
echo; echo "Run all jasmine tests"
print_usage_header "jasmine"
;;
rspec)
echo; echo "Run rspec tests"
echo; echo "The specified rspec tests will be executed. If none are given, all"
echo "tests will be executed."
print_usage_header "rspec"
;;
pronto)
echo; echo "Run pronto checks"
print_usage_header "pronto"
;;
migrate)
echo; echo "Execute pending migrations (incl. database setup)"
print_usage_header "migrate [options]" \
"-d Run in background"
;;
# misc
build)
echo; echo "(Re-)Build Docker image diaspora:dev-latest"
print_usage_header "build [options]" \
" --no-cache Rebuild image without using Docker's cache"
;;
pull)
echo; echo "Pull docker images needed for the development environment"
print_usage_header "pull"
;;
bundle)
echo; echo "Install gems using bundle into $DIASPORA_ROOT"
print_usage_header "bundle"
;;
yarn)
echo; echo "Install frontend dependencies using yarn into $DIASPORA_ROOT"
print_usage_header "yarn"
;;
config)
echo; echo "Create basic configuration files for usage with PostgreSQL (default)"
print_usage_header "config [options]" \
" --mysql Use MySQL as database (PostgreSQL is default)" \
" --overwrite Overwrite existing configuration"
;;
exec)
echo; echo "Execute a command in a diaspora* Docker container"
echo; echo "If there is no running diaspora* Docker container, a new one is created"
echo "and started."
print_usage_header "exec [options] COMMAND [ARGS...]" \
"-d Run in background"
;;
help)
echo; echo "Show help on a command"
print_usage_header "help COMMAND"
;;
setup-rails)
echo; echo "Set up development environment (install dependencies, migrate db, ...)"
print_usage_header "setup-rails"
;;
setup-tests)
echo; echo "Prepare cached files and database contents for tests"
print_usage_header "setup-tests"
;;
*)
print_usage_full
;;
esac
}
print_usage_header() {
# Print formatted usage information for COMMAND
# Usage: print_usage_header COMMAND [FLAG_DESCRIPTION...]
echo; echo "Usage: $1"
shift
if [ $# -gt 0 ]; then
echo; echo "Options:"
while [ $# -gt 0 ]; do
echo " $1"
shift
done
fi
}
print_usage_full() {
# Print overview of available commands
# $SCRIPT_NAME [help|-h|--help] leads here
echo; echo "Setup and run a diaspora instance for development in no time."
print_usage_header "$SCRIPT_NAME COMMAND"
echo
echo "Management Commands:"
echo " setup Prepare diaspora* to run for development"
echo " start Start diaspora*"
echo " stop Stop diaspora*"
echo " restart Restart of diaspora*"
echo " logs Follow log output of diaspora*"
echo " status Show current instance status of diaspora*"
echo " clean Reset diaspora* instance"
echo " docker-compose Run docker-compose commands"
echo
echo "Test and Development Commands:"
echo " cucumber Run cucumber tests"
echo " jasmine Run jasmine tests"
echo " rspec Run rspec tests"
echo " pronto Run pronto checks"
echo " migrate Execute pending migrations"
echo
echo "Misc. Commands:"
echo " build Build basic diaspora* environment"
echo " pull Update docker images"
echo " bundle (Re-)Install gems for diaspora*"
echo " yarn (Re-)Install frontend dependencies for diaspora*"
echo " config Configure diaspora*"
echo " exec Execute a command in the run environment (advanced)"
echo " help Show help for commands"
echo " setup-rails Prepare diaspora* development environment (install dependencies, migrate db)"
echo " setup-tests Prepare diaspora* test environment"
echo
echo "Run '$SCRIPT_NAME help COMMAND' for more information on a command."
}
# ----- Helper functions -----
dia_docker_compose() {
# Check permissions of docker socket and use sudo if needed
if [ -r "/var/run/docker.sock" ] && [ -w "/var/run/docker.sock" ]; then
docker-compose "$@"
else
echo "Attention: Docker socket not writable, using sudo for the docker command. You might be asked for your password now." >&2
sudo -E docker-compose "$@"
fi
}
dia_fetch_upstream() {
# Add and fetch upstream develop branch
if ! git remote show | grep -q '^upstream$'; then
git remote add upstream https://github.com/diaspora/diaspora.git
fi
git fetch upstream develop
}
dia_is_configured() {
# Check if config files exist
[ -f "$DIASPORA_CONFIG_DB" ] && [ -f "$DIASPORA_CONFIG_DIA" ]
}
exit_if_unconfigured() {
# Exit if config does not seem complete
if ! dia_is_configured; then
echo "Fatal: Config files missing. Run the 'setup' or 'config' command to configure."
exit 1
fi
}
dia_is_running() {
# Check if diaspora container is running
dia_docker_compose ps --services --filter status=running | grep -qx 'diaspora'
}
dia_is_db_running() {
# Check if db container is running
dia_docker_compose ps --services --filter status=running | grep -qx $DIASPORA_DOCKER_DB
}
dia_is_redis_running() {
# Check if redis container is running
dia_docker_compose ps --services --filter status=running | grep -qx redis
}
dia_get_db() {
# Get currently configured or assumed db type
grep -q '^ <<: \*mysql' "$DIASPORA_CONFIG_DB" 2>/dev/null && echo mysql || echo postgresql
}
# ----- Command functions -----
dia_build() {
if [ $# -gt 0 ] && [ "$1" == "--no-cache" ]; then nocache="--no-cache"; fi
# Build the diaspora Docker container (diaspora:dev-latest)
dia_docker_compose build --pull $nocache diaspora
}
dia_pull() {
dia_docker_compose pull redis $(dia_get_db)
}
dia_bundle() {
# Run bundle in order to install all gems into $DIASPORA_ROOT
# Do not start database, not required and sometimes not yet configured
echo "Installing gems via bundler ..."
dia_docker_compose run \
--rm \
--no-deps \
-e DIA_NODB=1 \
diaspora \
/bin/sh -c "gem install bundler && script/configure_bundler && bin/bundle install --full-index"
}
dia_yarn() {
# Run yarn in order to install all frontend dependencies into $DIASPORA_ROOT
# Do not start database, not required and sometimes not yet configured
echo "Installing frontend dependencies via yarn ..."
dia_docker_compose run --rm --no-deps -e DIA_NODB=1 diaspora bin/yarn
}
dia_clean() {
# Delete all containers and volumes
for i in "$@"; do
case "$i" in
--config)
dia_config_delete=1
;;
esac
done
dia_docker_compose down -v
if [ ! -z $dia_config_delete ]; then
rm "$DIASPORA_CONFIG_DIA" "$DIASPORA_CONFIG_DB"
fi
}
dia_config() {
# Create rudimentary configuration files if they don't exist
echo "Configuring diaspora ..."
for i in "$@"; do
case "$i" in
--mysql)
dia_config_mysql=1
;;
--overwrite)
dia_config_delete=1
;;
esac
done
[ ! -f "$DIASPORA_ROOT"/public/source.tar.gz ] && touch "$DIASPORA_ROOT"/public/source.tar.gz
# Delete existing files if requested
if [ ! -z $dia_config_delete ]; then
rm "$DIASPORA_CONFIG_DIA" "$DIASPORA_CONFIG_DB"
fi
# Create new diaspora.toml if none exists
if [ ! -f "$DIASPORA_CONFIG_DIA" ]; then
cp "$DIASPORA_CONFIG_DIA".example "$DIASPORA_CONFIG_DIA"
fi
# Select database type
if [ -z $dia_config_mysql ]; then
export DIASPORA_DOCKER_DB=postgresql
else
export DIASPORA_DOCKER_DB=mysql
fi
# Create new database.yml if none exists
if [ ! -f "$DIASPORA_CONFIG_DB" ]; then
sed -E '
/^postgresql/,/^[[:alpha:]]/ {
s/host:.*/host: postgresql/
s/password.*/password: postgres/
}
/^mysql/,/^[[:alpha:]]/ {
s/host:.*/host: mysql/
s/password:.*/password: mysql/
}
/^common/,/^[[:alpha:]]/ {
s/^(\s+<<:).*/\1 *'$DIASPORA_DOCKER_DB'/
}' "$DIASPORA_CONFIG_DB".example > "$DIASPORA_CONFIG_DB"
fi
# Update exisiting database.yml to reflect correct database type
if [ "$(dia_get_db)" != "$DIASPORA_DOCKER_DB" ]; then
sed -E -i'' '
/^common/,/^[[:alpha:]]/ {
s/^(\s+<<:).*/\1 *'$DIASPORA_DOCKER_DB'/
}' "$DIASPORA_CONFIG_DB"
fi
}
dia_cucumber() {
# Run cucumber tests
if [ "$1" == "-d" ]; then detach="-d"; shift; fi
dia_docker_compose run \
--rm $detach \
diaspora \
bin/cucumber "$@"
}
dia_exec() {
# Run a custom command inside a running diaspora container. Start a new one if necessary.
exit_if_unconfigured
if [ "$1" == "-d" ]; then detach="-d"; shift; fi
if dia_is_running; then
# Use a running container
dia_docker_compose exec $detach diaspora /exec-entrypoint.sh "$@"
else
# stop db/redis if it was not running before
if ! dia_is_db_running; then stopdb="dia_docker_compose stop $DIASPORA_DOCKER_DB"; fi
if ! dia_is_redis_running; then stopredis="dia_docker_compose stop redis"; fi
# Start a new container
echo "No running instance found, starting new one for command execution ..."
dia_docker_compose run --rm $detach --service-ports diaspora "$@"
$stopdb
$stopredis
fi
}
dia_jasmine() {
# Run jasmine tests
dia_docker_compose run \
--rm $1 \
-e RAILS_ENV=test \
diaspora \
bin/rake jasmine:ci
}
dia_logs() {
# Show logs of running diaspora* instance
dia_follow=diaspora
for i in "$@"; do
case "$i" in
-a|--all)
dia_follow=""
;;
esac
done
dia_docker_compose logs -f --tail=100 $dia_follow
}
dia_migrate() {
# Run migrations if configured
echo "Creating and/or migrating database ..."
exit_if_unconfigured
dia_docker_compose run \
--rm $1 \
diaspora \
bin/rake db:create db:migrate
}
dia_pronto() {
# Run pronto checks
exit_if_unconfigured
cd "$DIASPORA_ROOT"
if git diff-index --quiet HEAD --; then
dia_fetch_upstream
fi
cd - >/dev/null
dia_docker_compose run \
--rm \
--no-deps \
diaspora \
bin/pronto run --unstaged -c upstream/develop
}
dia_restart() {
# Restart diaspora inside container if already running; start new container otherwise
for i in "$@"; do
case "$i" in
--full)
dia_restart_full=1
;;
esac
done
if dia_is_running; then
if [ -z $dia_restart_full ]; then
dia_docker_compose exec \
diaspora \
bin/eye restart diaspora
else
dia_docker_compose restart
fi
else
dia_start
fi
}
dia_rspec() {
# Run rspec tests
exit_if_unconfigured
assets=""
# Assumption: If (and only if) the tested file is not available, assets need be regenerated
[ -f "$DIASPORA_ROOT"/public/404.html ] && assets="assets:generate_error_pages"
# Prepare database (and assets if necessary)
dia_docker_compose run \
--rm \
-e RAILS_ENV=test \
diaspora \
bin/rake db:create db:migrate $assets
# Run tests
dia_docker_compose run \
--rm \
diaspora \
bin/rspec "$@"
}
dia_setup() {
# Prepare the entire environment for development
for i in "$@"; do
case "$i" in
--force)
build="$build --no-cache"
config="$config --overwrite"
;;
--mysql)
config="$config --mysql"
;;
esac
done
(
set -e
dia_build $build
dia_config $config
dia_pull
dia_bundle
dia_setup_rails
dia_setup_tests
)
# stop db afterwards as it is not needed while dia is not running
dia_docker_compose stop $DIASPORA_DOCKER_DB
}
dia_setup_rails() {
# Prepare rails, install dependencies, migrate database, ...
echo "Setting up environment for tests ..."
# stop db/redis if it was not running before
if ! dia_is_db_running; then stopdb="dia_docker_compose stop $DIASPORA_DOCKER_DB"; fi
if ! dia_is_redis_running; then stopredis="dia_docker_compose stop redis"; fi
dia_docker_compose run --rm diaspora bin/setup
$stopdb
$stopredis
}
dia_setup_tests() {
# Prepare all possible tests
echo "Setting up environment for tests ..."
# stop db/redis if it was not running before
if ! dia_is_db_running; then stopdb="dia_docker_compose stop $DIASPORA_DOCKER_DB"; fi
if ! dia_is_redis_running; then stopredis="dia_docker_compose stop redis"; fi
dia_docker_compose run \
--rm \
-e RAILS_ENV=test \
diaspora \
bin/rake db:create db:migrate tests:generate_fixtures assets:generate_error_pages
$stopdb
$stopredis
}
dia_start() {
# Start all containers if config appears to exist
exit_if_unconfigured
if [ $# -eq 0 ]; then
options=--abort-on-container-exit
else
options=$1
fi
dia_docker_compose up $options diaspora
}
dia_status() {
# Print running containers and current images
dia_docker_compose ps
echo
dia_docker_compose images
}
dia_stop() {
# Stop all containers
dia_docker_compose stop
}
# ----- Variables -----
# Symlinks are treated as files
export SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}")
export SCRIPT_ROOT=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# Assumption: The script is in the "script" subfolder of the diaspora root folder
export DIASPORA_ROOT=$(dirname "$SCRIPT_ROOT")
export DIASPORA_ROOT_UID=1001
export DIASPORA_ROOT_GID=1001
export DIASPORA_CONFIG_DIA=$DIASPORA_ROOT/config/diaspora.toml
export DIASPORA_CONFIG_DB=$DIASPORA_ROOT/config/database.yml
export DIASPORA_DOCKER_DB=$(dia_get_db)
export COMPOSE_FILE=$DIASPORA_ROOT/docker/develop/docker-compose.yml
export COMPOSE_PROJECT_NAME=diasporadev
# ----- Arg parsing -----
if [ $# -lt 1 ]; then
print_usage
exit 1
fi
dia_command=$1
shift
case "$dia_command" in
--help|-h)
print_usage_full
exit 0
;;
help)
if [ $# -lt 1 ]; then
print_usage_full
else
print_usage "$1"
fi
exit 0
;;
build)
dia_build "$@"
;;
bundle)
dia_bundle
;;
clean)
dia_clean "$@"
;;
config)
dia_config "$@"
;;
cucumber)
dia_cucumber "$@"
;;
docker-compose)
dia_docker_compose "$@"
;;
exec)
dia_exec "$@"
;;
jasmine)
dia_jasmine
;;
logs)
dia_logs "$@"
;;
migrate)
dia_migrate "$@"
;;
pronto)
dia_pronto
;;
pull)
dia_pull
;;
restart)
dia_restart "$@"
;;
rspec)
dia_rspec "$@"
;;
setup)
dia_setup "$@"
;;
setup-rails)
dia_setup_rails
;;
setup-tests)
dia_setup_tests
;;
start)
dia_start "$1"
;;
status)
dia_status
;;
stop)
dia_stop
;;
yarn)
dia_yarn
;;
*)
print_usage
exit 1
;;
esac