From b5ca4c2e065bd75e246acffd817ec9b5f8bb0c1f Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Wed, 4 Mar 2015 09:28:01 +0100 Subject: [PATCH 1/8] Fixed security issue - File with root password in plaintext was readable from database the first time server was run --- 5.5/docker-entrypoint.sh | 60 +++++++++++++++++++++++++++++++--------- 5.6/docker-entrypoint.sh | 60 +++++++++++++++++++++++++++++++--------- 5.7/docker-entrypoint.sh | 59 +++++++++++++++++++++++++++++++-------- 3 files changed, 142 insertions(+), 37 deletions(-) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index a944425a6..d32ca0912 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -1,14 +1,25 @@ #!/bin/bash set -e +get_option () { + local section=$1 + local option=$2 + local default=$3 + ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret +} + # if command starts with an option, prepend mysqld if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # read DATADIR from the MySQL config - DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + # Get config + DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then @@ -16,16 +27,27 @@ if [ "$1" = 'mysqld' ]; then echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi - - echo 'Running mysql_install_db ...' - mysql_install_db --datadir="$DATADIR" --basedir=/usr/local/mysql + mkdir -p $DATADIR + echo 'Running mysql_install_db' + mysql_install_db --user=mysql --datadir=$DATADIR --rpm echo 'Finished mysql_install_db' - + + mysqld --user=mysql --datadir=$DATADIR --skip-networking & + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - tempSqlFile='/tmp/mysql-first-time.sql' + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work @@ -38,23 +60,35 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then - echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" >> "$tempSqlFile" + echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" if [ "$MYSQL_DATABASE" ]; then - echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" >> "$tempSqlFile" + echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - set -- "$@" --init-file="$tempSqlFile" + chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile + + rm -f $tempSqlFile + kill $(cat $PIDFILE) + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi + echo 'MySQL init process done. Ready for start up.' fi - - chown -R mysql:mysql "$DATADIR" fi exec "$@" diff --git a/5.6/docker-entrypoint.sh b/5.6/docker-entrypoint.sh index 8343260f3..d767d5bd1 100755 --- a/5.6/docker-entrypoint.sh +++ b/5.6/docker-entrypoint.sh @@ -1,31 +1,53 @@ #!/bin/bash set -e +get_option () { + local section=$1 + local option=$2 + local default=$3 + ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret +} + # if command starts with an option, prepend mysqld if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # read DATADIR from the MySQL config + # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - + SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then echo >&2 'error: database is uninitialized and MYSQL_ROOT_PASSWORD not set' echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi - - echo 'Running mysql_install_db ...' - mysql_install_db --datadir="$DATADIR" + mkdir -p $DATADIR + echo 'Running mysql_install_db' + mysql_install_db --user=mysql --datadir=$DATADIR --rpm --keep-my-cnf echo 'Finished mysql_install_db' - + + mysqld --user=mysql --datadir=$DATADIR --skip-networking & + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - tempSqlFile='/tmp/mysql-first-time.sql' + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work @@ -38,23 +60,35 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then - echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" >> "$tempSqlFile" + echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" if [ "$MYSQL_DATABASE" ]; then - echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" >> "$tempSqlFile" + echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - set -- "$@" --init-file="$tempSqlFile" + chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile + + rm -f $tempSqlFile + kill $(cat $PIDFILE) + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi + echo 'MySQL init process done. Ready for start up.' fi - - chown -R mysql:mysql "$DATADIR" fi exec "$@" diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index f8def9a9f..7e8337fbb 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -1,31 +1,54 @@ #!/bin/bash set -e +get_option () { + local section=$1 + local option=$2 + local default=$3 + ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret +} + # if command starts with an option, prepend mysqld if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # read DATADIR from the MySQL config + # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - + SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then echo >&2 'error: database is uninitialized and MYSQL_ROOT_PASSWORD not set' echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi - + + mkdir -p $DATADIR echo 'Initializing database' mysqld --initialize-insecure=on --datadir="$DATADIR" echo 'Database initialized' - + + mysqld --user=mysql --datadir=$DATADIR --skip-networking & + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - tempSqlFile='/tmp/mysql-first-time.sql' + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work @@ -38,23 +61,37 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then - echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" >> "$tempSqlFile" + echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" if [ "$MYSQL_DATABASE" ]; then - echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" >> "$tempSqlFile" + echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - set -- "$@" --init-file="$tempSqlFile" + chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile + sed -i -e '/^log-error/d' /etc/my.cnf + cat /etc/my.cnf + rm -f $tempSqlFile + kill $(cat $PIDFILE) + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi + echo 'MySQL init process done. Ready for start up.' fi - - chown -R mysql:mysql "$DATADIR" fi exec "$@" + From 6e9444efd813447fd7897950af7fc8bf476b9249 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Thu, 5 Mar 2015 09:16:50 +0100 Subject: [PATCH 2/8] Tell mysql_install_db where mysqld is located --- 5.7/docker-entrypoint.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index 7e8337fbb..295a481a5 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -44,6 +44,10 @@ if [ "$1" = 'mysqld' ]; then exit 1 fi + # Workaround for bug in 5.7 that doesn't clean up after itself correctly + rm -f $DATADIR/ib_logfile0 + rm -f $DATADIR/ib_logfile1 + rm -f $DATADIR/ibdata1 # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: @@ -76,8 +80,6 @@ if [ "$1" = 'mysqld' ]; then chown -R mysql:mysql "$DATADIR" mysql -uroot < $tempSqlFile - sed -i -e '/^log-error/d' /etc/my.cnf - cat /etc/my.cnf rm -f $tempSqlFile kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do From 8e2518a0ad4d2aa0260c61c0dd0d75b0ef34ca12 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Thu, 5 Mar 2015 13:45:25 +0100 Subject: [PATCH 3/8] Changed some paths to reflect how 5.5 is set up differently --- 5.5/docker-entrypoint.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index d32ca0912..db6d21e31 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -5,7 +5,7 @@ get_option () { local section=$1 local option=$2 local default=$3 - ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + ret=$(/usr/local/mysql/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) [ -z $ret ] && ret=$default echo $ret } @@ -18,8 +18,9 @@ fi if [ "$1" = 'mysqld' ]; then # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") - PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + SOCKET=$(get_option mysqld socket "/tmp/mysql.sock") + HOSTNAME=$(hostname) + PIDFILE=$(get_option mysqld pid-file "$DATADIR/$HOSTNAME.pid") if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then @@ -29,10 +30,10 @@ if [ "$1" = 'mysqld' ]; then fi mkdir -p $DATADIR echo 'Running mysql_install_db' - mysql_install_db --user=mysql --datadir=$DATADIR --rpm + mysql_install_db --user=mysql --datadir=$DATADIR --rpm --basedir=/usr/local/mysql echo 'Finished mysql_install_db' - mysqld --user=mysql --datadir=$DATADIR --skip-networking & + mysqld --user=mysql --datadir=$DATADIR --skip-networking --basedir=/usr/local/mysql & for i in $(seq 30 -1 0); do [ -S $SOCKET ] && break echo 'MySQL init process in progress...' From 355b0d250e34abd1bbdc971fd61a898aaa047987 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Fri, 6 Mar 2015 12:45:24 +0100 Subject: [PATCH 4/8] Ensure correct ownership of an existing datadir --- 5.5/docker-entrypoint.sh | 2 ++ 5.6/docker-entrypoint.sh | 2 ++ 5.7/docker-entrypoint.sh | 2 ++ 3 files changed, 6 insertions(+) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index db6d21e31..1e182772b 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -90,6 +90,8 @@ if [ "$1" = 'mysqld' ]; then fi echo 'MySQL init process done. Ready for start up.' fi + + chown -R mysql:mysql "$DATADIR" fi exec "$@" diff --git a/5.6/docker-entrypoint.sh b/5.6/docker-entrypoint.sh index d767d5bd1..1f80ae8d8 100755 --- a/5.6/docker-entrypoint.sh +++ b/5.6/docker-entrypoint.sh @@ -89,6 +89,8 @@ if [ "$1" = 'mysqld' ]; then fi echo 'MySQL init process done. Ready for start up.' fi + + chown -R mysql:mysql "$DATADIR" fi exec "$@" diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index 295a481a5..e27fc8cf3 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -93,6 +93,8 @@ if [ "$1" = 'mysqld' ]; then fi echo 'MySQL init process done. Ready for start up.' fi + + chown -R mysql:mysql "$DATADIR" fi exec "$@" From 3e88d6834be736c8c573678f446f7c02aeefe250 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Mon, 16 Mar 2015 09:32:54 +0100 Subject: [PATCH 5/8] * Fix whitespace inconsistencies * Removed hardcoded path from my_print_defaults command * Moved command for setting datadir ownership to before server is started --- 5.5/docker-entrypoint.sh | 71 ++++++++++++++++++++-------------------- 5.6/docker-entrypoint.sh | 65 ++++++++++++++++++------------------ 5.7/docker-entrypoint.sh | 64 ++++++++++++++++++------------------ 3 files changed, 101 insertions(+), 99 deletions(-) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index 1e182772b..26aeaaa29 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -2,12 +2,12 @@ set -e get_option () { - local section=$1 - local option=$2 - local default=$3 - ret=$(/usr/local/mysql/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) - [ -z $ret ] && ret=$default - echo $ret + local section=$1 + local option=$2 + local default=$3 + ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret } # if command starts with an option, prepend mysqld @@ -17,11 +17,11 @@ fi if [ "$1" = 'mysqld' ]; then # Get config - DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "/tmp/mysql.sock") - HOSTNAME=$(hostname) - PIDFILE=$(get_option mysqld pid-file "$DATADIR/$HOSTNAME.pid") - + DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + SOCKET=$(get_option mysqld socket "/tmp/mysql.sock") + HOSTNAME=$(hostname) + PIDFILE=$(get_option mysqld pid-file "$DATADIR/$HOSTNAME.pid") + if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then echo >&2 'error: database is uninitialized and MYSQL_ROOT_PASSWORD not set' @@ -29,25 +29,27 @@ if [ "$1" = 'mysqld' ]; then exit 1 fi mkdir -p $DATADIR + chown -R mysql:mysql "$DATADIR" + echo 'Running mysql_install_db' mysql_install_db --user=mysql --datadir=$DATADIR --rpm --basedir=/usr/local/mysql echo 'Finished mysql_install_db' mysqld --user=mysql --datadir=$DATADIR --skip-networking --basedir=/usr/local/mysql & - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] && break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 - fi - + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated @@ -59,35 +61,34 @@ if [ "$1" = 'mysqld' ]; then GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ; DROP DATABASE IF EXISTS test ; EOSQL - + if [ "$MYSQL_DATABASE" ]; then echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi - + if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" - + if [ "$MYSQL_DATABASE" ]; then echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi - + echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - - chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile rm -f $tempSqlFile kill $(cat $PIDFILE) - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL hangs during init process.' - exit 1 - fi + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi echo 'MySQL init process done. Ready for start up.' fi diff --git a/5.6/docker-entrypoint.sh b/5.6/docker-entrypoint.sh index 1f80ae8d8..50af4a1a6 100755 --- a/5.6/docker-entrypoint.sh +++ b/5.6/docker-entrypoint.sh @@ -2,12 +2,12 @@ set -e get_option () { - local section=$1 - local option=$2 - local default=$3 - ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) - [ -z $ret ] && ret=$default - echo $ret + local section=$1 + local option=$2 + local default=$3 + ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret } # if command starts with an option, prepend mysqld @@ -18,8 +18,8 @@ fi if [ "$1" = 'mysqld' ]; then # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") - PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then @@ -28,25 +28,27 @@ if [ "$1" = 'mysqld' ]; then exit 1 fi mkdir -p $DATADIR + chown -R mysql:mysql "$DATADIR" + echo 'Running mysql_install_db' mysql_install_db --user=mysql --datadir=$DATADIR --rpm --keep-my-cnf echo 'Finished mysql_install_db' mysqld --user=mysql --datadir=$DATADIR --skip-networking & - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] && break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 - fi - + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated @@ -58,35 +60,34 @@ if [ "$1" = 'mysqld' ]; then GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ; DROP DATABASE IF EXISTS test ; EOSQL - + if [ "$MYSQL_DATABASE" ]; then echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi - + if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" - + if [ "$MYSQL_DATABASE" ]; then echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi - + echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - - chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile rm -f $tempSqlFile kill $(cat $PIDFILE) - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL hangs during init process.' - exit 1 - fi + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi echo 'MySQL init process done. Ready for start up.' fi diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index e27fc8cf3..ef2024ab1 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -2,12 +2,12 @@ set -e get_option () { - local section=$1 - local option=$2 - local default=$3 - ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) - [ -z $ret ] && ret=$default - echo $ret + local section=$1 + local option=$2 + local default=$3 + ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret } # if command starts with an option, prepend mysqld @@ -18,8 +18,8 @@ fi if [ "$1" = 'mysqld' ]; then # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") - PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then @@ -29,21 +29,22 @@ if [ "$1" = 'mysqld' ]; then fi mkdir -p $DATADIR + chown -R mysql:mysql "$DATADIR" echo 'Initializing database' mysqld --initialize-insecure=on --datadir="$DATADIR" echo 'Database initialized' mysqld --user=mysql --datadir=$DATADIR --skip-networking & - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] && break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] && break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 - fi - + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + # Workaround for bug in 5.7 that doesn't clean up after itself correctly rm -f $DATADIR/ib_logfile0 rm -f $DATADIR/ib_logfile1 @@ -51,7 +52,7 @@ if [ "$1" = 'mysqld' ]; then # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: - + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) cat > "$tempSqlFile" <<-EOSQL -- What's done in this file shouldn't be replicated @@ -63,34 +64,33 @@ if [ "$1" = 'mysqld' ]; then GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ; DROP DATABASE IF EXISTS test ; EOSQL - + if [ "$MYSQL_DATABASE" ]; then echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" fi - + if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" - + if [ "$MYSQL_DATABASE" ]; then echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" fi fi - + echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - - chown -R mysql:mysql "$DATADIR" + mysql -uroot < $tempSqlFile rm -f $tempSqlFile kill $(cat $PIDFILE) - for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break - echo 'MySQL init process in progress...' - sleep 1 + for i in $(seq 30 -1 0); do + [ -S $SOCKET ] || break + echo 'MySQL init process in progress...' + sleep 1 done - if [ $i = 0 ]; then - echo >&2 'MySQL hangs during init process.' - exit 1 - fi + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi echo 'MySQL init process done. Ready for start up.' fi From b1414563419ad0778178650c972de2377c428765 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Tue, 7 Apr 2015 11:10:43 +0200 Subject: [PATCH 6/8] Fix variable quoting inconsistencies --- 5.5/docker-entrypoint.sh | 12 ++++++------ 5.6/docker-entrypoint.sh | 14 +++++++------- 5.7/docker-entrypoint.sh | 10 +++++----- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index 26aeaaa29..2ecd27425 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -28,16 +28,16 @@ if [ "$1" = 'mysqld' ]; then echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi - mkdir -p $DATADIR + mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" echo 'Running mysql_install_db' - mysql_install_db --user=mysql --datadir=$DATADIR --rpm --basedir=/usr/local/mysql + mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --basedir=/usr/local/mysql echo 'Finished mysql_install_db' - mysqld --user=mysql --datadir=$DATADIR --skip-networking --basedir=/usr/local/mysql & + mysqld --user=mysql --datadir="$DATADIR" --skip-networking --basedir=/usr/local/mysql & for i in $(seq 30 -1 0); do - [ -S $SOCKET ] && break + [ -S "$SOCKET" ] && break echo 'MySQL init process in progress...' sleep 1 done @@ -76,9 +76,9 @@ if [ "$1" = 'mysqld' ]; then echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - mysql -uroot < $tempSqlFile + mysql -uroot < "$tempSqlFile" - rm -f $tempSqlFile + rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do [ -S $SOCKET ] || break diff --git a/5.6/docker-entrypoint.sh b/5.6/docker-entrypoint.sh index 50af4a1a6..d7502eb1a 100755 --- a/5.6/docker-entrypoint.sh +++ b/5.6/docker-entrypoint.sh @@ -18,7 +18,7 @@ fi if [ "$1" = 'mysqld' ]; then # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + SOCKET=$(get_option mysqld socket "$DATADIR/mysql.sock") PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then @@ -27,16 +27,16 @@ if [ "$1" = 'mysqld' ]; then echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi - mkdir -p $DATADIR + mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" echo 'Running mysql_install_db' - mysql_install_db --user=mysql --datadir=$DATADIR --rpm --keep-my-cnf + mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --keep-my-cnf echo 'Finished mysql_install_db' - mysqld --user=mysql --datadir=$DATADIR --skip-networking & + mysqld --user=mysql --datadir="$DATADIR" --skip-networking & for i in $(seq 30 -1 0); do - [ -S $SOCKET ] && break + [ -S "$SOCKET" ] && break echo 'MySQL init process in progress...' sleep 1 done @@ -75,9 +75,9 @@ if [ "$1" = 'mysqld' ]; then echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - mysql -uroot < $tempSqlFile + mysql -uroot < "$tempSqlFile" - rm -f $tempSqlFile + rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do [ -S $SOCKET ] || break diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index ef2024ab1..ea8989183 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -18,7 +18,7 @@ fi if [ "$1" = 'mysqld' ]; then # Get config DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" - SOCKET=$(get_option mysqld socket "$datadir/mysql.sock") + SOCKET=$(get_option mysqld socket "$DATADIR/mysql.sock") PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then @@ -28,13 +28,13 @@ if [ "$1" = 'mysqld' ]; then exit 1 fi - mkdir -p $DATADIR + mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" echo 'Initializing database' mysqld --initialize-insecure=on --datadir="$DATADIR" echo 'Database initialized' - mysqld --user=mysql --datadir=$DATADIR --skip-networking & + mysqld --user=mysql --datadir="$DATADIR" --skip-networking & for i in $(seq 30 -1 0); do [ -S $SOCKET ] && break echo 'MySQL init process in progress...' @@ -79,8 +79,8 @@ if [ "$1" = 'mysqld' ]; then echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" - mysql -uroot < $tempSqlFile - rm -f $tempSqlFile + mysql -uroot < "$tempSqlFile" + rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do [ -S $SOCKET ] || break From ae647b4e7b39ed49c453a31de63e3578a992fbf4 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Tue, 14 Apr 2015 13:58:49 +0200 Subject: [PATCH 7/8] Various fixes. * Removed unnecessary folder check * Specify pid-file for 5.5 instead of using hostname * Change server shutdown check to be more reliable (socket is closed before all resources are released, which could lead to issues) --- 5.5/docker-entrypoint.sh | 9 +++++---- 5.6/docker-entrypoint.sh | 5 +++-- 5.7/docker-entrypoint.sh | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index 2ecd27425..deabc099f 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -20,7 +20,7 @@ if [ "$1" = 'mysqld' ]; then DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" SOCKET=$(get_option mysqld socket "/tmp/mysql.sock") HOSTNAME=$(hostname) - PIDFILE=$(get_option mysqld pid-file "$DATADIR/$HOSTNAME.pid") + PIDFILE=$(get_option mysqld pid-file "$DATADIR/mysqld.pid") if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then @@ -28,6 +28,7 @@ if [ "$1" = 'mysqld' ]; then echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi + mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" @@ -35,7 +36,7 @@ if [ "$1" = 'mysqld' ]; then mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --basedir=/usr/local/mysql echo 'Finished mysql_install_db' - mysqld --user=mysql --datadir="$DATADIR" --skip-networking --basedir=/usr/local/mysql & + mysqld --user=mysql --datadir="$DATADIR" --skip-networking --basedir=/usr/local/mysql --pid-file="$PIDFILE" & for i in $(seq 30 -1 0); do [ -S "$SOCKET" ] && break echo 'MySQL init process in progress...' @@ -63,7 +64,7 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then @@ -81,7 +82,7 @@ if [ "$1" = 'mysqld' ]; then rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break + [ -f "$PIDFILE" ] || break echo 'MySQL init process in progress...' sleep 1 done diff --git a/5.6/docker-entrypoint.sh b/5.6/docker-entrypoint.sh index d7502eb1a..8e85cfe92 100755 --- a/5.6/docker-entrypoint.sh +++ b/5.6/docker-entrypoint.sh @@ -27,6 +27,7 @@ if [ "$1" = 'mysqld' ]; then echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' exit 1 fi + mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" @@ -62,7 +63,7 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then @@ -80,7 +81,7 @@ if [ "$1" = 'mysqld' ]; then rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break + [ -f "$PIDFILE" ] || break echo 'MySQL init process in progress...' sleep 1 done diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index ea8989183..20a9141c5 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -30,6 +30,7 @@ if [ "$1" = 'mysqld' ]; then mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" + echo 'Initializing database' mysqld --initialize-insecure=on --datadir="$DATADIR" echo 'Database initialized' @@ -66,7 +67,7 @@ if [ "$1" = 'mysqld' ]; then EOSQL if [ "$MYSQL_DATABASE" ]; then - echo "CREATE DATABASE IF NOT EXISTS \`"$MYSQL_DATABASE"\` ;" >> "$tempSqlFile" + echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" fi if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then @@ -83,7 +84,7 @@ if [ "$1" = 'mysqld' ]; then rm -f "$tempSqlFile" kill $(cat $PIDFILE) for i in $(seq 30 -1 0); do - [ -S $SOCKET ] || break + [ -f "$PIDFILE" ] || break echo 'MySQL init process in progress...' sleep 1 done From 0fd8c6845ed83239f36daa48a66c8e42eac3dc46 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Wed, 3 Jun 2015 10:18:39 +0200 Subject: [PATCH 8/8] Removed workaround that isn't needed on current Debian image --- 5.7/docker-entrypoint.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/5.7/docker-entrypoint.sh b/5.7/docker-entrypoint.sh index 20a9141c5..f8d0086f2 100755 --- a/5.7/docker-entrypoint.sh +++ b/5.7/docker-entrypoint.sh @@ -46,10 +46,6 @@ if [ "$1" = 'mysqld' ]; then exit 1 fi - # Workaround for bug in 5.7 that doesn't clean up after itself correctly - rm -f $DATADIR/ib_logfile0 - rm -f $DATADIR/ib_logfile1 - rm -f $DATADIR/ibdata1 # These statements _must_ be on individual lines, and _must_ end with # semicolons (no line breaks or comments are permitted). # TODO proper SQL escaping on ALL the things D: