From d0ee591084f44034e87ec2129e12afbbd49c6377 Mon Sep 17 00:00:00 2001 From: Lars Tangvald Date: Fri, 7 Jul 2017 12:05:11 +0200 Subject: [PATCH] All sources generated genOracleLinux executed --- 5.5/Dockerfile | 29 ++++++-- 5.5/docker-entrypoint.sh | 152 +++++++++++++++++++++++++++---------- 5.5/healthcheck.sh | 24 ++++++ 5.6/Dockerfile | 31 ++++++-- 5.6/docker-entrypoint.sh | 157 +++++++++++++++++++++++++++------------ 5.6/healthcheck.sh | 24 ++++++ 5.7/Dockerfile | 30 ++++++-- 5.7/docker-entrypoint.sh | 154 +++++++++++++++++++++++++++----------- 5.7/healthcheck.sh | 24 ++++++ 8.0/Dockerfile | 30 ++++++-- 8.0/docker-entrypoint.sh | 154 +++++++++++++++++++++++++++----------- 8.0/healthcheck.sh | 24 ++++++ genOracleLinux.sh | 8 +- 13 files changed, 633 insertions(+), 208 deletions(-) create mode 100755 5.5/healthcheck.sh create mode 100755 5.6/healthcheck.sh create mode 100755 5.7/healthcheck.sh create mode 100755 8.0/healthcheck.sh diff --git a/5.5/Dockerfile b/5.5/Dockerfile index 64b59052d..3fcd279cc 100644 --- a/5.5/Dockerfile +++ b/5.5/Dockerfile @@ -1,19 +1,34 @@ +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA FROM oraclelinux:7-slim -ENV PACKAGE_URL http://repo.mysql.com/yum/mysql-5.5-community/docker/x86_64/mysql-community-server-minimal-5.5.55-2.el7.x86_64.rpm +ARG PACKAGE_URL=https://repo.mysql.com/yum/mysql-5.5-community/docker/x86_64/mysql-community-server-minimal-5.5.57-2.el7.x86_64.rpm +ARG PACKAGE_URL_SHELL="" # Install server -RUN rpmkeys --import http://repo.mysql.com/RPM-GPG-KEY-mysql \ - && yum install -y $PACKAGE_URL \ - && yum install -y libpwquality \ - && rm -rf /var/cache/yum/* -RUN mkdir /docker-entrypoint-initdb.d +RUN rpmkeys --import https://repo.mysql.com/RPM-GPG-KEY-mysql \ + && yum install -y $PACKAGE_URL $PACKAGE_URL_SHELL libpwquality \ + && yum clean all \ + && mkdir /docker-entrypoint-initdb.d VOLUME /var/lib/mysql COPY docker-entrypoint.sh /entrypoint.sh +COPY healthcheck.sh /healthcheck.sh ENTRYPOINT ["/entrypoint.sh"] - +HEALTHCHECK CMD /healthcheck.sh EXPOSE 3306 CMD ["mysqld"] diff --git a/5.5/docker-entrypoint.sh b/5.5/docker-entrypoint.sh index f236477e9..cc30febc6 100755 --- a/5.5/docker-entrypoint.sh +++ b/5.5/docker-entrypoint.sh @@ -1,29 +1,58 @@ #!/bin/bash +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA set -e -# if command starts with an option, prepend mysqld +echo "[Entrypoint] MySQL Docker Image 5.5.57-1.1.0" +# Fetch value from server config +# We use mysqld --verbose --help instead of my_print_defaults because the +# latter only show values present in config files, and not server defaults +_get_config() { + local conf="$1"; shift + "$@" --verbose --help 2>/dev/null | grep "^$conf" | awk '$1 == "'"$conf"'" { print $2; exit }' +} + +# If command starts with an option, prepend mysqld +# This allows users to add command-line options without +# needing to specify the "mysqld" command if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # Test we're able to startup without errors. We redirect stdout to /dev/null so + # Test that the server can start. We redirect stdout to /dev/null so # only the error messages are left. result=0 output=$("$@" --verbose --help 2>&1 > /dev/null) || result=$? if [ ! "$result" = "0" ]; then - echo >&2 'error: could not run mysql. This could be caused by a misconfigured my.cnf' - echo >&2 "$output" + echo >&2 '[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.' + echo >&2 "[Entrypoint] $output" exit 1 fi # Get config - DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + DATADIR="$(_get_config 'datadir' "$@")" + SOCKET="$(_get_config 'socket' "$@")" if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then - echo >&2 'error: database is uninitialized and password option is not specified ' - echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD' + echo >&2 '[Entrypoint] ERROR: No password option specified for new database.' + echo >&2 '[Entrypoint] You need to specify one of the following:' + echo >&2 '[Entrypoint] - MYSQL_RANDOM_ROOT_PASSWORD (recommended)' + echo >&2 '[Entrypoint] - MYSQL_ROOT_PASSWORD' + echo >&2 '[Entrypoint] - MYSQL_ALLOW_EMPTY_PASSWORD' exit 1 fi # If the password variable is a filename we use the contents of the file @@ -33,32 +62,38 @@ if [ "$1" = 'mysqld' ]; then mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" - echo 'Running mysql_install_db' + echo '[Entrypoint] Initializing database' mysql_install_db --user=mysql --datadir="$DATADIR" --rpm - echo 'Finished mysql_install_db' - - "$@" --skip-networking --socket=/var/run/mysqld/mysqld.sock & - pid="$!" - - mysql=( mysql --protocol=socket -uroot -hlocalhost --socket=/var/run/mysqld/mysqld.sock) - - for i in {30..0}; do - if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then - break + echo '[Entrypoint] Database initialized' + + "$@" --skip-networking --socket="$SOCKET" & + + # To avoid using password on commandline, put it in a temporary file. + # The file is only populated when and if the root password is set. + PASSFILE=$(mktemp -u /var/lib/mysql-files/XXXXXXXXXX) + install /dev/null -m0600 -omysql -gmysql "$PASSFILE" + mysql=( mysql --defaults-extra-file="$PASSFILE" --protocol=socket -uroot -hlocalhost --socket="$SOCKET") + + if [ ! -z "yes" ]; + then + for i in {30..0}; do + if mysqladmin --socket="$SOCKET" ping &>/dev/null; then + break + fi + echo '[Entrypoint] Waiting for server...' + sleep 1 + done + if [ "$i" = 0 ]; then + echo >&2 '[Entrypoint] Timeout during MySQL init.' + exit 1 fi - echo 'MySQL init process in progress...' - sleep 1 - done - if [ "$i" = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 fi - mysql_tzinfo_to_sql /usr/share/zoneinfo | "${mysql[@]}" mysql - + mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql + if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then MYSQL_ROOT_PASSWORD="$(pwmake 128)" - echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" + echo "[Entrypoint] GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" fi if [ -z "$MYSQL_ROOT_HOST" ]; then ROOTCREATE="SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}');" @@ -71,13 +106,18 @@ if [ "$1" = 'mysqld' ]; then -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work SET @@SESSION.SQL_LOG_BIN=0; - DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost'); + DELETE FROM mysql.user WHERE user NOT IN ('mysql.session', 'mysql.sys', 'root') OR host NOT IN ('localhost'); + CREATE USER 'healthchecker'@'localhost' IDENTIFIED BY 'healthcheckpass'; ${ROOTCREATE} - DROP DATABASE IF EXISTS test ; FLUSH PRIVILEGES ; EOSQL if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then - mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) + # Put the password into the temporary config file + cat >"$PASSFILE" <&2 'MySQL init process failed.' - exit 1 + # When using a local socket, mysqladmin shutdown will only complete when the server is actually down + mysqladmin --defaults-extra-file="$PASSFILE" shutdown -uroot --socket="$SOCKET" + rm -f "$PASSFILE" + unset PASSFILE + echo "[Entrypoint] Server shut down" + + # This needs to be done outside the normal init, since mysqladmin shutdown will not work after + if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then + if [ -z "" ]; then + echo "[Entrypoint] User expiration is only supported in MySQL 5.6+" + else + echo "[Entrypoint] Setting root user as expired. Password will need to be changed before database can be used." + SQL=$(mktemp -u /var/lib/mysql-files/XXXXXXXXXX) + install /dev/null -m0600 -omysql -gmysql "$SQL" + if [ ! -z "$MYSQL_ROOT_HOST" ]; then + cat << EOF > "$SQL" +ALTER USER 'root'@'${MYSQL_ROOT_HOST}' PASSWORD EXPIRE; +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + else + cat << EOF > "$SQL" +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + fi + set -- "$@" --init-file="$SQL" + unset SQL + fi fi echo - echo 'MySQL init process done. Ready for start up.' + echo '[Entrypoint] MySQL init process done. Ready for start up.' echo fi + # Used by healthcheck to make sure it doesn't mistakenly report container + # healthy during startup + # Put the password into the temporary config file + touch /healthcheck.cnf + cat >"/healthcheck.cnf" </dev/null | grep "^$conf" | awk '$1 == "'"$conf"'" { print $2; exit }' +} + +# If command starts with an option, prepend mysqld +# This allows users to add command-line options without +# needing to specify the "mysqld" command if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # Test we're able to startup without errors. We redirect stdout to /dev/null so + # Test that the server can start. We redirect stdout to /dev/null so # only the error messages are left. result=0 output=$("$@" --verbose --help 2>&1 > /dev/null) || result=$? if [ ! "$result" = "0" ]; then - echo >&2 'error: could not run mysql. This could be caused by a misconfigured my.cnf' - echo >&2 "$output" + echo >&2 '[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.' + echo >&2 "[Entrypoint] $output" exit 1 fi # Get config - DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + DATADIR="$(_get_config 'datadir' "$@")" + SOCKET="$(_get_config 'socket' "$@")" if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then - echo >&2 'error: database is uninitialized and password option is not specified ' - echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD' + echo >&2 '[Entrypoint] ERROR: No password option specified for new database.' + echo >&2 '[Entrypoint] You need to specify one of the following:' + echo >&2 '[Entrypoint] - MYSQL_RANDOM_ROOT_PASSWORD (recommended)' + echo >&2 '[Entrypoint] - MYSQL_ROOT_PASSWORD' + echo >&2 '[Entrypoint] - MYSQL_ALLOW_EMPTY_PASSWORD' exit 1 fi # If the password variable is a filename we use the contents of the file @@ -33,33 +62,38 @@ if [ "$1" = 'mysqld' ]; then mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" - echo 'Running mysql_install_db' + echo '[Entrypoint] Initializing database' mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --keep-my-cnf - echo 'Finished mysql_install_db' - - "$@" --skip-networking --socket=/var/run/mysqld/mysqld.sock & - pid="$!" - - mysql=( mysql --protocol=socket -uroot -hlocalhost --socket=/var/run/mysqld/mysqld.sock) - - for i in {30..0}; do - if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then - break + echo '[Entrypoint] Database initialized' + + "$@" --skip-networking --socket="$SOCKET" & + + # To avoid using password on commandline, put it in a temporary file. + # The file is only populated when and if the root password is set. + PASSFILE=$(mktemp -u /var/lib/mysql-files/XXXXXXXXXX) + install /dev/null -m0600 -omysql -gmysql "$PASSFILE" + mysql=( mysql --defaults-extra-file="$PASSFILE" --protocol=socket -uroot -hlocalhost --socket="$SOCKET") + + if [ ! -z "yes" ]; + then + for i in {30..0}; do + if mysqladmin --socket="$SOCKET" ping &>/dev/null; then + break + fi + echo '[Entrypoint] Waiting for server...' + sleep 1 + done + if [ "$i" = 0 ]; then + echo >&2 '[Entrypoint] Timeout during MySQL init.' + exit 1 fi - echo 'MySQL init process in progress...' - sleep 1 - done - if [ "$i" = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 fi - # sed is for https://bugs.mysql.com/bug.php?id=20545 mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql - + if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then MYSQL_ROOT_PASSWORD="$(pwmake 128)" - echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" + echo "[Entrypoint] GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" fi if [ -z "$MYSQL_ROOT_HOST" ]; then ROOTCREATE="SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}');" @@ -72,13 +106,18 @@ if [ "$1" = 'mysqld' ]; then -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work SET @@SESSION.SQL_LOG_BIN=0; - DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost'); + DELETE FROM mysql.user WHERE user NOT IN ('mysql.session', 'mysql.sys', 'root') OR host NOT IN ('localhost'); + CREATE USER 'healthchecker'@'localhost' IDENTIFIED BY 'healthcheckpass'; ${ROOTCREATE} - DROP DATABASE IF EXISTS test ; FLUSH PRIVILEGES ; EOSQL if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then - mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) + # Put the password into the temporary config file + cat >"$PASSFILE" < "$SQL" +ALTER USER 'root'@'${MYSQL_ROOT_HOST}' PASSWORD EXPIRE; +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + else + cat << EOF > "$SQL" +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + fi + set -- "$@" --init-file="$SQL" + unset SQL fi fi - if ! kill -s TERM "$pid" || ! wait "$pid"; then - echo >&2 'MySQL init process failed.' - exit 1 - fi echo - echo 'MySQL init process done. Ready for start up.' + echo '[Entrypoint] MySQL init process done. Ready for start up.' echo fi + # Used by healthcheck to make sure it doesn't mistakenly report container + # healthy during startup + # Put the password into the temporary config file + touch /healthcheck.cnf + cat >"/healthcheck.cnf" </dev/null | grep "^$conf" | awk '$1 == "'"$conf"'" { print $2; exit }' +} + +# If command starts with an option, prepend mysqld +# This allows users to add command-line options without +# needing to specify the "mysqld" command if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # Test we're able to startup without errors. We redirect stdout to /dev/null so + # Test that the server can start. We redirect stdout to /dev/null so # only the error messages are left. result=0 output=$("$@" --verbose --help 2>&1 > /dev/null) || result=$? if [ ! "$result" = "0" ]; then - echo >&2 'error: could not run mysql. This could be caused by a misconfigured my.cnf' - echo >&2 "$output" + echo >&2 '[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.' + echo >&2 "[Entrypoint] $output" exit 1 fi # Get config - DATADIR="$("$@" --verbose --help --log-bin-index=/tmp/tmp.index 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + DATADIR="$(_get_config 'datadir' "$@")" + SOCKET="$(_get_config 'socket' "$@")" if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then - echo >&2 'error: database is uninitialized and password option is not specified ' - echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD' + echo >&2 '[Entrypoint] ERROR: No password option specified for new database.' + echo >&2 '[Entrypoint] You need to specify one of the following:' + echo >&2 '[Entrypoint] - MYSQL_RANDOM_ROOT_PASSWORD (recommended)' + echo >&2 '[Entrypoint] - MYSQL_ROOT_PASSWORD' + echo >&2 '[Entrypoint] - MYSQL_ALLOW_EMPTY_PASSWORD' exit 1 fi # If the password variable is a filename we use the contents of the file @@ -33,32 +62,38 @@ if [ "$1" = 'mysqld' ]; then mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" - echo 'Initializing database' - "$@" --initialize-insecure=on - echo 'Database initialized' - - "$@" --skip-networking --socket=/var/run/mysqld/mysqld.sock & - pid="$!" - - mysql=( mysql --protocol=socket -uroot -hlocalhost --socket=/var/run/mysqld/mysqld.sock) - - for i in {30..0}; do - if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then - break + echo '[Entrypoint] Initializing database' + "$@" --initialize-insecure + echo '[Entrypoint] Database initialized' + + "$@" --daemonize --skip-networking --socket="$SOCKET" + + # To avoid using password on commandline, put it in a temporary file. + # The file is only populated when and if the root password is set. + PASSFILE=$(mktemp -u /var/lib/mysql-files/XXXXXXXXXX) + install /dev/null -m0600 -omysql -gmysql "$PASSFILE" + mysql=( mysql --defaults-extra-file="$PASSFILE" --protocol=socket -uroot -hlocalhost --socket="$SOCKET") + + if [ ! -z "" ]; + then + for i in {30..0}; do + if mysqladmin --socket="$SOCKET" ping &>/dev/null; then + break + fi + echo '[Entrypoint] Waiting for server...' + sleep 1 + done + if [ "$i" = 0 ]; then + echo >&2 '[Entrypoint] Timeout during MySQL init.' + exit 1 fi - echo 'MySQL init process in progress...' - sleep 1 - done - if [ "$i" = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 fi mysql_tzinfo_to_sql /usr/share/zoneinfo | "${mysql[@]}" mysql if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then MYSQL_ROOT_PASSWORD="$(pwmake 128)" - echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" + echo "[Entrypoint] GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" fi if [ -z "$MYSQL_ROOT_HOST" ]; then ROOTCREATE="ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';" @@ -71,13 +106,18 @@ if [ "$1" = 'mysqld' ]; then -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work SET @@SESSION.SQL_LOG_BIN=0; - DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost'); + DELETE FROM mysql.user WHERE user NOT IN ('mysql.session', 'mysql.sys', 'root') OR host NOT IN ('localhost'); + CREATE USER 'healthchecker'@'localhost' IDENTIFIED BY 'healthcheckpass'; ${ROOTCREATE} - DROP DATABASE IF EXISTS test ; FLUSH PRIVILEGES ; EOSQL if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then - mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) + # Put the password into the temporary config file + cat >"$PASSFILE" < "$SQL" +ALTER USER 'root'@'${MYSQL_ROOT_HOST}' PASSWORD EXPIRE; +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + else + cat << EOF > "$SQL" +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + fi + set -- "$@" --init-file="$SQL" + unset SQL fi fi - if ! kill -s TERM "$pid" || ! wait "$pid"; then - echo >&2 'MySQL init process failed.' - exit 1 - fi echo - echo 'MySQL init process done. Ready for start up.' + echo '[Entrypoint] MySQL init process done. Ready for start up.' echo fi + # Used by healthcheck to make sure it doesn't mistakenly report container + # healthy during startup + # Put the password into the temporary config file + touch /healthcheck.cnf + cat >"/healthcheck.cnf" </dev/null | grep "^$conf" | awk '$1 == "'"$conf"'" { print $2; exit }' +} + +# If command starts with an option, prepend mysqld +# This allows users to add command-line options without +# needing to specify the "mysqld" command if [ "${1:0:1}" = '-' ]; then set -- mysqld "$@" fi if [ "$1" = 'mysqld' ]; then - # Test we're able to startup without errors. We redirect stdout to /dev/null so + # Test that the server can start. We redirect stdout to /dev/null so # only the error messages are left. result=0 output=$("$@" --verbose --help 2>&1 > /dev/null) || result=$? if [ ! "$result" = "0" ]; then - echo >&2 'error: could not run mysql. This could be caused by a misconfigured my.cnf' - echo >&2 "$output" + echo >&2 '[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.' + echo >&2 "[Entrypoint] $output" exit 1 fi # Get config - DATADIR="$("$@" --verbose --help --log-bin-index=/tmp/tmp.index 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" + DATADIR="$(_get_config 'datadir' "$@")" + SOCKET="$(_get_config 'socket' "$@")" if [ ! -d "$DATADIR/mysql" ]; then if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then - echo >&2 'error: database is uninitialized and password option is not specified ' - echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD' + echo >&2 '[Entrypoint] ERROR: No password option specified for new database.' + echo >&2 '[Entrypoint] You need to specify one of the following:' + echo >&2 '[Entrypoint] - MYSQL_RANDOM_ROOT_PASSWORD (recommended)' + echo >&2 '[Entrypoint] - MYSQL_ROOT_PASSWORD' + echo >&2 '[Entrypoint] - MYSQL_ALLOW_EMPTY_PASSWORD' exit 1 fi # If the password variable is a filename we use the contents of the file @@ -33,32 +62,38 @@ if [ "$1" = 'mysqld' ]; then mkdir -p "$DATADIR" chown -R mysql:mysql "$DATADIR" - echo 'Initializing database' - "$@" --initialize-insecure=on - echo 'Database initialized' - - "$@" --skip-networking --socket=/var/run/mysqld/mysqld.sock & - pid="$!" - - mysql=( mysql --protocol=socket -uroot -hlocalhost --socket=/var/run/mysqld/mysqld.sock) - - for i in {30..0}; do - if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then - break + echo '[Entrypoint] Initializing database' + "$@" --initialize-insecure + echo '[Entrypoint] Database initialized' + + "$@" --daemonize --skip-networking --socket="$SOCKET" + + # To avoid using password on commandline, put it in a temporary file. + # The file is only populated when and if the root password is set. + PASSFILE=$(mktemp -u /var/lib/mysql-files/XXXXXXXXXX) + install /dev/null -m0600 -omysql -gmysql "$PASSFILE" + mysql=( mysql --defaults-extra-file="$PASSFILE" --protocol=socket -uroot -hlocalhost --socket="$SOCKET") + + if [ ! -z "" ]; + then + for i in {30..0}; do + if mysqladmin --socket="$SOCKET" ping &>/dev/null; then + break + fi + echo '[Entrypoint] Waiting for server...' + sleep 1 + done + if [ "$i" = 0 ]; then + echo >&2 '[Entrypoint] Timeout during MySQL init.' + exit 1 fi - echo 'MySQL init process in progress...' - sleep 1 - done - if [ "$i" = 0 ]; then - echo >&2 'MySQL init process failed.' - exit 1 fi mysql_tzinfo_to_sql /usr/share/zoneinfo | "${mysql[@]}" mysql if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then MYSQL_ROOT_PASSWORD="$(pwmake 128)" - echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" + echo "[Entrypoint] GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" fi if [ -z "$MYSQL_ROOT_HOST" ]; then ROOTCREATE="ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';" @@ -71,13 +106,18 @@ if [ "$1" = 'mysqld' ]; then -- What's done in this file shouldn't be replicated -- or products like mysql-fabric won't work SET @@SESSION.SQL_LOG_BIN=0; - DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost'); + DELETE FROM mysql.user WHERE user NOT IN ('mysql.session', 'mysql.sys', 'root') OR host NOT IN ('localhost'); + CREATE USER 'healthchecker'@'localhost' IDENTIFIED BY 'healthcheckpass'; ${ROOTCREATE} - DROP DATABASE IF EXISTS test ; FLUSH PRIVILEGES ; EOSQL if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then - mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) + # Put the password into the temporary config file + cat >"$PASSFILE" < "$SQL" +ALTER USER 'root'@'${MYSQL_ROOT_HOST}' PASSWORD EXPIRE; +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + else + cat << EOF > "$SQL" +ALTER USER 'root'@'localhost' PASSWORD EXPIRE; +EOF + fi + set -- "$@" --init-file="$SQL" + unset SQL fi fi - if ! kill -s TERM "$pid" || ! wait "$pid"; then - echo >&2 'MySQL init process failed.' - exit 1 - fi echo - echo 'MySQL init process done. Ready for start up.' + echo '[Entrypoint] MySQL init process done. Ready for start up.' echo fi + # Used by healthcheck to make sure it doesn't mistakenly report container + # healthy during startup + # Put the password into the temporary config file + touch /healthcheck.cnf + cat >"/healthcheck.cnf" <