#!/bin/sh set -e echoerr() { printf "%s\n" "$*" >&2; } # # Read environment variables from file if envrionment variable ${1}_FILE is set # file_env() { local var="" local fileVar="" eval var="\$${1}" eval fileVar="\$${1}_FILE" local def="${2:-}" if [ -n "${var:-}" ] && [ -n "${fileVar:-}" ]; then echo >&2 "error: both ${1} and ${1}_FILE are set (but are exclusive)" exit 1 fi local val="$def" if [ -n "${var:-}" ]; then val="${var}" elif [ -n "${fileVar:-}" ]; then val="$(cat "${fileVar}")" fi if [ -n "${val:-}" ]; then export "${1}"="$val" fi unset "${1}_FILE" } export SEMAPHORE_CONFIG_PATH="${SEMAPHORE_CONFIG_PATH:-/etc/semaphore}" export SEMAPHORE_DB_PATH="${SEMAPHORE_DB_PATH:-/var/lib/semaphore}" export SEMAPHORE_DB_PORT="${SEMAPHORE_DB_PORT:-}" file_env 'SEMAPHORE_DB_USER' file_env 'SEMAPHORE_DB_PASS' file_env 'SEMAPHORE_ADMIN' export SEMAPHORE_ADMIN_EMAIL="${SEMAPHORE_ADMIN_EMAIL:-admin@localhost}" export SEMAPHORE_ADMIN_NAME="${SEMAPHORE_ADMIN_NAME:-Semaphore Admin}" file_env 'SEMAPHORE_ADMIN_PASSWORD' export SEMAPHORE_LDAP_ACTIVATED="${SEMAPHORE_LDAP_ACTIVATED:-no}" export SEMAPHORE_LDAP_HOST="${SEMAPHORE_LDAP_HOST:-}" export SEMAPHORE_LDAP_PORT="${SEMAPHORE_LDAP_PORT:-}" export SEMAPHORE_LDAP_DN_BIND="${SEMAPHORE_LDAP_DN_BIND:-}" file_env 'SEMAPHORE_LDAP_PASSWORD' export SEMAPHORE_LDAP_DN_SEARCH="${SEMAPHORE_LDAP_DN_SEARCH:-}" export SEMAPHORE_LDAP_MAPPING_USERNAME="${SEMAPHORE_LDAP_MAPPING_USERNAME:-uid}" export SEMAPHORE_LDAP_MAPPING_FULLNAME="${SEMAPHORE_LDAP_MAPPING_FULLNAME:-cn}" export SEMAPHORE_LDAP_MAPPING_EMAIL="${SEMAPHORE_LDAP_MAPPING_EMAIL:-mail}" file_env 'SEMAPHORE_ACCESS_KEY_ENCRYPTION' [ -d "${SEMAPHORE_CONFIG_PATH}" ] || mkdir -p "${SEMAPHORE_CONFIG_PATH}" || { echo "Can't create Semaphore config path ${SEMAPHORE_CONFIG_PATH}." exit 1 } [ -d "${SEMAPHORE_DB_PATH}" ] || mkdir -p "${SEMAPHORE_DB_PATH}" || { echo "Can't create Semaphore data path ${SEMAPHORE_DB_PATH}." exit 1 } # # Extract database host and port from config.json if they are not set. # Set default SEMAPHORE_DB_DIALECT and SEMAPHORE_DB_HOST if empty. # if [ -z "${SEMAPHORE_DB_DIALECT}" ]; then if [ -f "${SEMAPHORE_CONFIG_PATH}/config.json" ]; then SEMAPHORE_DB_DIALECT=$(cat "${SEMAPHORE_CONFIG_PATH}/config.json" | jq '.dialect // ""' -r) fi fi export SEMAPHORE_DB_DIALECT="${SEMAPHORE_DB_DIALECT:-mysql}" if [ -z "${SEMAPHORE_DB_HOST}" ]; then if [ -f "${SEMAPHORE_CONFIG_PATH}/config.json" ]; then SEMAPHORE_DB_HOST=$(cat "${SEMAPHORE_CONFIG_PATH}/config.json" | jq ".${SEMAPHORE_DB_DIALECT}.host // \"\"" -r) fi fi if [ -z "${SEMAPHORE_DB_HOST}" ]; then if [ "${SEMAPHORE_DB_DIALECT}" == 'bolt' ]; then export SEMAPHORE_DB_HOST=${SEMAPHORE_DB_PATH}/database.boltdb else export SEMAPHORE_DB_HOST="${SEMAPHORE_DB_HOST:-0.0.0.0}" fi fi # # Remove port number from SEMAPHORE_DB_HOST and put it to SEMAPHORE_DB_PORT # case "$SEMAPHORE_DB_HOST" in *:*) SEMAPHORE_DB_PORT=$(echo "$SEMAPHORE_DB_HOST" | cut -d ':' -f 2) SEMAPHORE_DB_HOST=$(echo "$SEMAPHORE_DB_HOST" | cut -d ':' -f 1) ;; *) esac # # Set SEMAPHORE_DB_PORT if it is not set # if [ -z "${SEMAPHORE_DB_PORT}" ]; then case ${SEMAPHORE_DB_DIALECT} in mysql) SEMAPHORE_DB_PORT=3306 ;; postgres) SEMAPHORE_DB_PORT=5432 ;; bolt) ;; *) echoerr "Unknown database dialect: ${SEMAPHORE_DB_DIALECT}" exit 1 ;; esac fi # # Ping database if it is not BoltDB # if [ "${SEMAPHORE_DB_DIALECT}" != 'bolt' ]; then echoerr "Pinging database on ${SEMAPHORE_DB_HOST} port ${SEMAPHORE_DB_PORT}..." TIMEOUT=30 while ! $(nc -z "$SEMAPHORE_DB_HOST" "$SEMAPHORE_DB_PORT") >/dev/null 2>&1; do TIMEOUT=$(expr $TIMEOUT - 1) if [ $TIMEOUT -eq 0 ]; then echoerr "Could not connect to database server. Exiting." exit 1 fi echo -n "." sleep 1 done export SEMAPHORE_DB_HOST="${SEMAPHORE_DB_HOST}:${SEMAPHORE_DB_PORT}" fi # # Generate new config.json if it does not exist # if [ ! -f "${SEMAPHORE_CONFIG_PATH}/config.json" ]; then echoerr "Generating setup file ${TMP_STDIN_CONFIG_FILE} ..." TMP_STDIN_CONFIG_FILE=$(mktemp) SEMAPHORE_TMP_PATH=${SEMAPHORE_TMP_PATH:-/tmp/semaphore} [ -d "${SEMAPHORE_TMP_PATH}" ] || mkdir -p "${SEMAPHORE_TMP_PATH}" || { echo "Can't create Semaphore tmp path ${SEMAPHORE_TMP_PATH}." exit 1 } case ${SEMAPHORE_DB_DIALECT} in mysql) SEMAPHORE_DB_DIALECT_ID=1 ;; bolt) SEMAPHORE_DB_DIALECT_ID=2 ;; postgres) SEMAPHORE_DB_DIALECT_ID=3 ;; *) echoerr "Unknown database dialect: ${SEMAPHORE_DB_DIALECT}" exit 1 ;; esac cat << EOF > "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_DB_DIALECT_ID} EOF if [ "${SEMAPHORE_DB_DIALECT}" = "bolt" ]; then cat << EOF >> "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_DB_HOST} EOF else cat << EOF >> "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_DB_HOST} ${SEMAPHORE_DB_USER} ${SEMAPHORE_DB_PASS} ${SEMAPHORE_DB:-semaphore} EOF fi cat << EOF >> "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_TMP_PATH} ${SEMAPHORE_WEB_ROOT:-} no no no no no ${SEMAPHORE_LDAP_ACTIVATED} EOF if [ "${SEMAPHORE_LDAP_ACTIVATED}" = "yes" ]; then cat << EOF >> "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_LDAP_HOST}:${SEMAPHORE_LDAP_PORT} ${SEMAPHORE_LDAP_NEEDTLS:-no} ${SEMAPHORE_LDAP_DN_BIND} ${SEMAPHORE_LDAP_PASSWORD} ${SEMAPHORE_LDAP_DN_SEARCH} ${SEMAPHORE_LDAP_SEARCH_FILTER:-(uid=%s)} ${SEMAPHORE_LDAP_MAPPING_DN:-dn} ${SEMAPHORE_LDAP_MAPPING_USERNAME} ${SEMAPHORE_LDAP_MAPPING_FULLNAME} ${SEMAPHORE_LDAP_MAPPING_EMAIL} EOF fi; cat << EOF >> "${TMP_STDIN_CONFIG_FILE}" ${SEMAPHORE_CONFIG_PATH} ${SEMAPHORE_ADMIN} ${SEMAPHORE_ADMIN_EMAIL} ${SEMAPHORE_ADMIN_NAME} ${SEMAPHORE_ADMIN_PASSWORD} EOF echoerr "Executing semaphore setup" if test "$#" -ne 1; then /usr/local/bin/semaphore setup - < "${TMP_STDIN_CONFIG_FILE}" else "$1" setup - < "${TMP_STDIN_CONFIG_FILE}" fi rm -f "${TMP_STDIN_CONFIG_FILE}" fi # # Install additional python dependencies # if test -f "${SEMAPHORE_CONFIG_PATH}/requirements.txt"; then echoerr "Installing additional python dependencies" pip3 install --upgrade \ -r "${SEMAPHORE_CONFIG_PATH}/requirements.txt" else echoerr "No additional python dependencies to install" fi # # Start Semaphore server # echoerr "Starting semaphore server" if test "$#" -ne 1; then exec /usr/local/bin/semaphore server --config "${SEMAPHORE_CONFIG_PATH}/config.json" else exec "$@" fi