@@ -39,6 +39,12 @@ file_env() {
39
39
unset " $fileVar "
40
40
}
41
41
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
+
42
48
# usage: docker_process_init_files [file [file [...]]]
43
49
# ie: docker_process_init_files /always-initdb.d/*
44
50
# process initializer files, based on file extensions
@@ -78,27 +84,30 @@ mysql_get_config() {
78
84
79
85
# Do a temporary startup of the MySQL server, for init purposes
80
86
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} " &
89
89
mysql_note " Waiting for server startup"
90
90
local i
91
91
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
93
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
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
95
99
break
96
100
fi
97
101
sleep 1
98
102
done
99
103
if [ " $i " = 0 ]; then
100
104
mysql_error " Unable to start server."
101
105
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
102
111
fi
103
112
}
104
113
@@ -137,7 +146,11 @@ docker_create_db_directories() {
137
146
# initializes the database directory
138
147
docker_init_database_dir () {
139
148
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
141
154
mysql_note " Database files initialized"
142
155
143
156
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e " $DATADIR /server-key.pem" ]; then
@@ -149,8 +162,10 @@ docker_init_database_dir() {
149
162
}
150
163
151
164
# Loads various settings that are used elsewhere in the script
165
+ # This should be called after mysql_check_config, but before any other functions
152
166
docker_setup_env () {
153
167
# Get config
168
+ declare -g DATADIR SOCKET
154
169
DATADIR=" $( mysql_get_config ' datadir' " $@ " ) "
155
170
SOCKET=" $( mysql_get_config ' socket' " $@ " ) "
156
171
@@ -160,19 +175,29 @@ docker_setup_env() {
160
175
file_env ' MYSQL_USER'
161
176
file_env ' MYSQL_PASSWORD'
162
177
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
163
183
}
164
184
165
185
# 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]
167
187
# 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
169
189
docker_process_sql () {
190
+ passfileArgs=()
191
+ if [ ' --dont-use-mysql-root-password' = " $1 " ]; then
192
+ passfileArgs+=( " $1 " )
193
+ shift
194
+ fi
170
195
# args sent in can override this db, since they will be later in the command
171
196
if [ -n " $MYSQL_DATABASE " ]; then
172
197
set -- --database=" $MYSQL_DATABASE " " $@ "
173
198
fi
174
199
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} " " $@ "
176
201
}
177
202
178
203
# Initializes database with timezone info and root password, plus optional extra db/user
@@ -182,17 +207,16 @@ docker_setup_db() {
182
207
# sed is for https://bugs.mysql.com/bug.php?id=20545
183
208
mysql_tzinfo_to_sql /usr/share/zoneinfo \
184
209
| 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
188
212
fi
189
213
# Generate random root password
190
214
if [ -n " $MYSQL_RANDOM_ROOT_PASSWORD " ]; then
191
215
export MYSQL_ROOT_PASSWORD=" $( pwgen -1 32) "
192
216
mysql_note " GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD "
193
217
fi
194
218
# Sets root password and creates root users for non-localhost hosts
195
- rootCreate=
219
+ local rootCreate=
196
220
# default root to listen for connections from anywhere
197
221
if [ -n " $MYSQL_ROOT_HOST " ] && [ " $MYSQL_ROOT_HOST " != ' localhost' ]; then
198
222
# no, we don't care if read finds a terminating character in this heredoc
@@ -203,15 +227,27 @@ docker_setup_db() {
203
227
EOSQL
204
228
fi
205
229
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
209
246
-- What's done in this file shouldn't be replicated
210
247
-- or products like mysql-fabric won't work
211
248
SET @@SESSION.SQL_LOG_BIN=0;
212
249
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}
215
251
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
216
252
FLUSH PRIVILEGES ;
217
253
${rootCreate}
@@ -241,7 +277,7 @@ _mysql_passfile() {
241
277
# echo the password to the "file" the client uses
242
278
# the client command will use process substitution to create a file on the fly
243
279
# 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
245
281
cat << -EOF
246
282
[client]
247
283
password="${MYSQL_ROOT_PASSWORD} "
@@ -283,9 +319,9 @@ _main() {
283
319
if [ " $1 " = ' mysqld' ] && ! _mysql_want_help " $@ " ; then
284
320
mysql_note " Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
285
321
322
+ mysql_check_config " $@ "
286
323
# Load various environment variables
287
324
docker_setup_env " $@ "
288
- mysql_check_config " $@ "
289
325
docker_create_db_directories
290
326
291
327
# If container is started as root user, restart as dedicated mysql user
@@ -294,8 +330,8 @@ _main() {
294
330
exec gosu mysql " $BASH_SOURCE " " $@ "
295
331
fi
296
332
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
299
335
docker_verify_minimum_env
300
336
docker_init_database_dir " $@ "
301
337
@@ -320,9 +356,7 @@ _main() {
320
356
exec " $@ "
321
357
}
322
358
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
327
361
_main " $@ "
328
362
fi
0 commit comments