Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mysql/bin/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ else
# shellcheck disable=SC2046
export $(parse_database_url.py | xargs)
# Setup .my.cnf so `mysql` just does the right thing
/bin/echo -e "[client]\nhost=$HOST\nport=$PORT\nuser=$USER" > ~/.my.cnf
# `database` only goes in [mysql] (read by the interactive mysql client);
# putting it in [client] breaks mysqladmin/mysqldump, which also read
# [client] but reject `database` as an unknown option.
/bin/echo -e "[client]\nhost=$HOST\nport=$PORT\nuser=$USER\n\n[mysql]\ndatabase=$NAME" > ~/.my.cnf
fi

exec "$@"
10 changes: 8 additions & 2 deletions mysql/bin/load-from-s3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ echo "Downloading $S3_PATH ..."
aws s3 cp --no-progress "$S3_PATH" /tmp/db.sql.gz
echo "Drop/create $NAME..."

mysql --execute "DROP DATABASE IF EXISTS "'`'"$NAME"'`'
mysql --execute "CREATE DATABASE "'`'"$NAME"'`'
# ~/.my.cnf now defaults to $NAME as the database (so a bare `mysql` works
# for interactive use), but $NAME doesn't exist for the moment between the
# DROP and CREATE below, and the app DB user typically has no privileges
# on any other schema to fall back to. Bypass the defaults file for these
# two statements so no default database is selected; MYSQL_PWD still
# supplies the password since it's read directly from the environment.
mysql --no-defaults --host="$HOST" --port="$PORT" --user="$USER" --execute "DROP DATABASE IF EXISTS "'`'"$NAME"'`'
mysql --no-defaults --host="$HOST" --port="$PORT" --user="$USER" --execute "CREATE DATABASE "'`'"$NAME"'`'

echo "Loading $S3_PATH into $NAME..."
set -x
Expand Down
2 changes: 1 addition & 1 deletion mysql/bin/parse_database_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
'USER': parsed.username,
'MYSQL_PWD': parsed.password,
'HOST': parsed.hostname,
'PORT': parsed.port,
'PORT': parsed.port or 3306,
'NAME': parsed.path.strip('/')
}
for k, v in env.items():
Expand Down
7 changes: 6 additions & 1 deletion mysql/docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ services:
volumes:
- db_data:/var/lib/mysql
s3:
image: localstack/localstack
# Pinned: localstack/localstack:latest moved to a unified image in March
# 2026 that requires a paid LOCALSTACK_AUTH_TOKEN to boot at all, even
# for plain S3. 4.14.0 is the last community-edition tag that starts
# without a license. Revisit this pin once the suite can run against a
# supported, token-free community image again.
image: localstack/localstack:4.14.0
platform: linux/amd64
environment:
SERVICES: s3
Expand Down
30 changes: 24 additions & 6 deletions mysql/tests/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,34 @@ done
echo "###### Setup test state"
aws s3api create-bucket --bucket "$BUCKET"
aws s3 rm --recursive "s3://$BUCKET/"
mysql -u root --execute 'DROP DATABASE IF EXISTS `test`'
mysql -u root --execute 'DROP DATABASE IF EXISTS `test-clone`'
mysql -u root --execute "DROP USER IF EXISTS 'test'"
mysql -u root --execute 'CREATE DATABASE `test`'
mysql -u root --execute "CREATE USER 'test'@'%' IDENTIFIED BY 'password'"
mysql -u root --execute 'GRANT ALL PRIVILEGES ON `test`.* TO `test`@`%`'
# `test` doesn't exist yet, and ~/.my.cnf now defaults to it (see [mysql]
# section written by entrypoint.sh), so these bootstrap statements target
# the always-present `mysql` system schema explicitly instead of relying
# on that default.
mysql -u root mysql --execute 'DROP DATABASE IF EXISTS `test`'
mysql -u root mysql --execute 'DROP DATABASE IF EXISTS `test-clone`'
mysql -u root mysql --execute "DROP USER IF EXISTS 'test'"
mysql -u root mysql --execute 'CREATE DATABASE `test`'
mysql -u root mysql --execute "CREATE USER 'test'@'%' IDENTIFIED BY 'password'"
mysql -u root mysql --execute 'GRANT ALL PRIVILEGES ON `test`.* TO `test`@`%`'
mysql test --execute "CREATE TABLE tbl (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL)"
mysql test --execute "INSERT INTO tbl (name) VALUES ('name1')"
mysql test --execute "INSERT INTO tbl (name) VALUES ('name2')"

