Files
dolt/docker/docker-entrypoint.sh
2025-06-23 15:50:43 -07:00

221 lines
7.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -eo pipefail
# logging functions
mysql_log() {
local type="$1"; shift
# accept argument string or stdin
local text="$*"; if [ "$#" -eq 0 ]; then text="$(cat)"; fi
local dt; dt="$(date --rfc-3339=seconds)"
printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
}
mysql_note() {
mysql_log Note "$@"
}
mysql_warn() {
mysql_log Warn "$@" >&2
}
mysql_error() {
mysql_log ERROR "$@" >&2
exit 1
}
docker_process_sql() {
dolt sql
}
CONTAINER_DATA_DIR="/var/lib/dolt"
INIT_COMPLETED="$CONTAINER_DATA_DIR/.init_completed"
DOLT_CONFIG_DIR="/etc/dolt/doltcfg.d"
SERVER_CONFIG_DIR="/etc/dolt/servercfg.d"
DOLT_ROOT_PATH="/.dolt"
check_for_dolt() {
local dolt_bin=$(which dolt)
if [ ! -x "$dolt_bin" ]; then
mysql_error "dolt binary executable not found"
fi
}
get_env_var() {
local var_name="$1"
local mysql_var="MYSQL_${var_name}"
local dolt_var="DOLT_${var_name}"
if [ -n "${!mysql_var}" ]; then
echo "${!mysql_var}"
elif [ -n "${!dolt_var}" ]; then
echo "${!dolt_var}"
else
echo ""
fi
}
get_env_var_name() {
local var_name="$1"
local mysql_var="MYSQL_${var_name}"
local dolt_var="DOLT_${var_name}"
if [ -n "${!mysql_var}" ]; then
echo "MYSQL_${var_name}"
elif [ -n "${!dolt_var}" ]; then
echo "DOLT_${var_name}"
else
echo "MYSQL_${var_name}/DOLT_${var_name}"
fi
}
# arg $1 is the directory to search in
# arg $2 is the type file to search for
get_config_file_path_if_exists() {
CONFIG_PROVIDED=
CONFIG_DIR=$1
FILE_TYPE=$2
if [ -d "$CONFIG_DIR" ]; then
mysql_note "Checking for config provided in $CONFIG_DIR"
number_of_files_found=( `find $CONFIG_DIR -type f -name "*.$FILE_TYPE" | wc -l` )
if [ $number_of_files_found -gt 1 ]; then
CONFIG_PROVIDED=
mysql_warn "multiple config file found in $CONFIG_DIR, using default config"
elif [ $number_of_files_found -eq 1 ]; then
files_found=( `ls $CONFIG_DIR/*$FILE_TYPE` )
mysql_note "$files_found file is found"
CONFIG_PROVIDED=$files_found
else
CONFIG_PROVIDED=
fi
fi
}
# taken from https://github.com/docker-library/mysql/blob/master/8.0/docker-entrypoint.sh
# this function will run files found in /docker-entrypoint-initdb.d directory BEFORE server is started
# usage: docker_process_init_files [file [file [...]]]
# ie: docker_process_init_files /always-initdb.d/*
# process initializer files, based on file extensions
docker_process_init_files() {
mysql_note "Running init scripts"
local f
for f; do
case "$f" in
*.sh)
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
# https://github.com/docker-library/postgres/pull/452
if [ -x "$f" ]; then
mysql_note "$0: running $f"
"$f"
else
mysql_note "$0: sourcing $f"
. "$f"
fi
;;
*.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
*.sql.bz2) mysql_note "$0: running $f"; bunzip2 -c "$f" | docker_process_sql; echo ;;
*.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
*.sql.xz) mysql_note "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;;
*.sql.zst) mysql_note "$0: running $f"; zstd -dc "$f" | docker_process_sql; echo ;;
*) mysql_warn "$0: ignoring $f" ;;
esac
echo
done
}
# if there is config file provided through /etc/dolt/doltcfg.d,
# we overwrite $HOME/.dolt/config_global.json file with this file.
set_dolt_config_if_defined() {
get_config_file_path_if_exists "$DOLT_CONFIG_DIR" "json"
if [ ! -z $CONFIG_PROVIDED ]; then
/bin/cp -rf $CONFIG_PROVIDED $HOME/$DOLT_ROOT_PATH/config_global.json
fi
}
create_default_database_from_env() {
local user
local password
local database
database=$(get_env_var "DATABASE")
user=$(get_env_var "USER")
password=$(get_env_var "PASSWORD")
if [ -n "$database" ]; then
mysql_note "Creating database ${database}"
dolt sql -q "CREATE DATABASE IF NOT EXISTS $database;"
fi
if [ "$user" = 'root' ]; then
# TODO: add ALLOW_EMPTY_PASSWORD and RANDOM_ROOT_PASSWORD support
mysql_error <<-EOF
$(get_env_var_name "USER")="root", $(get_env_var_name "USER") and $(get_env_var_name "PASSWORD") are for configuring a regular user and cannot be used for the root user
Remove $(get_env_var_name "USER")="root" and use the following to control the root user password:
- DOLT_ROOT_PASSWORD
EOF
fi
if [ -n "$user" ] && [ -z "$password" ]; then
mysql_warn "$(get_env_var_name "USER") specified, but missing $(get_env_var_name "PASSWORD"); user will not be created"
return
elif [ -z "$user" ] && [ -n "$password" ]; then
mysql_warn "$(get_env_var_name "PASSWORD") specified, but missing $(get_env_var_name "USER"); password will be ignored"
return
fi
if [ -n "$user" ] && [ -n "$password" ]; then
mysql_note "Creating user ${user}"
dolt sql -q "CREATE USER IF NOT EXISTS '$user'@'%' IDENTIFIED BY '$password';"
if [ -n "$database" ]; then
mysql_note "Giving user ${user} access to schema ${database}"
dolt sql -q "GRANT ALL ON \`${database//_/\\_}\`.* TO '$user'@'%';"
fi
fi
}
_main() {
# check for dolt binary executable
check_for_dolt
local dolt_version=$(dolt version | grep 'dolt version' | cut -f3 -d " ")
mysql_note "Entrypoint script for Dolt Server $dolt_version starting."
declare -g CONFIG_PROVIDED
# dolt config will be set if user provided a single json file in /etc/dolt/doltcfg.d directory.
# It will overwrite config_global.json file in $HOME/.dolt
set_dolt_config_if_defined
# if there is a single yaml provided in /etc/dolt/servercfg.d directory,
# it will be used to start the server with --config flag
get_config_file_path_if_exists "$SERVER_CONFIG_DIR" "yaml"
if [ ! -z "$CONFIG_PROVIDED" ]; then
set -- "$@" --config="$CONFIG_PROVIDED"
fi
# TODO: add support for MYSQL_ROOT_HOST and MYSQL_ROOT_PASSWORD
# If DOLT_ROOT_HOST has been specified create a root user for that host with the specified password
if [ -n "$DOLT_ROOT_HOST" ] && [ "$DOLT_ROOT_HOST" != 'localhost' ]; then
echo "Ensuring root@${DOLT_ROOT_HOST} superuser exists (DOLT_ROOT_HOST was specified)"
dolt sql -q "CREATE USER IF NOT EXISTS 'root'@'${DOLT_ROOT_HOST}' IDENTIFIED BY '${DOLT_ROOT_PASSWORD}';
ALTER USER 'root'@'${DOLT_ROOT_HOST}' IDENTIFIED BY '${DOLT_ROOT_PASSWORD}';
GRANT ALL ON *.* TO 'root'@'${DOLT_ROOT_HOST}' WITH GRANT OPTION;"
fi
# Ensure the root@localhost user exists, with the requested password
echo "Ensuring root@localhost user exists"
dolt sql -q "CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY '${DOLT_ROOT_PASSWORD}';
ALTER USER 'root'@'localhost' IDENTIFIED BY '${DOLT_ROOT_PASSWORD}';
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION;"
# If DOLT_DATABASE or MYSQL_DATABASE has been specified, create the database if it does not exist
create_default_database_from_env
if [[ ! -f $INIT_COMPLETED ]]; then
# run any file provided in /docker-entrypoint-initdb.d directory before the server starts
docker_process_init_files /docker-entrypoint-initdb.d/*
touch $INIT_COMPLETED
fi
# switch this process over to executing dolt sql-server
exec dolt sql-server --host=0.0.0.0 --port=3306 "$@"
}
_main "$@"