#!/bin/bash # # entrypoint script for webschlocker # # handle signals trap abort SIGHUP SIGINT SIGQUIT SIGTERM SIGSTOP SIGKILL function abort { echo echo "* * * ABORTED * * *" echo exit 0 } # who to run as [ -z ${WEBSCHLOCKER_USER+x} ] && WEBSCHLOCKER_USER="webschlocker" [ -z ${WEBSCHLOCKER_GROUP+x} ] && WEBSCHLOCKER_GROUP="webschlocker" # bind IP and port [ -z ${WEBSCHLOCKER_BIND_ADDRESS+x} ] && WEBSCHLOCKER_BIND_ADDRESS="0.0.0.0" [ -z ${WEBSCHLOCKER_BIND_PORT+x} ] && WEBSCHLOCKER_BIND_PORT="3000" # schleuder-web config [ -z ${WEBSCHLOCKER_CONFIG_HOSTNAME+x} ] && WEBSCHLOCKER_CONFIG_HOSTNAME=$( hostname ) [ -z ${WEBSCHLOCKER_CONFIG_MAILER_FROM+x} ] && WEBSCHLOCKER_CONFIG_MAILER_FROM="noreply@$WEBSCHLOCKER_CONFIG_HOSTNAME" [ -z ${WEBSCHLOCKER_CONFIG_DELIVERY_METHOD+x} ] && WEBSCHLOCKER_CONFIG_DELIVERY_METHOD="smtp" [ -z ${WEBSCHLOCKER_CONFIG_SENDMAIL_ARGUMENTS+x} ] && WEBSCHLOCKER_CONFIG_SENDMAIL_ARGUMENTS="-t -i -f" [ -z ${WEBSCHLOCKER_CONFIG_SMTP_ADDRESS+x} ] && WEBSCHLOCKER_CONFIG_SMTP_ADDRESS="localhost" [ -z ${WEBSCHLOCKER_CONFIG_SMTP_PORT+x} ] && WEBSCHLOCKER_CONFIG_SMTP_PORT="25" [ -z ${WEBSCHLOCKER_CONFIG_OPENSSL_VERIFY_MODE+x} ] && WEBSCHLOCKER_CONFIG_OPENSSL_VERIFY_MODE="none" [ -z ${WEBSCHLOCKER_CONFIG_API_HOST+x} ] && WEBSCHLOCKER_CONFIG_API_HOST="localhost" [ -z ${WEBSCHLOCKER_CONFIG_API_PORT+x} ] && WEBSCHLOCKER_CONFIG_API_PORT="4443" [ -z ${WEBSCHLOCKER_CONFIG_API_TLS_FINGERPRINT+x} ] && WEBSCHLOCKER_CONFIG_API_TLS_FINGERPRINT="" [ -z ${WEBSCHLOCKER_CONFIG_API_KEY+x} ] && WEBSCHLOCKER_CONFIG_API_KEY="" # db settings [ -z ${WEBSCHLOCKER_DB_ADAPTER+x} ] && WEBSCHLOCKER_DB_ADAPTER="sqlite3" [ -z ${WEBSCHLOCKER_DB_DATABASE+x} ] && WEBSCHLOCKER_DB_DATABASE="/var/schleuder-web/db.sqlite3" # these are unused by default, only useful with mysql/postgresql/etc [ -z ${WEBSCHLOCKER_DB_ENCODING+x} ] && WEBSCHLOCKER_DB_ENCODING="" [ -z ${WEBSCHLOCKER_DB_USERNAME+x} ] && WEBSCHLOCKER_DB_USERNAME="" [ -z ${WEBSCHLOCKER_DB_PASSWORD+x} ] && WEBSCHLOCKER_DB_PASSWORD="" [ -z ${WEBSCHLOCKER_DB_HOST+x} ] && WEBSCHLOCKER_DB_HOST="" # secret key base [ -z ${WEBSCHLOCKER_SECRET_KEY_BASE+x} ] && WEBSCHLOCKER_SECRET_KEY_BASE="$( echo $RANDOM | sha256sum | sed -r -e 's/\s+-//' )$( echo $RANDOM | sha256sum | sed -r -e 's/\s+-//' )" # only internal use for the time being WEBSCHLOCKER_CONFIG_DIR="/opt/schleuder-web/config" WEBSCHLOCKER_LOG_DIR="/opt/schleuder-web/log" WEBSCHLOCKER_TMP_DIR="/opt/schleuder-web/tmp" WEBSCHLOCKER_PUBLIC_DIR="/opt/schleuder-web/public" # # inform echo "+-- working with:" echo " +-- WEBSCHLOCKER_USER : $WEBSCHLOCKER_USER" echo " +-- WEBSCHLOCKER_GROUP : $WEBSCHLOCKER_GROUP" echo " +-- WEBSCHLOCKER_BIND_ADDRESS : $WEBSCHLOCKER_BIND_ADDRESS" echo " +-- WEBSCHLOCKER_BIND_PORT : $WEBSCHLOCKER_BIND_PORT" # # root is not what we want as the user to run as # # let's make sure we're not running as root, shall we? if [ "$WEBSCHLOCKER_UID" == "0" ] || [ "$WEBSCHLOCKER_USER" == "root" ] || [ "$WEBSCHLOCKER_GID" == "0" ] || [ "$WEBSCHLOCKER_GROUP" == "root" ]; then echo echo "* * * ERROR: trying to run as root -- I cannot let you do that, Dave!" echo exit 1 fi # get group data, if any, and check if the group exists if GROUP_DATA=`getent group "$WEBSCHLOCKER_GROUP"`; then # it does! do we have the gid given? if [[ "$WEBSCHLOCKER_GID" != "" ]]; then # we do! do these match? if [[ `echo "$GROUP_DATA" | cut -d ':' -f 3` != "$WEBSCHLOCKER_GID" ]]; then # they don't. we have a problem echo "ERROR: group $WEBSCHLOCKER_GROUP already exists, but with a different gid (`echo "$GROUP_DATA" | cut -d ':' -f 3`) than provided ($WEBSCHLOCKER_GID)!" exit 3 fi fi # if no gid given, the existing group satisfies us regardless of the GID # group does not exist else # do we have the gid given? GID_ARGS="" if [[ "$WEBSCHLOCKER_GID" != "" ]]; then # we do! does a group with a given id exist? if getent group "$WEBSCHLOCKER_GID" >/dev/null; then echo "ERROR: a group with a given id ($WEBSCHLOCKER_GID) already exists, can't create group $WEBSCHLOCKER_GROUP with this id" exit 4 fi # prepare the fragment of the groupadd command GID_ARGS="-g $WEBSCHLOCKER_GID" fi # we either have no GID given (and don't care about it), or have a GID given that does not exist in the system # great! let's add the group groupadd $GID_ARGS "$WEBSCHLOCKER_GROUP" fi # get user data, if any, and check if the user exists if USER_DATA=`id -u "$WEBSCHLOCKER_USER" 2>/dev/null`; then # it does! do we have the uid given? if [[ "$WEBSCHLOCKER_UID" != "" ]]; then # we do! do these match? if [[ "$USER_DATA" != "$WEBSCHLOCKER_UID" ]]; then # they don't. we have a problem echo "ERROR: user $WEBSCHLOCKER_USER already exists, but with a different uid ("$USER_DATA") than provided ($WEBSCHLOCKER_UID)!" exit 5 fi fi # if no uid given, the existing user satisfies us regardless of the uid # but is he in the right group? adduser "$WEBSCHLOCKER_USER" "$WEBSCHLOCKER_GROUP" # user does not exist else # do we have the uid given? UID_ARGS="" if [[ "$WEBSCHLOCKER_UID" != "" ]]; then # we do! does a group with a given id exist? if getent passwd "$WEBSCHLOCKER_UID" >/dev/null; then echo "ERROR: a user with a given id ($WEBSCHLOCKER_UID) already exists, can't create user $WEBSCHLOCKER_USER with this id" exit 6 fi # prepare the fragment of the useradd command UID_ARGS="-u $WEBSCHLOCKER_UID" fi # we either have no UID given (and don't care about it), or have a UID given that does not exist in the system # great! let's add the user useradd $UID_ARGS -r -g "$WEBSCHLOCKER_GROUP" "$WEBSCHLOCKER_USER" fi # # config # # # create the webschlocker config file, if it doesn't exist # see: https://git.codecoop.org/schleuder/schleuder-web/blob/master/config/schleuder-web.yml if [ ! -e "$WEBSCHLOCKER_CONFIG_DIR/schleuder-web.yml" ]; then echo "+-- no config file found in '$WEBSCHLOCKER_CONFIG_DIR/schleuder-web.yml', creating one..." # hopefully the unneeded settings will be ignored ;) # For delivery_method, sendmail_settings and smtp_settings see # . # # yes, the "defaults:" section is required, even though we're not using it. WEBSCHLOCKER_CONFIG=" defaults: {} production: web_hostname: $WEBSCHLOCKER_CONFIG_HOSTNAME api: host: $WEBSCHLOCKER_CONFIG_API_HOST port: $WEBSCHLOCKER_CONFIG_API_PORT tls_fingerprint: $WEBSCHLOCKER_CONFIG_API_TLS_FINGERPRINT api_key: $WEBSCHLOCKER_CONFIG_API_KEY mailer_from: $WEBSCHLOCKER_CONFIG_MAILER_FROM delivery_method: $WEBSCHLOCKER_CONFIG_DELIVERY_METHOD sendmail_settings: arguments: $WEBSCHLOCKER_CONFIG_SENDMAIL_ARGUMENTS smtp_settings: address: $WEBSCHLOCKER_CONFIG_SMTP_ADDRESS port: $WEBSCHLOCKER_CONFIG_SMTP_PORT #openssl_verify_mode: $WEBSCHLOCKER_CONFIG_OPENSSL_VERIFY_MODE " echo -e "$WEBSCHLOCKER_CONFIG" > "$WEBSCHLOCKER_CONFIG_DIR/schleuder-web.yml" else echo "+-- config file found in '$WEBSCHLOCKER_CONFIG_DIR/schleuder-web.yml', ignoring \$WEBSCHLOCKER_CONFIG_* envvars" fi # # create the database config file, if it doesn't exist # see: https://git.codecoop.org/schleuder/schleuder-web/blob/master/config/database.yml if [ ! -e "$WEBSCHLOCKER_CONFIG_DIR/database.yml" ]; then echo "+-- no database config file found in '$WEBSCHLOCKER_CONFIG_DIR/database.yml', creating one..." # let's hope the unneeded settings get ignored WEBSCHLOCKER_DATABASE=" production: pool: 5 timeout: 5000 adapter: $WEBSCHLOCKER_DB_ADAPTER database: $WEBSCHLOCKER_DB_DATABASE encoding: $WEBSCHLOCKER_DB_ENCODING username: $WEBSCHLOCKER_DB_USERNAME password: $WEBSCHLOCKER_DB_PASSWORD host: $WEBSCHLOCKER_DB_HOST " mkdir -p "$WEBSCHLOCKER_CONFIG_DIR" echo -e "$WEBSCHLOCKER_DATABASE" > "$WEBSCHLOCKER_CONFIG_DIR/database.yml" # when using sqlite, let's make sure the database directory is accessible/writable for the user if [ "$WEBSCHLOCKER_DB_ADAPTER" == "sqlite3" ]; then mkdir -p "$( dirname "$WEBSCHLOCKER_DB_DATABASE" )" chown -R "$WEBSCHLOCKER_USER:$WEBSCHLOCKER_GROUP" "$( dirname "$WEBSCHLOCKER_DB_DATABASE" )" fi else echo "+-- database config file found in '$WEBSCHLOCKER_CONFIG_DIR/database.yml', ignoring \$WEBSCHLOCKER_DB_* envvars" fi # # secrets file # see: https://git.codecoop.org/schleuder/schleuder-web/blob/master/config/secrets.yml if [ ! -e "$WEBSCHLOCKER_CONFIG_DIR/secrets.yml" ]; then echo "+-- no secrets file found in $WEBSCHLOCKER_CONFIG_DIR/secrets.yml, creating one..." WEBSCHLOCKER_SECRETS=" production: secret_key_base: $WEBSCHLOCKER_SECRET_KEY_BASE " echo -e "$WEBSCHLOCKER_SECRETS" > "$WEBSCHLOCKER_CONFIG_DIR/secrets.yml" else echo "+-- secrets file found in '$WEBSCHLOCKER_CONFIG_DIR/secrets.yml', ignoring \$WEBSCHLOCKER_SECRET_KEY_BASE* envvar" fi # # log directory echo "+-- creating and setting permissions on the log directory '$WEBSCHLOCKER_LOG_DIR'" mkdir -p "$WEBSCHLOCKER_LOG_DIR" chown -R "$WEBSCHLOCKER_USER:$WEBSCHLOCKER_GROUP" "$WEBSCHLOCKER_LOG_DIR" # # tmp directory echo "+-- creating and setting permissions on the tmp directory '$WEBSCHLOCKER_TMP_DIR'" mkdir -p "$WEBSCHLOCKER_TMP_DIR" chown -R "$WEBSCHLOCKER_USER:$WEBSCHLOCKER_GROUP" "$WEBSCHLOCKER_TMP_DIR" # # public assets directory echo "+-- creating and setting permissions on the public assets directory '$WEBSCHLOCKER_PUBLIC_DIR'" mkdir -p "$WEBSCHLOCKER_PUBLIC_DIR" chown -R "$WEBSCHLOCKER_USER:$WEBSCHLOCKER_GROUP" "$WEBSCHLOCKER_PUBLIC_DIR" # which version of the db we have? echo "+-- checking db schema version..." WEBSCHLEUDER_SCHEMA_VERSION="$( su -p -c "env PATH=\"$PATH\" bundle exec rake db:version RAILS_ENV=production" "$WEBSCHLOCKER_USER" | awk '/^Current version:/ {print $3}' )" if [[ $WEBSCHLEUDER_SCHEMA_VERSION > 0 ]]; then echo " +-- database schema version found: $WEBSCHLEUDER_SCHEMA_VERSION, no need for set-up" else # prep the database (as the correct user) echo " +-- database schema not found, setting up the database" su -p -c "env PATH=\"$PATH\" bundle exec rake db:setup RAILS_ENV=production" "$WEBSCHLOCKER_USER" fi # precompile assets su -p -c "env PATH=\"$PATH\" bundle exec rake assets:precompile RAILS_ENV=production" "$WEBSCHLOCKER_USER" # make sure the envvars are available within su export WEBSCHLOCKER_BIND_ADDRESS WEBSCHLOCKER_BIND_PORT # inform the user echo "+-- schleuder-web is available on port $WEBSCHLOCKER_BIND_PORT at:" if [ "$WEBSCHLOCKER_BIND_ADDRESS" == "0.0.0.0" ]; then ip -4 addr show scope global | grep inet | sed -r -e 's%inet.? (.+)/[0-9]{2,}.+%\1%' else echo " $WEBSCHLOCKER_BIND_ADDRESS" fi # do the magic! echo echo "+-- executing:" echo " $*" exec su -p -c "env PATH=\"$PATH\" $*" "$WEBSCHLOCKER_USER"