@@ -90,15 +90,17 @@ docker_get_config() {
90
90
# match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
91
91
}
92
92
93
+ # Do a temporary startup of the MySQL server, for init purposes
93
94
docker_start_server () {
94
- local socket=$1 ; shift
95
95
result=0
96
96
%%SERVERSTARTUP%%
97
97
if [ ! " $result " = " 0" ]; then
98
98
docker_error " Unable to start server. Status code $result ."
99
99
fi
100
100
}
101
101
102
+ # Wait for the temporary server to be ready for connections.
103
+ # It is only used for versions older than 5.7
102
104
docker_wait_for_server () {
103
105
local mysql=( " $@ " )
104
106
for i in {30..0}; do
@@ -112,141 +114,202 @@ docker_wait_for_server() {
112
114
fi
113
115
}
114
116
117
+ # Stop the server. When using a local socket file mysqladmin will block until
118
+ # the shutdown is complete.
115
119
docker_stop_server () {
116
- local passfile=$1
117
- local socket=$2
118
120
result=0
119
- mysqladmin --defaults-extra-file=" ${passfile } " shutdown -uroot --socket=" ${socket } " || result=$?
121
+ mysqladmin --defaults-extra-file=" ${PASSFILE } " shutdown -uroot --socket=" ${SOCKET } " || result=$?
120
122
if [ ! " $result " = " 0" ]; then
121
123
docker_error " Unable to shut down server. Status code $result ."
122
124
fi
123
125
}
126
+
127
+ # Verify that the minimally required password settings are set for new databases.
128
+ docker_verify_env () {
129
+ if [ -z " $MYSQL_ROOT_PASSWORD " -a -z " $MYSQL_ALLOW_EMPTY_PASSWORD " -a -z " $MYSQL_RANDOM_ROOT_PASSWORD " ]; then
130
+ docker_error " Database is uninitialized and password option is not specified \n\tYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD"
131
+ fi
132
+ }
133
+
134
+ # Creates and initializes the database directory
135
+ docker_init_database_dir () {
136
+ mkdir -p " $DATADIR "
137
+
138
+ docker_note " Initializing database files"
139
+ %%DATABASEINIT%%
140
+ docker_note " Database files initialized"
141
+
142
+ if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e " $DATADIR /server-key.pem" ]; then
143
+ # https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
144
+ docker_note " Initializing certificates"
145
+ mysql_ssl_rsa_setup --datadir=" $DATADIR "
146
+ docker_note " Certificates initialized"
147
+ fi
148
+ }
149
+
150
+ # Loads various settings that are used elsewhere in the script
151
+ docker_init_env () {
152
+ # Get config
153
+ DATADIR=" $( docker_get_config ' datadir' " $@ " ) "
154
+ SOCKET=" $( docker_get_config ' socket' " $@ " ) "
155
+
156
+ # We create a file to store the root password in so we don''t use it on the command line
157
+ TMPDIR=" $( mktemp -d) "
158
+ PASSFILE=" $( mktemp ${TMPDIR} /XXXXXXXXXX) "
159
+
160
+ # Initialize values that might be stored in a file
161
+ docker_file_env ' MYSQL_ROOT_HOST' ' %'
162
+ docker_file_env ' MYSQL_DATABASE'
163
+ docker_file_env ' MYSQL_USER'
164
+ docker_file_env ' MYSQL_PASSWORD'
165
+ docker_file_env ' MYSQL_ROOT_PASSWORD'
166
+ }
167
+
168
+ # Define the client command that's used in various places
169
+ docker_init_client_command () {
170
+ mysql=( mysql --defaults-file=" ${PASSFILE} " --protocol=socket -uroot -hlocalhost --socket=" ${SOCKET} " )
171
+ }
172
+
173
+ # Store root password in a file for use with the client command
174
+ docker_write_password_file () {
175
+ # Write the password to the file the client uses
176
+ if [ ! -z " $MYSQL_ROOT_PASSWORD " ]; then
177
+ cat > " ${PASSFILE} " << EOF
178
+ [client]
179
+ password="${MYSQL_ROOT_PASSWORD} "
180
+ EOF
181
+ fi
182
+ }
183
+
184
+ # Sets root password and creates root users for non-localhost hosts
185
+ docker_init_root_user () {
186
+ rootCreate=
187
+ # default root to listen for connections from anywhere
188
+ if [ ! -z " $MYSQL_ROOT_HOST " -a " $MYSQL_ROOT_HOST " != ' localhost' ]; then
189
+ # no, we don't care if read finds a terminating character in this heredoc
190
+ # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
191
+ read -r -d ' ' rootCreate << -EOSQL || true
192
+ CREATE USER 'root'@'${MYSQL_ROOT_HOST} ' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD} ' ;
193
+ GRANT ALL ON *.* TO 'root'@'${MYSQL_ROOT_HOST} ' WITH GRANT OPTION ;
194
+ EOSQL
195
+ fi
196
+
197
+ " ${mysql[@]} " << -EOSQL
198
+ -- What's done in this file shouldn't be replicated
199
+ -- or products like mysql-fabric won't work
200
+ SET @@SESSION.SQL_LOG_BIN=0;
201
+
202
+ %%PASSWORDSET%%
203
+ GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
204
+ ${rootCreate}
205
+ DROP DATABASE IF EXISTS test ;
206
+ FLUSH PRIVILEGES ;
207
+ EOSQL
208
+ }
209
+
210
+ # Creates a custom database and user if specified
211
+ docker_init_database_user () {
212
+ if [ " $MYSQL_DATABASE " ]; then
213
+ docker_note " Creating database ${MYSQL_DATABASE} "
214
+ echo " CREATE DATABASE IF NOT EXISTS \` $MYSQL_DATABASE \` ;" | " ${mysql[@]} "
215
+ mysql+=( " $MYSQL_DATABASE " )
216
+ fi
217
+
218
+ if [ " $MYSQL_USER " -a " $MYSQL_PASSWORD " ]; then
219
+ docker_note " Creating user ${MYSQL_USER} "
220
+ echo " CREATE USER '$MYSQL_USER '@'%' IDENTIFIED BY '$MYSQL_PASSWORD ' ;" | " ${mysql[@]} "
221
+
222
+ if [ " $MYSQL_DATABASE " ]; then
223
+ echo " GRANT ALL ON \` $MYSQL_DATABASE \` .* TO '$MYSQL_USER '@'%' ;" | " ${mysql[@]} "
224
+ fi
225
+
226
+ echo ' FLUSH PRIVILEGES ;' | " ${mysql[@]} "
227
+ fi
228
+ }
229
+
230
+ # Mark root user as expired so the password must be changed before anything
231
+ # else can be done (only supported for 5.6+)
232
+ docker_expire_root_user () {
233
+ if [ " ${MYSQL_MAJOR} " = " 5.5" ]; then
234
+ _warn " MySQL 5.5 does not support PASSWORD EXPIRE (required for MYSQL_ONETIME_PASSWORD)"
235
+ else
236
+ " ${mysql[@]} " << -EOSQL
237
+ ALTER USER 'root'@'%' PASSWORD EXPIRE;
238
+ EOSQL
239
+ fi
240
+ }
241
+
242
+ # Generate a random root password
243
+ docker_generate_root_password () {
244
+ export MYSQL_ROOT_PASSWORD=" $( pwgen -1 32) "
245
+ docker_note " GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD "
246
+ }
247
+
248
+ # Load timezone info into database
249
+ docker_load_tzinfo () {
250
+ # sed is for https://bugs.mysql.com/bug.php?id=20545
251
+ mysql_tzinfo_to_sql /usr/share/zoneinfo | sed ' s/Local time zone must be set--see zic manual page/FCTY/' | " ${mysql[@]} " mysql
252
+ }
253
+
254
+ docker_init_env " $@ "
255
+
124
256
# allow the container to be started with `--user`
125
257
if [ " $1 " = ' mysqld' -a -z " $wantHelp " -a " $( id -u) " = ' 0' ]; then
126
258
docker_check_config " $@ "
127
- DATADIR=" $( docker_get_config ' datadir' " $@ " ) "
128
259
mkdir -p " $DATADIR "
129
260
chown -R mysql:mysql " $DATADIR "
130
261
exec gosu mysql " $BASH_SOURCE " " $@ "
131
262
fi
132
263
264
+ docker_note " Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
265
+
133
266
if [ " $1 " = ' mysqld' -a -z " $wantHelp " ]; then
134
267
# still need to check config, container may have started with --user
135
268
docker_check_config " $@ "
136
- # Get config
137
- DATADIR=" $( docker_get_config ' datadir' " $@ " ) "
138
269
270
+ # If this is true then there's no database, and it needs to be initialized
139
271
if [ ! -d " $DATADIR /mysql" ]; then
140
- docker_file_env ' MYSQL_ROOT_PASSWORD'
141
- if [ -z " $MYSQL_ROOT_PASSWORD " -a -z " $MYSQL_ALLOW_EMPTY_PASSWORD " -a -z " $MYSQL_RANDOM_ROOT_PASSWORD " ]; then
142
- docker_error " Database is uninitialized and password option is not specified \n\tYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD"
143
- fi
144
-
145
- mkdir -p " $DATADIR "
146
-
147
- docker_note " Initializing database"
148
- %%DATABASEINIT%%
149
- docker_note " Database initialized"
150
-
151
- if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e " $DATADIR /server-key.pem" ]; then
152
- # https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
153
- docker_note " Initializing certificates"
154
- mysql_ssl_rsa_setup --datadir=" $DATADIR "
155
- docker_note " Certificates initialized"
156
- fi
157
-
158
- SOCKET=" $( docker_get_config ' socket' " $@ " ) "
159
- # We create a file to store the root password in so we don''t use it on the command line
160
- TMPDIR=" $( mktemp -d) "
161
- PASSFILE=" $( mktemp ${TMPDIR} /XXXXXXXXXX) "
272
+ docker_verify_env
273
+ docker_init_database_dir " $@ "
274
+ docker_init_client_command
162
275
163
- mysql=( mysql --defaults-file= " ${PASSFILE} " --protocol=socket -uroot -hlocalhost --socket= " ${SOCKET} " )
164
- docker_note " Starting server "
165
- docker_start_server " ${SOCKET} " " $@ "
276
+ docker_note " Starting temporary server "
277
+ docker_start_server " $@ "
278
+ # For 5.7+ the server is ready for use as soon as startup command unblocks
166
279
if [ " ${MYSQL_MAJOR} " = " 5.5" ] || [ " ${MYSQL_MAJOR} " = " 5.6" ]; then
167
280
docker_note " Waiting for server startup"
168
281
docker_wait_for_server " ${mysql[@]} "
169
282
fi
170
- docker_note " Server started."
283
+ docker_note " Temporary server started."
171
284
172
285
173
286
if [ -z " $MYSQL_INITDB_SKIP_TZINFO " ]; then
174
- # sed is for https://bugs.mysql.com/bug.php?id=20545
175
- mysql_tzinfo_to_sql /usr/share/zoneinfo | sed ' s/Local time zone must be set--see zic manual page/FCTY/' | " ${mysql[@]} " mysql
287
+ docker_load_tzinfo
176
288
fi
177
289
178
290
if [ ! -z " $MYSQL_RANDOM_ROOT_PASSWORD " ]; then
179
- export MYSQL_ROOT_PASSWORD=" $( pwgen -1 32) "
180
- docker_note " GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD "
181
- fi
182
-
183
- rootCreate=
184
- # default root to listen for connections from anywhere
185
- docker_file_env ' MYSQL_ROOT_HOST' ' %'
186
- if [ ! -z " $MYSQL_ROOT_HOST " -a " $MYSQL_ROOT_HOST " != ' localhost' ]; then
187
- # no, we don't care if read finds a terminating character in this heredoc
188
- # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
189
- read -r -d ' ' rootCreate << -EOSQL || true
190
- CREATE USER 'root'@'${MYSQL_ROOT_HOST} ' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD} ' ;
191
- GRANT ALL ON *.* TO 'root'@'${MYSQL_ROOT_HOST} ' WITH GRANT OPTION ;
192
- EOSQL
193
- fi
194
-
195
- " ${mysql[@]} " << -EOSQL
196
- -- What's done in this file shouldn't be replicated
197
- -- or products like mysql-fabric won't work
198
- SET @@SESSION.SQL_LOG_BIN=0;
199
-
200
- %%PASSWORDSET%%
201
- GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
202
- ${rootCreate}
203
- DROP DATABASE IF EXISTS test ;
204
- FLUSH PRIVILEGES ;
205
- EOSQL
206
-
207
- # Write the password to the file the client uses
208
- if [ ! -z " $MYSQL_ROOT_PASSWORD " ]; then
209
- cat > " ${PASSFILE} " << EOF
210
- [client]
211
- password="${MYSQL_ROOT_PASSWORD} "
212
- EOF
291
+ docker_generate_root_password
213
292
fi
293
+
294
+ docker_init_root_user
214
295
215
- docker_file_env ' MYSQL_DATABASE'
216
- if [ " $MYSQL_DATABASE " ]; then
217
- echo " CREATE DATABASE IF NOT EXISTS \` $MYSQL_DATABASE \` ;" | " ${mysql[@]} "
218
- mysql+=( " $MYSQL_DATABASE " )
219
- fi
296
+ docker_write_password_file
220
297
221
- docker_file_env ' MYSQL_USER'
222
- docker_file_env ' MYSQL_PASSWORD'
223
- if [ " $MYSQL_USER " -a " $MYSQL_PASSWORD " ]; then
224
- echo " CREATE USER '$MYSQL_USER '@'%' IDENTIFIED BY '$MYSQL_PASSWORD ' ;" | " ${mysql[@]} "
225
-
226
- if [ " $MYSQL_DATABASE " ]; then
227
- echo " GRANT ALL ON \` $MYSQL_DATABASE \` .* TO '$MYSQL_USER '@'%' ;" | " ${mysql[@]} "
228
- fi
229
-
230
- echo ' FLUSH PRIVILEGES ;' | " ${mysql[@]} "
231
- fi
298
+ docker_init_database_user
232
299
233
300
echo
234
301
for f in /docker-entrypoint-initdb.d/* ; do
235
302
docker_process_init_file " $f " " ${mysql[@]} "
236
303
done
237
304
238
305
if [ ! -z " $MYSQL_ONETIME_PASSWORD " ]; then
239
- if [ " ${MYSQL_MAJOR} " = " 5.5" ]; then
240
- _warn " MySQL 5.5 does not support PASSWORD EXPIRE (required for MYSQL_ONETIME_PASSWORD)"
241
- else
242
- " ${mysql[@]} " << -EOSQL
243
- ALTER USER 'root'@'%' PASSWORD EXPIRE;
244
- EOSQL
245
- fi
306
+ docker_expire_root_user
246
307
fi
247
- docker_note " Stopping server"
248
- docker_stop_server " ${PASSFILE} " " ${SOCKET} "
249
- docker_note " Server stopped"
308
+ docker_note " Stopping temporary server"
309
+ docker_stop_server
310
+ docker_note " Temporary server stopped"
311
+
312
+ # Remove the password file now that initialization is complete
250
313
rm -f " ${PASSFILE} "
251
314
unset PASSFILE
252
315
echo
0 commit comments