-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker-entrypoint.sh
655 lines (519 loc) · 13.3 KB
/
docker-entrypoint.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
#!/bin/bash
set -eo pipefail
shopt -s nullglob
DF_DATA_DIR=/df-data
DF_TMP_DIR=/tmp
APP_DIR=/app
# logging functions
log() {
local type="$1"; shift
# accept argument string or stdin
local text="$*"; if [ "$#" -eq 0 ]; then text="$(cat)"; fi
local dt; dt="$(date --rfc-3339=seconds)"
printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
}
log_note() {
log Note "$@"
}
log_warn() {
log Warn "$@" >&2
}
log_error() {
log ERROR "$@" >&2
exit 1
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
log_error "Both $var and $fileVar are set (but are exclusive)"
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
# check to see if this file is being run or sourced from another script
_is_sourced() {
# https://unix.stackexchange.com/a/215279
[ "${#FUNCNAME[@]}" -ge 2 ] \
&& [ "${FUNCNAME[0]}" = '_is_sourced' ] \
&& [ "${FUNCNAME[1]}" = 'source' ]
}
# Loads various settings that are used elsewhere in the script
# This should be called after mysql_check_config, but before any other functions
docker_setup_env() {
# Initialize values that might be stored in a file
file_env 'MYSQL_IP'
file_env 'MYSQL_PORT' '3306'
file_env 'MYSQL_USER'
file_env 'MYSQL_PASSWORD'
file_env 'MY_IP'
declare -g MYSQL_SECURITY_PASSWORD
MYSQL_SECURITY_PASSWORD="$(df-crypto enc ${MYSQL_PASSWORD})"
}
# Verify that the minimally required password settings are set for df-server.
docker_verify_minimum_env() {
if [ -z "$MYSQL_IP" -o -z "$MYSQL_PORT" ]; then
log_error <<-'EOF'
df-server is need to connect to MySQL and MYSQL_IP or MYSQL_PORT are not set
You need to specify one of the following as an environment variable:
- MYSQL_IP
- MYSQL_PORT
EOF
fi
if [ -z "$MYSQL_USER" -o -z "$MYSQL_PASSWORD" ]; then
log_error <<-'EOF'
df-server is need to connect to MySQL and MYSQL_USER or MYSQL_PASSWORD are not set
You need to specify one of the following as an environment variable:
- MYSQL_USER
- MYSQL_PASSWORD
EOF
fi
# check password length <= 20
if [ ${#MYSQL_PASSWORD} -gt 20 ]; then
log_error <<-'EOF'
MYSQL_PASSWORD is too long
EOF
fi
if [ -z "$MY_IP" ]; then
log_error <<-'EOF'
df-server is need to know MY_IP and MY_IP is not set
You need to specify one of the following as an environment variable:
- MY_IP
EOF
fi
}
docker_verify_minimum_df_data() {
if [ ! -f ${DF_DATA_DIR}/publickey.pem ]; then
log_error <<-'EOF'
You need to create a publickey.pem file.
Example:
openssl genrsa -out privatekey.pem 2048
openssl rsa -in privatekey.pem -outform PEM -pubout -out publickey.pem
EOF
fi
if [ ! -f ${DF_DATA_DIR}/Script.pvf ]; then
log_error "not found ${DF_DATA_DIR}/Script.pvf"
fi
}
docker_wait() {
if [ -z $1 ]; then
return
fi
while kill -0 $1 2> /dev/null; do
sleep 1
done
}
escape() {
echo "$1" | sed -e 's/[]\/$*.^[]/\\&/g'
}
docker_env_replace() {
sed -i \
-e "s/{MYSQL_IP}/$(escape ${MYSQL_IP})/g" \
-e "s/{MYSQL_PORT}/$(escape ${MYSQL_PORT})/g" \
-e "s/{MYSQL_USER}/$(escape ${MYSQL_USER})/g" \
-e "s/{MYSQL_PASSWORD}/$(escape ${MYSQL_PASSWORD})/g" \
-e "s/{MYSQL_SECURITY_PASSWORD}/$(escape ${MYSQL_SECURITY_PASSWORD})/g" \
-e "s/{MY_IP}/$(escape ${MY_IP})/g" \
"$@"
}
run_stun() {
cd ${APP_DIR}/stun
rm -rf ${DF_TMP_DIR}/stun-log
rm -rf ${DF_TMP_DIR}/stun-pid
mkdir -p ${DF_TMP_DIR}/stun-log
mkdir -p ${DF_TMP_DIR}/stun-pid
log_note "start stun"
./df_stun_r start
}
stop_stun() {
cd ${APP_DIR}/stun
log_note "stop stun"
kill $(cat pid/udp_server.pid)
}
run_monitor() {
cd ${APP_DIR}/monitor
rm -rf ${DF_TMP_DIR}/monitor-log
rm -rf ${DF_TMP_DIR}/monitor-pid
mkdir -p ${DF_TMP_DIR}/monitor-log
mkdir -p ${DF_TMP_DIR}/monitor-pid
log_note "start monitor"
./df_monitor_r mnt_siroco start
}
stop_monitor() {
cd ${APP_DIR}/monitor
log_note "stop monitor"
kill $(cat pid/mnt_siroco.pid)
}
run_manager() {
cd ${APP_DIR}/manager
rm -rf ${DF_TMP_DIR}/manager-log
rm -rf ${DF_TMP_DIR}/manager-pid
mkdir -p ${DF_TMP_DIR}/manager-log
mkdir -p ${DF_TMP_DIR}/manager-pid
log_note "start manager"
./df_manager_r manager start
}
stop_manager() {
cd ${APP_DIR}/manager
log_note "stop manager"
kill $(cat pid/manager.pid)
}
run_relay() {
cd ${APP_DIR}/relay
rm -rf ${DF_TMP_DIR}/relay-log
rm -rf ${DF_TMP_DIR}/relay-pid
mkdir -p ${DF_TMP_DIR}/relay-log
mkdir -p ${DF_TMP_DIR}/relay-pid
log_note "start relay"
./df_relay_r relay_200 start
}
stop_relay() {
cd ${APP_DIR}/relay
log_note "stop relay"
kill $(cat pid/relay_200.pid)
}
run_bridge() {
cd ${APP_DIR}/bridge
log_note <<-'EOF'
This service can't change the MYSQL port.
The MYSQL port must be 3306.
EOF
rm -rf ${DF_TMP_DIR}/bridge-log
rm -rf ${DF_TMP_DIR}/bridge-pid
rm -rf ${DF_TMP_DIR}/bridge-cfg
mkdir -p ${DF_TMP_DIR}/bridge-log
mkdir -p ${DF_TMP_DIR}/bridge-pid
cp -rf _cfg ${DF_TMP_DIR}/bridge-cfg
docker_env_replace cfg/bridge.cfg
log_note "start bridge"
./df_bridge_r bridge start
}
stop_bridge() {
cd ${APP_DIR}/bridge
log_note "stop bridge"
kill $(cat pid/bridge.pid)
}
run_channel() {
cd ${APP_DIR}/channel
rm -rf ${DF_TMP_DIR}/channel-log
rm -rf ${DF_TMP_DIR}/channel-pid
rm -rf ${DF_TMP_DIR}/channel-cfg
mkdir -p ${DF_TMP_DIR}/channel-log
mkdir -p ${DF_TMP_DIR}/channel-pid
cp -rf _cfg ${DF_TMP_DIR}/channel-cfg
docker_env_replace cfg/channel.cfg
log_note "start channel"
./df_channel_r channel start
}
stop_channel() {
cd ${APP_DIR}/channel
log_note "stop channel"
kill $(cat pid/channel.pid)
}
run_dbmw_guild() {
cd ${APP_DIR}/dbmw_guild
rm -rf ${DF_TMP_DIR}/dbmw_guild-log
rm -rf ${DF_TMP_DIR}/dbmw_guild-pid
rm -rf ${DF_TMP_DIR}/dbmw_guild-cfg
mkdir -p ${DF_TMP_DIR}/dbmw_guild-log
mkdir -p ${DF_TMP_DIR}/dbmw_guild-pid
cp -rf _cfg ${DF_TMP_DIR}/dbmw_guild-cfg
docker_env_replace cfg/dbmw_gld_siroco.cfg
log_note "start dbmw_guild"
./df_dbmw_r dbmw_gld_siroco start
}
stop_dbmw_guild() {
cd ${APP_DIR}/dbmw_guild
log_note "stop dbmw_guild"
kill $(cat pid/dbmw_gld_siroco.pid)
}
run_dbmw_mnt() {
cd ${APP_DIR}/dbmw_mnt
rm -rf ${DF_TMP_DIR}/dbmw_mnt-log
rm -rf ${DF_TMP_DIR}/dbmw_mnt-pid
rm -rf ${DF_TMP_DIR}/dbmw_mnt-cfg
mkdir -p ${DF_TMP_DIR}/dbmw_mnt-log
mkdir -p ${DF_TMP_DIR}/dbmw_mnt-pid
cp -rf _cfg ${DF_TMP_DIR}/dbmw_mnt-cfg
docker_env_replace cfg/dbmw_mnt_siroco.cfg
log_note "start dbmw_mnt"
./df_dbmw_r dbmw_mnt_siroco start
}
stop_dbmw_mnt() {
cd ${APP_DIR}/dbmw_mnt
log_note "stop dbmw_mnt"
kill $(cat pid/dbmw_mnt_siroco.pid)
}
run_dbmw_stat() {
cd ${APP_DIR}/dbmw_stat
rm -rf ${DF_TMP_DIR}/dbmw_stat-log
rm -rf ${DF_TMP_DIR}/dbmw_stat-pid
rm -rf ${DF_TMP_DIR}/dbmw_stat-cfg
mkdir -p ${DF_TMP_DIR}/dbmw_stat-log
mkdir -p ${DF_TMP_DIR}/dbmw_stat-pid
cp -rf _cfg ${DF_TMP_DIR}/dbmw_stat-cfg
docker_env_replace cfg/dbmw_stat_siroco.cfg
log_note "start dbmw_stat"
./df_dbmw_r dbmw_stat_siroco start
}
stop_dbmw_stat() {
cd ${APP_DIR}/dbmw_stat
log_note "stop dbmw_stat"
kill $(cat pid/dbmw_stat_siroco.pid)
}
run_auction() {
cd ${APP_DIR}/auction
log_note <<-'EOF'
This service have to connect to MySQL.
EOF
rm -rf ${DF_TMP_DIR}/auction-log
rm -rf ${DF_TMP_DIR}/auction-pid
rm -rf ${DF_TMP_DIR}/auction-cfg
mkdir -p ${DF_TMP_DIR}/auction-log
mkdir -p ${DF_TMP_DIR}/auction-pid
cp -rf _cfg ${DF_TMP_DIR}/auction-cfg
docker_env_replace cfg/auction_siroco.cfg
log_note "start auction"
./df_auction_r ./cfg/auction_siroco.cfg start df_auction_r
}
stop_auction() {
cd ${APP_DIR}/auction
log_note "stop auction"
kill $(cat pid/auction_siroco.pid)
}
run_point() {
cd ${APP_DIR}/point
log_note <<-'EOF'
This service have to connect to MySQL.
EOF
rm -rf ${DF_TMP_DIR}/point-log
rm -rf ${DF_TMP_DIR}/point-pid
rm -rf ${DF_TMP_DIR}/point-cfg
mkdir -p ${DF_TMP_DIR}/point-log
mkdir -p ${DF_TMP_DIR}/point-pid
cp -rf _cfg ${DF_TMP_DIR}/point-cfg
docker_env_replace cfg/point_siroco.cfg
log_note "start point"
./df_point_r ./cfg/point_siroco.cfg start df_point_r
}
stop_point() {
cd ${APP_DIR}/point
log_note "stop point"
kill $(cat pid/point_siroco.pid)
}
run_guild() {
cd ${APP_DIR}/guild
rm -rf ${DF_TMP_DIR}/guild-log
rm -rf ${DF_TMP_DIR}/guild-pid
mkdir -p ${DF_TMP_DIR}/guild-log
mkdir -p ${DF_TMP_DIR}/guild-pid
log_note "start guild"
./df_guild_r gld_siroco start
}
stop_guild() {
cd ${APP_DIR}/guild
log_note "stop guild"
kill $(cat pid/gld_siroco.pid)
}
run_statics() {
cd ${APP_DIR}/statics
rm -rf ${DF_TMP_DIR}/statics-log
rm -rf ${DF_TMP_DIR}/statics-pid
mkdir -p ${DF_TMP_DIR}/statics-log
mkdir -p ${DF_TMP_DIR}/statics-pid
log_note "start statics"
./df_statics_r stat_siroco start
}
stop_statics() {
cd ${APP_DIR}/statics
log_note "stop statics"
kill $(cat pid/stat_siroco.pid)
}
run_coserver() {
cd ${APP_DIR}/coserver
rm -rf ${DF_TMP_DIR}/coserver-log
rm -rf ${DF_TMP_DIR}/coserver-pid
mkdir -p ${DF_TMP_DIR}/coserver-log
mkdir -p ${DF_TMP_DIR}/coserver-pid
log_note "start coserver"
nice -n 19 ./df_coserver_r coserver start
}
stop_coserver() {
cd ${APP_DIR}/coserver
log_note "stop coserver"
kill $(cat pid/coserver.pid)
}
run_community() {
cd ${APP_DIR}/community
rm -rf ${DF_TMP_DIR}/community-log
rm -rf ${DF_TMP_DIR}/community-pid
mkdir -p ${DF_TMP_DIR}/community-log
mkdir -p ${DF_TMP_DIR}/community-pid
log_note "start community"
./df_community_r community start
}
stop_community() {
cd ${APP_DIR}/community
log_note "stop community"
kill $(cat pid/community.pid)
}
# secsvr/gunnersvr
run_secsvr_gunnersvr() {
rm -rf ${DF_TMP_DIR}/secsvr-gunnersvr
mkdir -p ${DF_TMP_DIR}/secsvr-gunnersvr
cd ${DF_TMP_DIR}/secsvr-gunnersvr
ln -sf ${APP_DIR}/secsvr/gunnersvr/cfg cfg
log_note "start secsvr/gunnersvr"
PRELOAD="/usr/local/lib/libdeslash_shm.so ${LD_PRELOAD}"
LD_PRELOAD=${PRELOAD} ${APP_DIR}/secsvr/gunnersvr/gunnersvr -t30 -i1 &
}
stop_secsvr_gunnersvr() {
cd ${DF_TMP_DIR}/secsvr-gunnersvr
log_note "stop secsvr/gunnersvr"
kill $(cat gunnersvr.pid)
}
# secsvr/zergsvr
run_secsvr_zergsvr() {
rm -rf ${DF_TMP_DIR}/secsvr-zergsvr
mkdir -p ${DF_TMP_DIR}/secsvr-zergsvr
cd ${DF_TMP_DIR}/secsvr-zergsvr
ln -sf ${APP_DIR}/secsvr/zergsvr/cfg cfg
log_note "start secsvr/zergsvr"
PRELOAD="/usr/local/lib/libdeslash_shm.so ${LD_PRELOAD}"
LD_PRELOAD=${PRELOAD} ${APP_DIR}/secsvr/zergsvr/zergsvr -t30 -i1 &
}
# secsvr/secagent
run_secsvr_secagent() {
rm -rf ${DF_TMP_DIR}/secsvr-secagent
mkdir -p ${DF_TMP_DIR}/secsvr-secagent
cd ${DF_TMP_DIR}/secsvr-secagent
ln -sf ${APP_DIR}/secsvr/zergsvr/cfg cfg
log_note "start secsvr/secagent"
PRELOAD="/usr/local/lib/libdeslash_shm.so ${LD_PRELOAD}"
LD_PRELOAD=${PRELOAD} ${APP_DIR}/secsvr/zergsvr/secagent &
}
stop_secsvr_secagent() {
cd ${DF_TMP_DIR}/secsvr-secagent
log_note "stop secsvr/secagent"
kill $(cat secagent.pid)
}
run_game() {
cd ${APP_DIR}/game
rm -rf ${DF_TMP_DIR}/game-log
rm -rf ${DF_TMP_DIR}/game-pid
rm -rf ${DF_TMP_DIR}/game-history
mkdir -p ${DF_TMP_DIR}/game-log
mkdir -p ${DF_TMP_DIR}/game-pid
mkdir -p ${DF_TMP_DIR}/game-history
if [ $# -eq 0 ]; then
log_error "You need to specify at least one channel."
fi
if [ ! -d ${DF_TMP_DIR}/game-cfg ]; then
log_note "copy game-cfg"
cp -rf _cfg ${DF_TMP_DIR}/game-cfg
docker_env_replace $(find ${DF_TMP_DIR}/game-cfg -type f -name "*.cfg")
fi
for c in "$@"; do
if [ ! -f ${DF_TMP_DIR}/game-cfg/$c.cfg ]; then
log_error "not found ${DF_TMP_DIR}/game-cfg/$c.cfg"
fi
done
LIBRARY_PATH=${APP_DIR}/game:/usr/local/lib:${LD_LIBRARY_PATH}
PRELOAD="$(pwd)/libfix-antisvr.so /usr/local/lib/libdeslash_shm.so ${LD_PRELOAD}"
for c in "$@"; do
log_note "start game $c"
LD_LIBRARY_PATH=${LIBRARY_PATH} \
LD_PRELOAD=${PRELOAD} ./df_game_r $c start
done
}
stop_game() {
cd ${APP_DIR}/game
LIBRARY_PATH=${APP_DIR}/game:/usr/local/lib:${LD_LIBRARY_PATH}
for c in "$@"; do
log_note "stop game $c"
kill -9 $(cat pid/$c.pid)
done
}
run() {
if [ $# -eq 0 ]; then
log_error "You need to specify at least one channel."
fi
run_stun
run_monitor
run_manager
run_relay
run_bridge
run_channel
run_dbmw_guild
run_dbmw_mnt
run_dbmw_stat
run_auction
run_point
run_guild
run_statics
run_coserver
run_community
run_secsvr_gunnersvr
run_secsvr_secagent
run_secsvr_zergsvr
run_game "$@"
stop() {
stop_secsvr_secagent
stop_secsvr_gunnersvr
stop_coserver
stop_community
stop_point
stop_guild
stop_statics
stop_dbmw_mnt
stop_dbmw_stat
stop_dbmw_guild
stop_bridge
stop_relay
stop_manager
stop_monitor
stop_stun
stop_game "$@"
}
trap '' SIGINT
trap "stop $@" SIGTERM
sleep 10
docker_wait $(cat ${DF_TMP_DIR}/game-pid/$1.pid)
log_note "done"
}
help() {
echo <<-'EOF'
Example:
run siroco11
run siroco11 siroco12 ...
EOF
}
_main() {
if [ $1 = "help" ]; then
help
exit 0
elif [ $1 = "run" ]; then
docker_setup_env
docker_verify_minimum_env
docker_verify_minimum_df_data
shift
run "$@"
exit 0
fi
exec "$@"
}
# If we are sourced from elsewhere, don't perform any further actions
if ! _is_sourced; then
_main "$@"
fi