Skip to content

Commit 91785a5

Browse files
committed
Add --dont-use-mysql-root-password flag for docker_process_sql
- also remove bash generating bash
1 parent 8d01eea commit 91785a5

File tree

5 files changed

+251
-135
lines changed

5 files changed

+251
-135
lines changed

.template.Debian/docker-entrypoint.sh

+54-25
Original file line numberDiff line numberDiff line change
@@ -84,27 +84,30 @@ mysql_get_config() {
8484

8585
# Do a temporary startup of the MySQL server, for init purposes
8686
docker_temp_server_start() {
87-
local result=0
88-
%%SERVERSTARTUP%%
89-
if [ "$result" != "0" ];then
90-
mysql_error "Unable to start server. Status code $result."
91-
fi
92-
93-
# For 5.7+ the server is ready for use as soon as startup command unblocks
94-
if [ "${MYSQL_MAJOR}" = "5.6" ]; then
87+
if [ "${MYSQL_MAJOR}" = '5.6' ]; then
88+
"$@" --skip-networking --socket="${SOCKET}" &
9589
mysql_note "Waiting for server startup"
9690
local i
9791
for i in {30..0}; do
98-
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
92+
# only use the root password if the database has already been initializaed
9993
# so that it won't try to fill in a password file when it hasn't been set yet
100-
if MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<<'SELECT 1' &> /dev/null; then
94+
extraArgs=()
95+
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
96+
extraArgs+=( '--dont-use-mysql-root-password' )
97+
fi
98+
if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
10199
break
102100
fi
103101
sleep 1
104102
done
105103
if [ "$i" = 0 ]; then
106104
mysql_error "Unable to start server."
107105
fi
106+
else
107+
# For 5.7+ the server is ready for use as soon as startup command unblocks
108+
if ! "$@" --daemonize --skip-networking --socket="${SOCKET}"; then
109+
mysql_error "Unable to start server."
110+
fi
108111
fi
109112
}
110113

@@ -143,7 +146,11 @@ docker_create_db_directories() {
143146
# initializes the database directory
144147
docker_init_database_dir() {
145148
mysql_note "Initializing database files"
146-
%%DATABASEINIT%%
149+
if [ "$MYSQL_MAJOR" = '5.6' ]; then
150+
mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
151+
else
152+
"$@" --initialize-insecure
153+
fi
147154
mysql_note "Database files initialized"
148155

149156
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
@@ -168,19 +175,29 @@ docker_setup_env() {
168175
file_env 'MYSQL_USER'
169176
file_env 'MYSQL_PASSWORD'
170177
file_env 'MYSQL_ROOT_PASSWORD'
178+
179+
declare -g DATABASE_ALREADY_EXISTS
180+
if [ -d "$DATADIR/mysql" ]; then
181+
DATABASE_ALREADY_EXISTS='true'
182+
fi
171183
}
172184

173185
# Execute sql script, passed via stdin
174-
# usage: docker_process_sql [mysql-cli-args]
186+
# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
175187
# ie: docker_process_sql --database=mydb <<<'INSERT ...'
176-
# ie: docker_process_sql --database=mydb <my-file.sql
188+
# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
177189
docker_process_sql() {
190+
passfileArgs=()
191+
if [ '--dont-use-mysql-root-password' = "$1" ]; then
192+
passfileArgs+=( "$1" )
193+
shift
194+
fi
178195
# args sent in can override this db, since they will be later in the command
179196
if [ -n "$MYSQL_DATABASE" ]; then
180197
set -- --database="$MYSQL_DATABASE" "$@"
181198
fi
182199

183-
mysql --defaults-file=<( _mysql_passfile ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
200+
mysql --defaults-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
184201
}
185202

186203
# Initializes database with timezone info and root password, plus optional extra db/user
@@ -190,17 +207,16 @@ docker_setup_db() {
190207
# sed is for https://bugs.mysql.com/bug.php?id=20545
191208
mysql_tzinfo_to_sql /usr/share/zoneinfo \
192209
| sed 's/Local time zone must be set--see zic manual page/FCTY/' \
193-
| MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql
194-
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
195-
# so that it won't try to fill in a password file when it hasn't been set yet
210+
| docker_process_sql --dont-use-mysql-root-password --database=mysql
211+
# tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
196212
fi
197213
# Generate random root password
198214
if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
199215
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
200216
mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
201217
fi
202218
# Sets root password and creates root users for non-localhost hosts
203-
rootCreate=
219+
local rootCreate=
204220
# default root to listen for connections from anywhere
205221
if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
206222
# no, we don't care if read finds a terminating character in this heredoc
@@ -211,14 +227,27 @@ docker_setup_db() {
211227
EOSQL
212228
fi
213229

214-
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
215-
# so that it won't try to fill in a password file when it is just now being set
216-
MYSQL_ROOT_PASSWORD= docker_process_sql --database=mysql <<-EOSQL
230+
local passwordSet=
231+
if [ "$MYSQL_MAJOR" = '5.6' ]; then
232+
# no, we don't care if read finds a terminating character in this heredoc (see above)
233+
read -r -d '' passwordSet <<-EOSQL || true
234+
DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
235+
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
236+
EOSQL
237+
else
238+
# no, we don't care if read finds a terminating character in this heredoc (see above)
239+
read -r -d '' passwordSet <<-EOSQL || true
240+
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
241+
EOSQL
242+
fi
243+
244+
# tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is just now being set
245+
docker_process_sql --dont-use-mysql-root-password --database=mysql <<-EOSQL
217246
-- What's done in this file shouldn't be replicated
218247
-- or products like mysql-fabric won't work
219248
SET @@SESSION.SQL_LOG_BIN=0;
220249
221-
%%PASSWORDSET%%
250+
${passwordSet}
222251
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
223252
FLUSH PRIVILEGES ;
224253
${rootCreate}
@@ -248,7 +277,7 @@ _mysql_passfile() {
248277
# echo the password to the "file" the client uses
249278
# the client command will use process substitution to create a file on the fly
250279
# ie: --defaults-file=<( _mysql_passfile )
251-
if [ -n "$MYSQL_ROOT_PASSWORD" ]; then
280+
if [ '--dont-use-mysql-root-password' != "$1" ] && [ -n "$MYSQL_ROOT_PASSWORD" ]; then
252281
cat <<-EOF
253282
[client]
254283
password="${MYSQL_ROOT_PASSWORD}"
@@ -301,8 +330,8 @@ _main() {
301330
exec gosu mysql "$BASH_SOURCE" "$@"
302331
fi
303332

304-
# If this is true then there's no database, and it needs to be initialized
305-
if [ ! -d "$DATADIR/mysql" ]; then
333+
# there's no database, so it needs to be initialized
334+
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
306335
docker_verify_minimum_env
307336
docker_init_database_dir "$@"
308337

5.6/docker-entrypoint.sh

+65-31
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ file_env() {
3939
unset "$fileVar"
4040
}
4141

42+
# check to see if this file is being run or sourced from another script
43+
_is_sourced() {
44+
# https://unix.stackexchange.com/a/215279
45+
[ "${FUNCNAME[${#FUNCNAME[@]} - 1]}" == 'source' ]
46+
}
47+
4248
# usage: docker_process_init_files [file [file [...]]]
4349
# ie: docker_process_init_files /always-initdb.d/*
4450
# process initializer files, based on file extensions
@@ -78,27 +84,30 @@ mysql_get_config() {
7884

7985
# Do a temporary startup of the MySQL server, for init purposes
8086
docker_temp_server_start() {
81-
local result=0
82-
"$@" --skip-networking --socket="${SOCKET}" &
83-
if [ "$result" != "0" ];then
84-
mysql_error "Unable to start server. Status code $result."
85-
fi
86-
87-
# For 5.7+ the server is ready for use as soon as startup command unblocks
88-
if [ "${MYSQL_MAJOR}" = "5.6" ]; then
87+
if [ "${MYSQL_MAJOR}" = '5.6' ]; then
88+
"$@" --skip-networking --socket="${SOCKET}" &
8989
mysql_note "Waiting for server startup"
9090
local i
9191
for i in {30..0}; do
92-
# unset MYSQL_ROOT_PASSWORD for just docker_process_sql
92+
# only use the root password if the database has already been initializaed
9393
# 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
94+
extraArgs=()
95+
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
96+
extraArgs+=( '--dont-use-mysql-root-password' )
97+
fi
98+
if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
9599
break
96100
fi
97101
sleep 1
98102
done
99103
if [ "$i" = 0 ]; then
100104
mysql_error "Unable to start server."
101105
fi
106+
else
107+
# For 5.7+ the server is ready for use as soon as startup command unblocks
108+
if ! "$@" --daemonize --skip-networking --socket="${SOCKET}"; then
109+
mysql_error "Unable to start server."
110+
fi
102111
fi
103112
}
104113

@@ -137,7 +146,11 @@ docker_create_db_directories() {
137146
# initializes the database directory
138147
docker_init_database_dir() {
139148
mysql_note "Initializing database files"
140-
mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
149+
if [ "$MYSQL_MAJOR" = '5.6' ]; then
150+
mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
151+
else
152+
"$@" --initialize-insecure
153+
fi
141154
mysql_note "Database files initialized"
142155

143156
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
@@ -149,8 +162,10 @@ docker_init_database_dir() {
149162
}
150163

151164
# Loads various settings that are used elsewhere in the script
165+
# This should be called after mysql_check_config, but before any other functions
152166
docker_setup_env() {
153167
# Get config
168+
declare -g DATADIR SOCKET
154169
DATADIR="$(mysql_get_config 'datadir' "$@")"
155170
SOCKET="$(mysql_get_config 'socket' "$@")"
156171

@@ -160,19 +175,29 @@ docker_setup_env() {
160175
file_env 'MYSQL_USER'
161176
file_env 'MYSQL_PASSWORD'
162177
file_env 'MYSQL_ROOT_PASSWORD'
178+
179+
declare -g DATABASE_ALREADY_EXISTS
180+
if [ -d "$DATADIR/mysql" ]; then
181+
DATABASE_ALREADY_EXISTS='true'
182+
fi
163183
}
164184

165185
# Execute sql script, passed via stdin
166-
# usage: docker_process_sql [mysql-cli-args]
186+
# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
167187
# ie: docker_process_sql --database=mydb <<<'INSERT ...'
168-
# ie: docker_process_sql --database=mydb <my-file.sql
188+
# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
169189
docker_process_sql() {
190+
passfileArgs=()
191+
if [ '--dont-use-mysql-root-password' = "$1" ]; then
192+
passfileArgs+=( "$1" )
193+
shift
194+
fi
170195
# args sent in can override this db, since they will be later in the command
171196
if [ -n "$MYSQL_DATABASE" ]; then
172197
set -- --database="$MYSQL_DATABASE" "$@"
173198
fi
174199

175-
mysql --defaults-file=<( _mysql_passfile ) --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
200+
mysql --defaults-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
176201
}
177202

178203
# Initializes database with timezone info and root password, plus optional extra db/user
@@ -182,17 +207,16 @@ docker_setup_db() {
182207
# sed is for https://bugs.mysql.com/bug.php?id=20545
183208
mysql_tzinfo_to_sql /usr/share/zoneinfo \
184209
| 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
210+
| docker_process_sql --dont-use-mysql-root-password --database=mysql
211+
# tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
188212
fi
189213
# Generate random root password
190214
if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
191215
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
192216
mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
193217
fi
194218
# Sets root password and creates root users for non-localhost hosts
195-
rootCreate=
219+
local rootCreate=
196220
# default root to listen for connections from anywhere
197221
if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
198222
# no, we don't care if read finds a terminating character in this heredoc
@@ -203,15 +227,27 @@ docker_setup_db() {
203227
EOSQL
204228
fi
205229

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
230+
local passwordSet=
231+
if [ "$MYSQL_MAJOR" = '5.6' ]; then
232+
# no, we don't care if read finds a terminating character in this heredoc (see above)
233+
read -r -d '' passwordSet <<-EOSQL || true
234+
DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
235+
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
236+
EOSQL
237+
else
238+
# no, we don't care if read finds a terminating character in this heredoc (see above)
239+
read -r -d '' passwordSet <<-EOSQL || true
240+
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
241+
EOSQL
242+
fi
243+
244+
# tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is just now being set
245+
docker_process_sql --dont-use-mysql-root-password --database=mysql <<-EOSQL
209246
-- What's done in this file shouldn't be replicated
210247
-- or products like mysql-fabric won't work
211248
SET @@SESSION.SQL_LOG_BIN=0;
212249
213-
DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
214-
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}');
250+
${passwordSet}
215251
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
216252
FLUSH PRIVILEGES ;
217253
${rootCreate}
@@ -241,7 +277,7 @@ _mysql_passfile() {
241277
# echo the password to the "file" the client uses
242278
# the client command will use process substitution to create a file on the fly
243279
# ie: --defaults-file=<( _mysql_passfile )
244-
if [ -n "$MYSQL_ROOT_PASSWORD" ]; then
280+
if [ '--dont-use-mysql-root-password' != "$1" ] && [ -n "$MYSQL_ROOT_PASSWORD" ]; then
245281
cat <<-EOF
246282
[client]
247283
password="${MYSQL_ROOT_PASSWORD}"
@@ -283,9 +319,9 @@ _main() {
283319
if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
284320
mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
285321

322+
mysql_check_config "$@"
286323
# Load various environment variables
287324
docker_setup_env "$@"
288-
mysql_check_config "$@"
289325
docker_create_db_directories
290326

291327
# If container is started as root user, restart as dedicated mysql user
@@ -294,8 +330,8 @@ _main() {
294330
exec gosu mysql "$BASH_SOURCE" "$@"
295331
fi
296332

297-
# If this is true then there's no database, and it needs to be initialized
298-
if [ ! -d "$DATADIR/mysql" ]; then
333+
# there's no database, so it needs to be initialized
334+
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
299335
docker_verify_minimum_env
300336
docker_init_database_dir "$@"
301337

@@ -320,9 +356,7 @@ _main() {
320356
exec "$@"
321357
}
322358

323-
# This checks if the script has been sourced from elsewhere.
324-
# If so we don't perform any further actions
325-
# https://unix.stackexchange.com/a/215279
326-
if [ "${FUNCNAME[${#FUNCNAME[@]} - 1]}" != 'source' ]; then
359+
# If we are sourced from elsewhere, don't perform any further actions
360+
if ! _is_sourced; then
327361
_main "$@"
328362
fi

0 commit comments

Comments
 (0)