add bats testing for docker entrypoint and amend root user creation

This commit is contained in:
elianddb
2025-09-11 14:09:51 -07:00
parent 9b9904d0ac
commit 50a3498430
3 changed files with 95 additions and 40 deletions
+72 -36
View File
@@ -68,16 +68,16 @@ get_env_var_name() {
# arg $2 is the type file to search for
get_config_file_path_if_exists() {
CONFIG_PROVIDED=
CONFIG_DIR=$1
FILE_TYPE=$2
local CONFIG_DIR=$1
local 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
local 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` )
elif [ "$number_of_files_found" -eq 1 ]; then
local files_found=$(ls "$CONFIG_DIR"/*"$FILE_TYPE")
mysql_note "$files_found file is found"
CONFIG_PROVIDED=$files_found
else
@@ -99,13 +99,17 @@ docker_process_init_files() {
*.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"
if [ -x "$f" ]; then
mysql_note "$0: running $f"
if ! "$f"; then
mysql_error "Failed to execute init script '$f'"
fi
else
mysql_note "$0: sourcing $f"
if ! . "$f"; then
mysql_error "Failed to source init script '$f'"
fi
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 ;;
@@ -122,8 +126,10 @@ docker_process_init_files() {
# 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
if [ ! -z "$CONFIG_PROVIDED" ]; then
if ! /bin/cp -rf "$CONFIG_PROVIDED" "$HOME/$DOLT_ROOT_PATH/config_global.json" 2>&1; then
mysql_error "Failed to copy config file from '$CONFIG_PROVIDED' to '$HOME/$DOLT_ROOT_PATH/config_global.json'. Check file permissions and paths."
fi
fi
}
@@ -137,8 +143,11 @@ create_default_database_from_env() {
password=$(get_env_var "PASSWORD")
if [ -n "$database" ]; then
mysql_note "Creating database ${database}"
dolt sql -q "CREATE DATABASE IF NOT EXISTS $database;"
mysql_note "Creating database ${database}"
local db_output
if ! db_output=$(dolt sql -q "CREATE DATABASE IF NOT EXISTS \`$database\`;" 2>&1); then
mysql_error "Failed to create database '$database'. Error: $db_output"
fi
fi
if [ "$user" = 'root' ]; then
@@ -151,20 +160,29 @@ 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
mysql_error "$(get_env_var_name "USER") specified, but missing $(get_env_var_name "PASSWORD"); user creation requires a password"
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
if [ -n "$user" ]; then
mysql_note "Creating user ${user}"
dolt sql -q "CREATE USER IF NOT EXISTS '$user'@'%' IDENTIFIED BY '$password';"
if ! dolt sql -q "CREATE USER IF NOT EXISTS '$user'@'%' IDENTIFIED BY '$password';" 2>&1; then
mysql_error "Failed to create user '$user'. Check if user already exists or if there are permission issues."
fi
# Grant basic server access
mysql_note "Granting server access to user ${user}"
if ! dolt sql -q "GRANT USAGE ON *.* TO '$user'@'%';" 2>&1; then
mysql_error "Failed to grant server access to user '$user'"
fi
if [ -n "$database" ]; then
mysql_note "Giving user ${user} access to schema ${database}"
dolt sql -q "GRANT ALL ON \`${database//_/\\_}\`.* TO '$user'@'%';"
if ! dolt sql -q "GRANT ALL ON \`$database\`.* TO '$user'@'%';" 2>&1; then
mysql_error "Failed to grant permissions to user '$user' on database '$database'"
fi
fi
fi
}
@@ -173,7 +191,8 @@ _main() {
# check for dolt binary executable
check_for_dolt
local dolt_version=$(dolt version | grep 'dolt version' | cut -f3 -d " ")
local dolt_version
dolt_version=$(dolt version | grep 'dolt version' | cut -f3 -d " ")
mysql_note "Entrypoint script for Dolt Server $dolt_version starting."
declare -g CONFIG_PROVIDED
@@ -190,29 +209,46 @@ _main() {
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;"
# Note: User creation will happen after server starts to avoid conflicts with default users
# 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/*
if ls /docker-entrypoint-initdb.d/* >/dev/null 2>&1; then
docker_process_init_files /docker-entrypoint-initdb.d/*
fi
touch $INIT_COMPLETED
fi
# Start the server in the background to create users
mysql_note "Starting Dolt server in background for user creation"
dolt sql-server --host=0.0.0.0 --port=3306 "$@" &
local server_pid=$!
# Wait for server to be ready
sleep 3
# Create root user with the specified host (defaults to localhost if not specified)
local root_host="${DOLT_ROOT_HOST:-localhost}"
mysql_note "Ensuring root@${root_host} superuser exists with password"
# Remove existing root users to avoid conflicts
mysql_note "Cleaning up existing root users"
dolt sql -q "DROP USER IF EXISTS 'root'@'localhost'; DROP USER IF EXISTS 'root'@'%';" 2>&1 || mysql_warn "Could not clean up existing root users"
# Create the new root user
dolt sql -q "CREATE USER 'root'@'${root_host}' IDENTIFIED BY '${DOLT_ROOT_PASSWORD}'; GRANT ALL ON *.* TO 'root'@'${root_host}' WITH GRANT OPTION;" 2>&1 || mysql_error "Failed to create root@${root_host} user. Check logs for details."
# Show what users exist for debugging
mysql_note "Current users in the system:"
dolt sql -q "SELECT User, Host FROM mysql.user;" 2>&1 || mysql_warn "Could not list users"
# Stop the background server
kill $server_pid 2>/dev/null || true
wait $server_pid 2>/dev/null || true
# switch this process over to executing dolt sql-server
exec dolt sql-server --host=0.0.0.0 --port=3306 "$@"
}
+9 -2
View File
@@ -7,20 +7,27 @@ RUN apt update -y && \
apt install -y \
curl \
tini \
ca-certificates && \
ca-certificates \
mysql-client && \
apt clean && \
rm -rf /var/lib/apt/lists/*
# we install dolt with the install.sh script, which will determine the platform/arch of the container
# and install the proper dolt binary
RUN bash -c 'curl -L https://github.com/dolthub/dolt/releases/download/v${DOLT_VERSION}/install.sh | bash'
# Handle "latest" by fetching the actual latest version
RUN if [ "$DOLT_VERSION" = "latest" ]; then \
DOLT_VERSION=$(curl -s https://api.github.com/repos/dolthub/dolt/releases/latest | grep '"tag_name"' | cut -d'"' -f4 | sed 's/^v//'); \
fi && \
curl -L https://github.com/dolthub/dolt/releases/download/v${DOLT_VERSION}/install.sh | bash
RUN /usr/local/bin/dolt version
RUN mkdir /docker-entrypoint-initdb.d
RUN mkdir -p /var/lib/dolt
VOLUME /var/lib/dolt
COPY docker/docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
RUN chmod 755 /var/lib/dolt
EXPOSE 3306 33060
WORKDIR /var/lib/dolt
+14 -2
View File
@@ -85,6 +85,18 @@ To see all supported options for `dolt sql-server`, you can run the image with `
$ docker run dolthub/dolt-sql-server:latest --help
```
## Building the image
To build this image from source, use the `serverDockerfile`:
```shell
# Build with the latest Dolt version (automatically fetches the latest release)
$ docker build -f docker/serverDockerfile --build-arg DOLT_VERSION=latest -t dolt-sql-server:latest .
# Build with a specific Dolt version
$ docker build -f docker/serverDockerfile --build-arg DOLT_VERSION=1.59.7 -t dolt-sql-server:latest .
```
### Connect to the server in the container from the host system
From the host system, to connect to a server running in a container, we need to map a port on the host system to the port our sql-server is running on in the container.
@@ -141,8 +153,8 @@ $ docker run -p 3307:3306 -v /Users/jennifer/docker/databases/:/var/lib/dolt/ do
The Dolt SQL Server image supports the following environment variables:
- `DOLT_ROOT_PASSWORD`: Sets the password for the root user
- `DOLT_ROOT_HOST`: Specifies a host for the root user (default: localhost)
- `DOLT_ROOT_PASSWORD`: Sets the password for root (default: empty)
- `DOLT_ROOT_HOST`: Specifies a host for the root and user (default: localhost)
- `DOLT_DATABASE` / `MYSQL_DATABASE`: Creates a database with this name if it doesn't exist
- `DOLT_USER` / `MYSQL_USER`: Creates a user with this name if it doesn't exist
- `DOLT_PASSWORD` / `MYSQL_PASSWORD`: Sets the password for the user specified in `DOLT_USER`/`MYSQL_USER`