Skip to content

Commit 7a557cd

Browse files
committed
Adjustments from tianon's comments
- move PASSFILE to a function `_mysql_passfile` - consistently use `-n` over `! -z` or `[ "$var" ]` - drop 5.5 specific blocks - move `docker_create_db_directories` up - rename `_want_help` to `_mysql_want_help` to match new `_mysql_passfile`
1 parent a92a18c commit 7a557cd

File tree

4 files changed

+152
-144
lines changed

4 files changed

+152
-144
lines changed

.template.Debian/docker-entrypoint.sh

+38-36
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ docker_temp_server_start() {
8585
fi
8686

8787
# For 5.7+ the server is ready for use as soon as startup command unblocks
88-
if [ "${MYSQL_MAJOR}" = "5.5" ] || [ "${MYSQL_MAJOR}" = "5.6" ]; then
88+
if [ "${MYSQL_MAJOR}" = "5.6" ]; then
8989
mysql_note "Waiting for server startup"
9090
local i
9191
for i in {30..0}; do
92-
if docker_process_sql --database=mysql <<<'SELECT 1' &> /dev/null; then
92+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
93+
# so that it won't try to fill in a password file when it hasn't been set yet
94+
if MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<<'SELECT 1' &> /dev/null; then
9395
break
9496
fi
9597
sleep 1
@@ -104,7 +106,7 @@ docker_temp_server_start() {
104106
# the shutdown is complete.
105107
docker_temp_server_stop() {
106108
local result=0
107-
mysqladmin --defaults-extra-file=<( echo "${PASSFILE}" ) shutdown -uroot --socket="${SOCKET}" || result=$?
109+
mysqladmin --defaults-extra-file=<( _mysql_passfile ) shutdown -uroot --socket="${SOCKET}" || result=$?
108110
if [ "$result" != "0" ]; then
109111
mysql_error "Unable to shut down server. Status code $result."
110112
fi
@@ -170,25 +172,29 @@ docker_process_sql() {
170172
set -- --database="$MYSQL_DATABASE" "$@"
171173
fi
172174

173-
mysql --defaults-file=<( echo "${PASSFILE}" ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
175+
mysql --defaults-file=<( _mysql_passfile ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
174176
}
175177

176178
# Initializes database with timezone info and root password, plus optional extra db/user
177179
docker_setup_db() {
178180
# Load timezone info into database
179181
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
180182
# sed is for https://bugs.mysql.com/bug.php?id=20545
181-
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | docker_process_sql --database=mysql
183+
mysql_tzinfo_to_sql /usr/share/zoneinfo \
184+
| sed 's/Local time zone must be set--see zic manual page/FCTY/' \
185+
| MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql
186+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
187+
# so that it won't try to fill in a password file when it hasn't been set yet
182188
fi
183189
# Generate random root password
184-
if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
190+
if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
185191
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
186192
mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
187193
fi
188194
# Sets root password and creates root users for non-localhost hosts
189195
rootCreate=
190196
# default root to listen for connections from anywhere
191-
if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
197+
if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
192198
# no, we don't care if read finds a terminating character in this heredoc
193199
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
194200
read -r -d '' rootCreate <<-EOSQL || true
@@ -197,7 +203,9 @@ docker_setup_db() {
197203
EOSQL
198204
fi
199205

200-
docker_process_sql --database=mysql <<-EOSQL
206+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
207+
# so that it won't try to fill in a password file when it is just now being set
208+
MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<-EOSQL
201209
-- What's done in this file shouldn't be replicated
202210
-- or products like mysql-fabric won't work
203211
SET @@SESSION.SQL_LOG_BIN=0;
@@ -209,27 +217,17 @@ docker_setup_db() {
209217
DROP DATABASE IF EXISTS test ;
210218
EOSQL
211219

212-
# Write the password to the "file" the client uses
213-
# the client command will use process substitution to create a file on the fly
214-
# ie: --defaults-file=<( echo "${PASSFILE}" )
215-
if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
216-
read -r -d '' PASSFILE <<-EOF || true
217-
[client]
218-
password="${MYSQL_ROOT_PASSWORD}"
219-
EOF
220-
fi
221-
222220
# Creates a custom database and user if specified
223-
if [ "$MYSQL_DATABASE" ]; then
221+
if [ -n "$MYSQL_DATABASE" ]; then
224222
mysql_note "Creating database ${MYSQL_DATABASE}"
225223
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;"
226224
fi
227225

228-
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
226+
if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then
229227
mysql_note "Creating user ${MYSQL_USER}"
230228
docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;"
231229

232-
if [ "$MYSQL_DATABASE" ]; then
230+
if [ -n "$MYSQL_DATABASE" ]; then
233231
mysql_note "Giving user ${MYSQL_USER} access to schema ${MYSQL_DATABASE}"
234232
docker_process_sql --database=mysql <<<"GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;"
235233
fi
@@ -238,23 +236,31 @@ docker_setup_db() {
238236
fi
239237
}
240238

239+
_mysql_passfile() {
240+
# echo the password to the "file" the client uses
241+
# the client command will use process substitution to create a file on the fly
242+
# ie: --defaults-file=<( _mysql_passfile )
243+
if [ -n "$MYSQL_ROOT_PASSWORD" ]; then
244+
cat <<-EOF
245+
[client]
246+
password="${MYSQL_ROOT_PASSWORD}"
247+
EOF
248+
fi
249+
}
250+
241251
# Mark root user as expired so the password must be changed before anything
242252
# else can be done (only supported for 5.6+)
243253
mysql_expire_root_user() {
244-
if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
245-
if [ "${MYSQL_MAJOR}" = "5.5" ]; then
246-
mysql_warn "MySQL 5.5 does not support PASSWORD EXPIRE (required for MYSQL_ONETIME_PASSWORD)"
247-
else
248-
docker_process_sql --database=mysql <<-EOSQL
249-
ALTER USER 'root'@'%' PASSWORD EXPIRE;
250-
EOSQL
251-
fi
254+
if [ -n "$MYSQL_ONETIME_PASSWORD" ]; then
255+
docker_process_sql --database=mysql <<-EOSQL
256+
ALTER USER 'root'@'%' PASSWORD EXPIRE;
257+
EOSQL
252258
fi
253259
}
254260

255261
# check arguments for an option that would cause mysqld to stop
256262
# return true if there is one
257-
_want_help() {
263+
_mysql_want_help() {
258264
local arg
259265
for arg; do
260266
case "$arg" in
@@ -273,23 +279,20 @@ _main() {
273279
fi
274280

275281
# skip setup if they aren't running mysqld or want an option that stops mysqld
276-
if [ "$1" = 'mysqld' ] && ! _want_help "$@"; then
282+
if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
277283
mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
278284

279285
# Load various environment variables
280286
docker_setup_env "$@"
281287
mysql_check_config "$@"
288+
docker_create_db_directories
282289

283290
# If container is started as root user, restart as dedicated mysql user
284291
if [ "$(id -u)" = "0" ]; then
285-
docker_create_db_directories
286292
mysql_note "Switching to dedicated user 'mysql'"
287293
exec gosu mysql "$BASH_SOURCE" "$@"
288294
fi
289295

290-
# just in case the script was not started as root
291-
docker_create_db_directories
292-
293296
# If this is true then there's no database, and it needs to be initialized
294297
if [ ! -d "$DATADIR/mysql" ]; then
295298
docker_verify_minimum_env
@@ -308,7 +311,6 @@ _main() {
308311
docker_temp_server_stop
309312
mysql_note "Temporary server stopped"
310313

311-
unset PASSFILE
312314
echo
313315
mysql_note "MySQL init process done. Ready for start up."
314316
echo

5.6/docker-entrypoint.sh

+38-36
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ docker_temp_server_start() {
8585
fi
8686

8787
# For 5.7+ the server is ready for use as soon as startup command unblocks
88-
if [ "${MYSQL_MAJOR}" = "5.5" ] || [ "${MYSQL_MAJOR}" = "5.6" ]; then
88+
if [ "${MYSQL_MAJOR}" = "5.6" ]; then
8989
mysql_note "Waiting for server startup"
9090
local i
9191
for i in {30..0}; do
92-
if docker_process_sql --database=mysql <<<'SELECT 1' &> /dev/null; then
92+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
93+
# so that it won't try to fill in a password file when it hasn't been set yet
94+
if MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<<'SELECT 1' &> /dev/null; then
9395
break
9496
fi
9597
sleep 1
@@ -104,7 +106,7 @@ docker_temp_server_start() {
104106
# the shutdown is complete.
105107
docker_temp_server_stop() {
106108
local result=0
107-
mysqladmin --defaults-extra-file=<( echo "${PASSFILE}" ) shutdown -uroot --socket="${SOCKET}" || result=$?
109+
mysqladmin --defaults-extra-file=<( _mysql_passfile ) shutdown -uroot --socket="${SOCKET}" || result=$?
108110
if [ "$result" != "0" ]; then
109111
mysql_error "Unable to shut down server. Status code $result."
110112
fi
@@ -170,25 +172,29 @@ docker_process_sql() {
170172
set -- --database="$MYSQL_DATABASE" "$@"
171173
fi
172174

173-
mysql --defaults-file=<( echo "${PASSFILE}" ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
175+
mysql --defaults-file=<( _mysql_passfile ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
174176
}
175177

176178
# Initializes database with timezone info and root password, plus optional extra db/user
177179
docker_setup_db() {
178180
# Load timezone info into database
179181
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
180182
# sed is for https://bugs.mysql.com/bug.php?id=20545
181-
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | docker_process_sql --database=mysql
183+
mysql_tzinfo_to_sql /usr/share/zoneinfo \
184+
| sed 's/Local time zone must be set--see zic manual page/FCTY/' \
185+
| MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql
186+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
187+
# so that it won't try to fill in a password file when it hasn't been set yet
182188
fi
183189
# Generate random root password
184-
if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
190+
if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
185191
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
186192
mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
187193
fi
188194
# Sets root password and creates root users for non-localhost hosts
189195
rootCreate=
190196
# default root to listen for connections from anywhere
191-
if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
197+
if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
192198
# no, we don't care if read finds a terminating character in this heredoc
193199
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
194200
read -r -d '' rootCreate <<-EOSQL || true
@@ -197,7 +203,9 @@ docker_setup_db() {
197203
EOSQL
198204
fi
199205

200-
docker_process_sql --database=mysql <<-EOSQL
206+
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
207+
# so that it won't try to fill in a password file when it is just now being set
208+
MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<-EOSQL
201209
-- What's done in this file shouldn't be replicated
202210
-- or products like mysql-fabric won't work
203211
SET @@SESSION.SQL_LOG_BIN=0;
@@ -210,27 +218,17 @@ SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}');
210218
DROP DATABASE IF EXISTS test ;
211219
EOSQL
212220

213-
# Write the password to the "file" the client uses
214-
# the client command will use process substitution to create a file on the fly
215-
# ie: --defaults-file=<( echo "${PASSFILE}" )
216-
if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
217-
read -r -d '' PASSFILE <<-EOF || true
218-
[client]
219-
password="${MYSQL_ROOT_PASSWORD}"
220-
EOF
221-
fi
222-
223221
# Creates a custom database and user if specified
224-
if [ "$MYSQL_DATABASE" ]; then
222+
if [ -n "$MYSQL_DATABASE" ]; then
225223
mysql_note "Creating database ${MYSQL_DATABASE}"
226224
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;"
227225
fi
228226

229-
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
227+
if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then
230228
mysql_note "Creating user ${MYSQL_USER}"
231229
docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;"
232230

233-
if [ "$MYSQL_DATABASE" ]; then
231+
if [ -n "$MYSQL_DATABASE" ]; then
234232
mysql_note "Giving user ${MYSQL_USER} access to schema ${MYSQL_DATABASE}"
235233
docker_process_sql --database=mysql <<<"GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;"
236234
fi
@@ -239,23 +237,31 @@ SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}');
239237
fi
240238
}
241239

240+
_mysql_passfile() {
241+
# echo the password to the "file" the client uses
242+
# the client command will use process substitution to create a file on the fly
243+
# ie: --defaults-file=<( _mysql_passfile )
244+
if [ -n "$MYSQL_ROOT_PASSWORD" ]; then
245+
cat <<-EOF
246+
[client]
247+
password="${MYSQL_ROOT_PASSWORD}"
248+
EOF
249+
fi
250+
}
251+
242252
# Mark root user as expired so the password must be changed before anything
243253
# else can be done (only supported for 5.6+)
244254
mysql_expire_root_user() {
245-
if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
246-
if [ "${MYSQL_MAJOR}" = "5.5" ]; then
247-
mysql_warn "MySQL 5.5 does not support PASSWORD EXPIRE (required for MYSQL_ONETIME_PASSWORD)"
248-
else
249-
docker_process_sql --database=mysql <<-EOSQL
250-
ALTER USER 'root'@'%' PASSWORD EXPIRE;
251-
EOSQL
252-
fi
255+
if [ -n "$MYSQL_ONETIME_PASSWORD" ]; then
256+
docker_process_sql --database=mysql <<-EOSQL
257+
ALTER USER 'root'@'%' PASSWORD EXPIRE;
258+
EOSQL
253259
fi
254260
}
255261

256262
# check arguments for an option that would cause mysqld to stop
257263
# return true if there is one
258-
_want_help() {
264+
_mysql_want_help() {
259265
local arg
260266
for arg; do
261267
case "$arg" in
@@ -274,23 +280,20 @@ _main() {
274280
fi
275281

276282
# skip setup if they aren't running mysqld or want an option that stops mysqld
277-
if [ "$1" = 'mysqld' ] && ! _want_help "$@"; then
283+
if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
278284
mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
279285

280286
# Load various environment variables
281287
docker_setup_env "$@"
282288
mysql_check_config "$@"
289+
docker_create_db_directories
283290

284291
# If container is started as root user, restart as dedicated mysql user
285292
if [ "$(id -u)" = "0" ]; then
286-
docker_create_db_directories
287293
mysql_note "Switching to dedicated user 'mysql'"
288294
exec gosu mysql "$BASH_SOURCE" "$@"
289295
fi
290296

291-
# just in case the script was not started as root
292-
docker_create_db_directories
293-
294297
# If this is true then there's no database, and it needs to be initialized
295298
if [ ! -d "$DATADIR/mysql" ]; then
296299
docker_verify_minimum_env
@@ -309,7 +312,6 @@ _main() {
309312
docker_temp_server_stop
310313
mysql_note "Temporary server stopped"
311314

312-
unset PASSFILE
313315
echo
314316
mysql_note "MySQL init process done. Ready for start up."
315317
echo

0 commit comments

Comments
 (0)