printf "\n###### Testing bare mysql (no --database) uses database from DATABASE_URL...\n"
mysql --execute "SELECT COUNT(*) FROM tbl" | grep "2" > /dev/null
echo "✅ bare mysql connected to the database named in DATABASE_URL via ~/.my.cnf"

printf "\n###### Testing portless DATABASE_URL defaults PORT to 3306...\n"
PARSED_PORTLESS=$(DATABASE_URL="mysql://test:password@db/test" parse_database_url.py)
echo "$PARSED_PORTLESS" | grep "PORT=3306" > /dev/null
echo "✅ PORT defaulted to 3306 for a portless DATABASE_URL"

printf "\n###### Testing connection succeeds with a portless DATABASE_URL...\n"
eval "$PARSED_PORTLESS"
mysql --host="$HOST" --port="$PORT" --user="$USER" --password="$MYSQL_PWD" "$NAME" --execute "SELECT 1" > /dev/null
echo "✅ mysql connected successfully using the parsed portless DATABASE_URL"

printf "\n###### Starting tests...\n"
dump-to-s3.sh "s3://$BUCKET/dump.sql.gz" test
printf "\n###### Verify dump file exists...\n"
Expand Down
7 changes: 6 additions & 1 deletion postgres/bin/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ export PGSSLMODE=require
wait_for_db() {
local retries=30
local sleep_time=2
local last_error=""

echo "Waiting for PostgreSQL server to be ready..."
until psql "$DATABASE_URL" -c '\q' 2>/dev/null || [ "$retries" -eq 0 ]; do
until last_error=$(psql "$DATABASE_URL" -c '\q' 2>&1 >/dev/null) || [ "$retries" -eq 0 ]; do
echo "PostgreSQL is unavailable - ($((retries--)) retries left)..."
sleep "$sleep_time"
done

if [ "$retries" -eq 0 ]; then
echo "ERROR: PostgreSQL server did not respond."
if [ -n "$last_error" ]; then
echo "Last error from psql:"
echo "$last_error"
fi
exit 1
fi
}
Expand Down
2 changes: 1 addition & 1 deletion postgres/bin/parse_database_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
'USER': parsed.username,
'PGPASSWORD': parsed.password,
'HOST': parsed.hostname,
'PORT': parsed.port,
'PORT': parsed.port or 5432,
'NAME': parsed.path.strip('/')
}
for k, v in env.items():
Expand Down
7 changes: 6 additions & 1 deletion postgres/docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ services:
environment:
POSTGRES_PASSWORD: password
s3:
image: localstack/localstack
# Pinned: localstack/localstack:latest moved to a unified image in March
# 2026 that requires a paid LOCALSTACK_AUTH_TOKEN to boot at all, even
# for plain S3. 4.14.0 is the last community-edition tag that starts
# without a license. Revisit this pin once the suite can run against a
# supported, token-free community image again.
image: localstack/localstack:4.14.0
platform: linux/amd64
environment:
SERVICES: s3
Expand Down
8 changes: 8 additions & 0 deletions postgres/tests/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ psql test -c "CREATE TABLE tbl (id SERIAL PRIMARY KEY, name CHAR(255) NOT NULL)"
psql test -c "INSERT INTO tbl (name) VALUES ('name1')"
psql test -c "INSERT INTO tbl (name) VALUES ('name2')"

printf "\n###### Testing portless DATABASE_URL defaults PORT to 5432...\n"
DATABASE_URL="postgres://test:password@db/test" parse_database_url.py | grep "PORT=5432" > /dev/null
echo "✅ PORT defaulted to 5432 for a portless DATABASE_URL"

printf "\n###### Testing connection succeeds with a portless DATABASE_URL...\n"
psql "postgres://test:password@db/test" -c '\q'
echo "✅ psql connected successfully using a portless DATABASE_URL"

printf "\n###### Testing SERVER_VERSION override...\n"
export SERVER_VERSION=17
DUMP_LOG=$(dump-to-s3.sh "s3://$BUCKET/explicit.dump" test 2>&1)
Expand Down
Loading