diff --git a/src/opt/docker/bin/config.sh b/src/opt/docker/bin/config.sh new file mode 100644 index 0000000..3b9bec6 --- /dev/null +++ b/src/opt/docker/bin/config.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash + +shopt -s nullglob + +### + # Check if current user is root + # + ## +function rootCheck() { + # Root check + if [ "$(/usr/bin/whoami)" != "root" ]; then + echo "[ERROR] $* must be run as root" + exit 1 + fi +} + +### + # Create /docker.stdout and /docker.stderr + # + ## +function createDockerStdoutStderr() { + # link stdout from docker + if [[ -n "$LOG_STDOUT" ]]; then + echo "Log stdout redirected to $LOG_STDOUT" + else + LOG_STDOUT="/proc/$$/fd/1" + fi + + if [[ -n "$LOG_STDERR" ]]; then + echo "Log stderr redirected to $LOG_STDERR" + else + LOG_STDERR="/proc/$$/fd/2" + fi + + ln -f -s "$LOG_STDOUT" /docker.stdout + ln -f -s "$LOG_STDERR" /docker.stderr +} +### + # Include script directory text inside a file + # + # $1 -> path + # + ## +function includeScriptDir() { + if [[ -d "$1" ]]; then + for FILE in "$1"/*.sh; do + echo "-> Executing ${FILE}" + # run custom scripts, only once + . "$FILE" + done + fi +} + +### + # Show deprecation notice + # + ## +function deprecationNotice() { + echo "" + echo "###############################################################################" + echo "### THIS CALL IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE" + echo "###" + echo "### $*" + echo "###" + echo "###############################################################################" + echo "" +} + +### + # Run "entrypoint" scripts + # + ## +function runEntrypoints() { + # try to find entrypoint task script + ENTRYPOINT_SCRIPT="/opt/docker/bin/entrypoint.d/${TASK}.sh" + if [ ! -f "$ENTRYPOINT_SCRIPT" ]; then + # use default + ENTRYPOINT_SCRIPT="/opt/docker/bin/entrypoint.d/default.sh" + fi + + if [ ! -f "$ENTRYPOINT_SCRIPT" ]; then + exit 1 + fi + + . "$ENTRYPOINT_SCRIPT" +} + +### + # Run "entrypoint" provisioning + # + ## +function runProvisionEntrypoint() { + includeScriptDir "/opt/docker/provision/entrypoint.d" + includeScriptDir "/entrypoint.d" +} + +### + # https://stackoverflow.com/questions/41451159/how-to-execute-a-script-when-i-terminate-a-docker-container + # https://hynek.me/articles/docker-signals/ + # + ## +function runTeardownEntrypoint() { + echo "Container stopped, performing teardown..." + includeScriptDir "/opt/docker/provision/entrypoint.d/teardown" + includeScriptDir "/entrypoint.d/teardown" +} + +### + # List environment variables (based on prefix) + # + ## +function envListVars() { + if [[ $# -eq 1 ]]; then + env | grep "^${1}" | cut -d= -f1 + else + env | cut -d= -f1 + fi +} + +### + # Get environment variable (even with dots in name) + # + ## +function envGetValue() { + awk "BEGIN {print ENVIRON[\"$1\"]}" +} diff --git a/src/opt/docker/bin/entrypoint.d/cli.sh b/src/opt/docker/bin/entrypoint.d/cli.sh new file mode 100644 index 0000000..80109a7 --- /dev/null +++ b/src/opt/docker/bin/entrypoint.d/cli.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +############################################# +## Run CLI_SCRIPT from environment variable +############################################# + +if [ -n "${CLI_SCRIPT}" ]; then + if [ -n "${CONTAINER_UID}" ]; then + # Run as EFFECTIVE_USER + shift + exec gosu "${CONTAINER_UID}" "${CLI_SCRIPT}" "$@" + else + # Run as root + exec "${CLI_SCRIPT}" "$@" + fi +else + echo "[ERROR] No CLI_SCRIPT in in docker environment defined" + exit 1 +fi diff --git a/src/opt/docker/bin/entrypoint.sh b/src/opt/docker/bin/entrypoint.sh index 0dbd513..4795ba6 100755 --- a/src/opt/docker/bin/entrypoint.sh +++ b/src/opt/docker/bin/entrypoint.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash if [[ -z "$CONTAINER_UID" ]]; then - export CONTAINER_UID=$APPLICATION_UID + export CONTAINER_UID=1000 fi -set -o pipefail # trace ERR through pipes -set -o errtrace # trace ERR through 'time command' and other functions -set -o nounset ## set -u : exit the script if you try to use an uninitialised variable -set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o pipefail # trace ERR through pipes +set -o errtrace # trace ERR through 'time command' and other functions +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errexit ## set -e : exit the script if any statement returns a non-true return value # auto elevate privileges (if container is not started as root) if [[ "$UID" -ne 0 ]]; then @@ -15,33 +15,21 @@ if [[ "$UID" -ne 0 ]]; then exec gosu root "$0" "$@" fi -# remove suid bit on gosu -# chmod -s /sbin/gosu - -trap 'echo sigterm ; exit' SIGTERM -trap 'echo sigkill ; exit' SIGKILL - -# sanitize input and set task -TASK="$(echo $1| sed 's/[^-_a-zA-Z0-9]*//g')" - -source /opt/docker/bin/config.sh - +. /opt/docker/bin/config.sh createDockerStdoutStderr -if [[ "$UID" -eq 0 ]]; then - # Only run provision if user is root - - if [ "$TASK" == "supervisord" -o "$TASK" == "noop" ]; then - # Visible provisioning - runProvisionEntrypoint - else - # Hidden provisioning - runProvisionEntrypoint > /dev/null - fi +# sanitize input and set task +TASK="$(echo $1 | sed 's/[^-_a-zA-Z0-9]*//g')" + +if [ "$TASK" == "supervisord" ] || [ "$TASK" == "noop" ]; then + # visible provisioning + runProvisionEntrypoint + trap 'runTeardownEntrypoint' SIGTERM + runEntrypoints "$@" & + wait $! + runTeardownEntrypoint +else + # hidden provisioning + runProvisionEntrypoint > /dev/null + runEntrypoints "$@" fi - -############################# -## COMMAND -############################# - -runEntrypoints "$@" diff --git a/src/opt/docker/provision/entrypoint.d/05-gosu.sh b/src/opt/docker/provision/entrypoint.d/05-gosu.sh new file mode 100644 index 0000000..5456e7a --- /dev/null +++ b/src/opt/docker/provision/entrypoint.d/05-gosu.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# remove suid bit +chmod -s /sbin/gosu diff --git a/src/opt/docker/provision/entrypoint.d/teardown/05-gosu.sh b/src/opt/docker/provision/entrypoint.d/teardown/05-gosu.sh new file mode 100644 index 0000000..28fbaaa --- /dev/null +++ b/src/opt/docker/provision/entrypoint.d/teardown/05-gosu.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# add suid bit +chmod +s /sbin/gosu