Update latest jemalloc to 5.1.0
[discourse_docker.git] / launcher
CommitLineData
ace450bd 1#!/bin/bash
7e738616 2
5cb39519 3usage () {
c2d3ee4a 4 echo "Usage: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]"
5cb39519
JA
5 echo "Commands:"
6 echo " start: Start/initialize a container"
7 echo " stop: Stop a running container"
8 echo " restart: Restart a container"
9 echo " destroy: Stop and remove a container"
4a5acf8c 10 echo " enter: Open a shell to run commands inside the container"
c2d3ee4a 11 echo " logs: View the Docker logs for a container"
5cb39519
JA
12 echo " bootstrap: Bootstrap a container for the config based on a template"
13 echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)"
14 echo " cleanup: Remove all containers that have stopped for > 24 hours"
15 echo
16 echo "Options:"
1f656469 17 echo " --skip-prereqs Don't check launcher prerequisites"
1f656469 18 echo " --docker-args Extra arguments to pass when running docker"
cad2919f 19 echo " --skip-mac-address Don't assign a mac address"
5cb39519
JA
20 exit 1
21}
22
7e738616
S
23command=$1
24config=$2
65573a0e 25user_args=""
87c4f221 26
1f656469 27while [ ${#} -gt 0 ]; do
65573a0e 28 case "${1}" in
19e3a6c0
S
29 --debug)
30 DEBUG="1"
31 ;;
1f656469 32 --skip-prereqs)
4f36bb43 33 SKIP_PREREQS="1"
1f656469 34 ;;
cad2919f
GXT
35 --skip-mac-address)
36 SKIP_MAC_ADDRESS="1"
37 ;;
1f656469
GXT
38 --docker-args)
39 user_args="$2"
40 shift
41 ;;
1f656469
GXT
42 esac
43
44 shift 1
45done
55d17203 46
87756d6d
EH
47# Docker doesn't like uppercase characters, spaces or special characters, catch it now before we build everything out and then find out
48re='[A-Z/ !@#$%^&*()+~`=]'
49if [[ $config =~ $re ]];
50 then
8877f99e 51 echo
87756d6d
EH
52 echo "ERROR: Config name must not contain upper case characters, spaces or special characters. Correct config name and rerun $0."
53 echo
54 exit 1
55fi
56
7936ebaa 57cd "$(dirname "$0")"
55d17203 58
0998a7c8 59docker_min_version='17.03.1'
ddf8c54c 60docker_rec_version='17.06.2'
6828238a
JP
61git_min_version='1.8.0'
62git_rec_version='1.8.0'
60668406 63
8dea575c 64config_file=containers/"$config".yml
5201a40c 65cidbootstrap=cids/"$config"_bootstrap.cid
5efded6a 66local_discourse=local_discourse
8194e684 67image=discourse/base:2.0.20180404
4807b1b8 68docker_path=`which docker.io || which docker`
6828238a 69git_path=`which git`
8877f99e 70
e0fd1f5b
TB
71if [ "${SUPERVISED}" = "true" ]; then
72 restart_policy="--restart=no"
73 attach_on_start="-a"
74 attach_on_run="-a stdout -a stderr"
75else
76 attach_on_run="-d"
77fi
78
f2a3edee
AY
79if [ -n "$DOCKER_HOST" ]; then
80 docker_ip=`sed -e 's/^tcp:\/\/\(.*\):.*$/\1/' <<< "$DOCKER_HOST"`
81elif [ -x "$(which ip 2>/dev/null)" ]; then
813fef38 82 docker_ip=`ip addr show docker0 | \
03bb0735
LG
83 grep 'inet ' | \
84 awk '{ split($2,a,"/"); print a[1] }';`
85else
813fef38 86 docker_ip=`ifconfig | \
03bb0735
LG
87 grep -B1 "inet addr" | \
88 awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
89 grep docker0 | \
90 awk -F: '{ print $3 }';`
91fi
80c11be3 92
7a96c86d 93# From https://stackoverflow.com/a/44660519/702738
60668406 94compare_version() {
7a96c86d
RSS
95 if [[ $1 == $2 ]]; then
96 return 1
97 fi
98 local IFS=.
99 local i a=(${1%%[^0-9.]*}) b=(${2%%[^0-9.]*})
100 local arem=${1#${1%%[^0-9.]*}} brem=${2#${2%%[^0-9.]*}}
101 for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
102 if ((10#${a[i]:-0} < 10#${b[i]:-0})); then
60668406 103 return 1
7a96c86d
RSS
104 elif ((10#${a[i]:-0} > 10#${b[i]:-0})); then
105 return 0
60668406
DP
106 fi
107 done
7a96c86d
RSS
108 if [ "$arem" '<' "$brem" ]; then
109 return 1
110 elif [ "$arem" '>' "$brem" ]; then
111 return 0
112 fi
113 return 1
60668406
DP
114}
115
665468eb
JA
116
117install_docker() {
c2d3ee4a 118 echo "Docker is not installed, you will need to install Docker in order to run Launcher"
bf6d49b5 119 echo "See https://docs.docker.com/installation/"
665468eb
JA
120 exit 1
121}
122
87c4f221 123check_prereqs() {
794e44d5
GXT
124
125 if [ -z $docker_path ]; then
665468eb
JA
126 install_docker
127 fi
a3e18d95 128
e741295a 129 # 1. docker daemon running?
30835a52
S
130 # we send stderr to /dev/null cause we don't care about warnings,
131 # it usually complains about swap which does not matter
132 test=`$docker_path info 2> /dev/null`
e741295a
MB
133 if [[ $? -ne 0 ]] ; then
134 echo "Cannot connect to the docker daemon - verify it is running and you have access"
135 exit 1
136 fi
137
90287f8e 138 # 2. running an approved storage driver?
7644adb7 139 if ! $docker_path info 2> /dev/null | egrep -q '^Storage Driver: (aufs|btrfs|zfs|overlay|overlay2)$'; then
90287f8e 140 echo "Your Docker installation is not using a supported storage driver. If we were to proceed you may have a broken install."
7644adb7 141 echo "aufs is the recommended storage driver, although zfs/btrfs/overlay and overlay2 may work as well."
90287f8e
MP
142 echo "Other storage drivers are known to be problematic."
143 echo "You can tell what filesystem you are using by running \"docker info\" and looking at the 'Storage Driver' line."
5dfdf9a3 144 echo
90287f8e
MP
145 echo "If you wish to continue anyway using your existing unsupported storage driver,"
146 echo "read the source code of launcher and figure out how to bypass this check."
48f22d14 147 exit 1
a3e18d95
S
148 fi
149
60668406
DP
150 # 3. running recommended docker version
151 test=($($docker_path --version)) # Get docker version string
152 test=${test[2]//,/} # Get version alone and strip comma if exists
a3e18d95 153
87c4f221 154 # At least minimum docker version
cf00fce0 155 if compare_version "${docker_min_version}" "${test}"; then
60668406 156 echo "ERROR: Docker version ${test} not supported, please upgrade to at least ${docker_min_version}, or recommended ${docker_rec_version}"
a3e18d95
S
157 exit 1
158 fi
159
87c4f221 160 # Recommend newer docker version
60668406
DP
161 if compare_version "${docker_rec_version}" "${test}"; then
162 echo "WARNING: Docker version ${test} deprecated, recommend upgrade to ${docker_rec_version} or newer."
163 fi
164
405948ee
S
165 # 4. discourse docker image is downloaded
166 test=`$docker_path images | awk '{print $1 ":" $2 }' | grep "$image"`
167
168 if [ -z "$test" ]; then
169 echo
170 echo "WARNING: We are about to start downloading the Discourse base image"
171 echo "This process may take anywhere between a few minutes to an hour, depending on your network speed"
172 echo
173 echo "Please be patient"
174 echo
405948ee 175 fi
405948ee 176
6828238a
JP
177 # 5. running recommended git version
178 test=($($git_path --version)) # Get git version string
179 test=${test[2]//,/} # Get version alone and strip comma if exists
180
181 # At least minimum version
182 if compare_version "${git_min_version}" "${test}"; then
183 echo "ERROR: Git version ${test} not supported, please upgrade to at least ${git_min_version}, or recommended ${git_rec_version}"
184 exit 1
185 fi
186
187 # Recommend best version
188 if compare_version "${git_rec_version}" "${test}"; then
189 echo "WARNING: Git version ${test} deprecated, recommend upgrade to ${git_rec_version} or newer."
190 fi
191
192 # 6. able to attach stderr / out / tty
e02c1511 193 test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working`
a3e18d95
S
194 if [[ "$test" =~ "working" ]] ; then : ; else
195 echo "Your Docker installation is not working correctly"
196 echo
197 echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
198 exit 1
199 fi
4770834b 200
49b2fcc4 201 # 7. enough space for the bootstrap on docker folder
8cdc533d
RSS
202 folder=`$docker_path info --format '{{.DockerRootDir}}'`
203 safe_folder=${folder:-/var/lib/docker}
49b2fcc4
RSS
204 test=$(($(stat -f --format="%a*%S" $safe_folder)/1024**3 < 5))
205 if [[ $test -ne 0 ]] ; then
da095c30
RSS
206 echo "You have less than 5GB of free space on the disk where $safe_folder is located. You will need more space to continue"
207 df -h $safe_folder
49b2fcc4
RSS
208 echo
209 read -p "Would you like to attempt to recover space by cleaning docker images and containers in the system?(y/N)" -n 1 -r
210 echo
211 if [[ $REPLY =~ ^[Yy]$ ]]
212 then
213 docker system prune
214 echo "If the cleanup was successful, you may try again now"
215 fi
216 exit 1
217 fi
6e784be6
MP
218}
219
6828238a 220
cf3dd6f2 221if [ -z "$SKIP_PREREQS" ] && [ "$command" != "cleanup" ]; then
87c4f221 222 check_prereqs
55d17203 223fi
a3e18d95 224
60f9f04c
S
225host_run() {
226 read -r -d '' env_ruby << 'RUBY'
227 require 'yaml'
228
229 input = STDIN.readlines.join
230 yaml = YAML.load(input)
231
232 if host_run = yaml['host_run']
233 params = yaml['params'] || {}
234 host_run.each do |run|
235 params.each do |k,v|
236 run = run.gsub("$#{k}", v)
237 end
238 STDOUT.write "#{run}--SEP--"
239 end
240 end
241RUBY
242
e02c1511 243 host_run=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e "$env_ruby"`
60f9f04c
S
244
245 while [ "$host_run" ] ; do
246 iter=${host_run%%--SEP--*}
247 echo
248 echo "Host run: $iter"
249 $iter || exit 1
250 echo
251 host_run="${host_run#*--SEP--}"
252 done
253}
254
255
d90671f3 256set_volumes() {
e02c1511 257 volumes=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
02d9a654 258 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
d90671f3
SS
259}
260
41daa523 261set_links() {
e02c1511 262 links=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
41daa523 263 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['links'].map{|l| '--link ' << l['link']['name'] << ':' << l['link']['alias'] << ' '}.join"`
264}
265
06310c73
GXT
266find_templates() {
267 local templates=`cat $1 | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
7f77c274
SS
268 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
269
06310c73
GXT
270 local arrTemplates=${templates// / }
271
2ec550f7 272 if [ ! -z "$templates" ]; then
06310c73
GXT
273 for template in "${arrTemplates[@]}"
274 do
275 local nested_templates=$(find_templates $template)
276
277 if [ ! -z "$nested_templates" ]; then
278 templates="$templates $nested_templates"
279 fi
280 done
281
282 echo $templates
283 else
284 echo ""
285 fi
286}
287
288set_template_info() {
289 templates=$(find_templates $config_file)
290
7f77c274
SS
291 arrTemplates=(${templates// / })
292 config_data=$(cat $config_file)
293
294 input="hack: true"
295
7f77c274
SS
296 for template in "${arrTemplates[@]}"
297 do
298 [ ! -z $template ] && {
299 input="$input _FILE_SEPERATOR_ $(cat $template)"
300 }
301 done
302
303 # we always want our config file last so it takes priority
304 input="$input _FILE_SEPERATOR_ $config_data"
305
306 read -r -d '' env_ruby << 'RUBY'
307 require 'yaml'
308
309 input=STDIN.readlines.join
093e6628 310 # default to UTF-8 for the dbs sake
3cb3d9c4 311 env = {'LANG' => 'en_US.UTF-8'}
7f77c274
SS
312 input.split('_FILE_SEPERATOR_').each do |yml|
313 yml.strip!
314 begin
315 env.merge!(YAML.load(yml)['env'] || {})
f3824347 316 rescue Psych::SyntaxError => e
317 puts e
318 puts "*ERROR."
7f77c274
SS
319 rescue => e
320 puts yml
321 p e
322 end
323 end
4b563ee8 324 puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n")
7f77c274
SS
325RUBY
326
e02c1511 327 raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
4b563ee8
SS
328
329 env=()
f3824347 330 ok=1
4b563ee8 331 while read i; do
f3824347 332 if [ "$i" == "*ERROR." ]; then
333 ok=0
334 elif [ -n "$i" ]; then
16f2d250
S
335 env[${#env[@]}]=$i
336 fi
4b563ee8
SS
337 done <<< "$raw"
338
f3824347 339 if [ "$ok" -ne 1 ]; then
340 echo "${env[@]}"
c2d3ee4a 341 echo "YAML syntax error. Please check your containers/*.yml config files."
f3824347 342 exit 1
343 fi
762d9bbf
MP
344
345 read -r -d '' labels_ruby << 'RUBY'
346 require 'yaml'
347
348 input=STDIN.readlines.join
349 # default to UTF-8 for the dbs sake
350 labels = {}
351 input.split('_FILE_SEPERATOR_').each do |yml|
352 yml.strip!
353 begin
354 labels.merge!(YAML.load(yml)['labels'] || {})
355 rescue Psych::SyntaxError => e
356 puts e
357 puts "*ERROR."
358 rescue => e
359 puts yml
360 p e
361 end
362 end
363 puts labels.map{|k,v| "-l\n#{k}=#{v}" }.join("\n")
364RUBY
365
366 raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$labels_ruby"`
367
368 labels=()
369 ok=1
370 while read i; do
371 if [ "$i" == "*ERROR." ]; then
372 ok=0
373 elif [ -n "$i" ]; then
daddbf86 374 labels[${#labels[@]}]=$(echo $i | sed s/{{config}}/${config}/g)
762d9bbf
MP
375 fi
376 done <<< "$raw"
377
378 if [ "$ok" -ne 1 ]; then
379 echo "${labels[@]}"
380 echo "YAML syntax error. Please check your containers/*.yml config files."
381 exit 1
382 fi
7f77c274
SS
383}
384
665468eb 385if [ -z $docker_path ]; then
52388b87 386 install_docker
665468eb 387fi
52388b87 388
de869404 389[ "$command" == "cleanup" ] && {
c692f743
L
390 echo
391 echo "The following command will"
392 echo "- Delete all docker images for old containers"
393 echo "- Delete all stopped and orphan containers"
394 echo
395 read -p "Are you sure (Y/n): " -n 1 -r && echo
396 if [[ $REPLY =~ ^[Yy]$ || ! $REPLY ]]
397 then
30835a52 398 space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
29a35d1b 399 echo "Starting Cleanup (bytes free $space)"
30835a52 400
29a35d1b 401 STATE_DIR=./.gc-state scripts/docker-gc
30835a52 402
29a35d1b
S
403 space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
404 echo "Finished Cleanup (bytes free $space)"
30835a52 405
c692f743 406 else
30835a52 407 exit 1
c692f743 408 fi
2dfd2c6d
GXT
409
410 if [ -d /var/discourse/shared/standalone/postgres_data_old ]; then
411 echo
412 echo "Old PostgreSQL backup data cluster detected taking up $(du -hs /var/discourse/shared/standalone/postgres_data_old | awk '{print $1}') detected"
413 read -p "Would you like to remove it? (Y/n): " -n 1 -r && echo
414
415 if [[ $REPLY =~ ^[Yy]$ ]]; then
416 echo "removing old PostgreSQL data cluster at /var/discourse/shared/standalone/postgres_data_old..."
417 rm -rf /var/discourse/shared/standalone/postgres_data_old
418 else
419 exit 1
420 fi
421 fi
422
a8b66f98
L
423 exit 0
424}
5f803fb4 425
65573a0e
GXT
426if [ -z "$command" -a -z "$config" ]; then
427 usage
428fi
429
430if [ ! "$command" == "setup" ]; then
431 if [[ ! -e $config_file ]]; then
7e738616 432 echo "Config file was not found, ensure $config_file exists"
5dfdf9a3 433 echo
71680b16 434 echo "Available configs ( `cd containers && ls -dm *.yml | tr -s '\n' ' ' | awk '{ gsub(/\.yml/, ""); print }'`)"
7e738616 435 exit 1
65573a0e 436 fi
7e738616
S
437fi
438
e2ed1fb6
S
439docker_version=($($docker_path --version))
440docker_version=${test[2]//,/}
69545efd 441restart_policy=${restart_policy:---restart=always}
e2ed1fb6 442
30835a52 443set_existing_container(){
295e8f19 444 existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
337a89aa
S
445}
446
665468eb 447run_stop() {
337a89aa 448
30835a52 449 set_existing_container
60f9f04c 450
30835a52 451 if [ ! -z $existing ]
337a89aa 452 then
30835a52
S
453 (
454 set -x
a9cba0fc 455 $docker_path stop -t 10 $config
30835a52 456 )
337a89aa 457 else
30835a52
S
458 echo "$config was not started !"
459 exit 1
460 fi
461}
337a89aa 462
8877f99e
S
463set_run_image() {
464 run_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
465 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['run_image']"`
466
467 if [ -z "$run_image" ]; then
468 run_image="$local_discourse/$config"
469 fi
470}
471
472set_boot_command() {
473 boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
474 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['boot_command']"`
475
476 if [ -z "$boot_command" ]; then
477
478 no_boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
479 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['no_boot_command']"`
480
481 if [ -z "$no_boot_command" ]; then
482 boot_command="/sbin/boot"
483 fi
484 fi
485}
486
665468eb 487run_start() {
337a89aa 488
295e8f19
S
489 existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
490 echo $existing
30835a52
S
491 if [ ! -z $existing ]
492 then
493 echo "Nothing to do, your container has already started!"
eac33309 494 exit 0
30835a52
S
495 fi
496
295e8f19 497 existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
30835a52
S
498 if [ ! -z $existing ]
499 then
500 echo "starting up existing container"
501 (
502 set -x
503 $docker_path start $config
504 )
505 exit 0
506 fi
507
508 host_run
1f656469 509
afec9a51
GXT
510 ports=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
511 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| \"-p #{p}\"}.join(' ')"`
512
8b617e6e
PG
513 docker_args=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
514 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['docker_args']"`
515
30835a52
S
516 set_template_info
517 set_volumes
518 set_links
8877f99e
S
519 set_run_image
520 set_boot_command
30835a52 521
c6dd6f9d
FB
522 # get hostname and settings from container configuration
523 for envar in "${env[@]}"
524 do
525 if [[ $envar == DOCKER_USE_HOSTNAME* ]] || [[ $envar == DISCOURSE_HOSTNAME* ]]
526 then
527 # use as environment variable
528 eval $envar
529 fi
530 done
531
30835a52 532 (
c834fdd1 533 hostname=`hostname -s`
c6dd6f9d
FB
534 # overwrite hostname
535 if [ "$DOCKER_USE_HOSTNAME" = "true" ]
536 then
537 hostname=$DISCOURSE_HOSTNAME
538 else
539 hostname=$hostname-$config
540 fi
541
a0606001
S
542 # we got to normalize so we only have allowed strings, this is more comprehensive but lets see how bash does first
543 # hostname=`$docker_path run $user_args --rm $image ruby -e 'print ARGV[0].gsub(/[^a-zA-Z-]/, "-")' $hostname`
544 # docker added more hostname rules
fd2e7637 545 hostname=${hostname//_/-}
a0606001 546
cad2919f
GXT
547
548 if [ -z "$SKIP_MAC_ADDRESS" ] ; then
549 mac_address="--mac-address $($docker_path run $user_args -i --rm -a stdout -a stderr $image /bin/sh -c "echo $hostname | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'")"
550 fi
d2a86ee1 551
30835a52 552 set -x
27c21012 553 $docker_path run --shm-size=512m $links $attach_on_run $restart_policy "${env[@]}" "${labels[@]}" -h "$hostname" \
bf268008 554 -e DOCKER_HOST_IP="$docker_ip" --name $config -t $ports $volumes $mac_address $docker_args $user_args \
d2a86ee1 555 $run_image $boot_command
30835a52
S
556
557 )
558 exit 0
337a89aa
S
559
560}
561
ec8f8b83 562
665468eb 563run_bootstrap() {
794e44d5 564
5dfdf9a3 565 # I got no frigging clue what this does, ask Sam Saffron. It RUNS STUFF ON THE HOST I GUESS?
60f9f04c
S
566 host_run
567
680dd4ea
S
568 # Is the image available?
569 # If not, pull it here so the user is aware what's happening.
4807b1b8 570 $docker_path history $image >/dev/null 2>&1 || $docker_path pull $image
88126eba 571
680dd4ea 572 set_template_info
93149421 573
e02c1511 574 base_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
680dd4ea 575 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`
93149421 576
e02c1511 577 update_pups=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
680dd4ea 578 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
b9c7b50e 579
680dd4ea
S
580 if [[ ! X"" = X"$base_image" ]]; then
581 image=$base_image
582 fi
b9c7b50e 583
680dd4ea 584 set_volumes
41daa523 585 set_links
b9c7b50e 586
680dd4ea 587 rm -f $cidbootstrap
d90671f3 588
680dd4ea
S
589 run_command="cd /pups &&"
590 if [[ ! "false" = $update_pups ]]; then
591 run_command="$run_command git pull &&"
592 fi
ca2ce907 593 run_command="$run_command /pups/bin/pups --stdin"
2162f1d4 594
680dd4ea 595 echo $run_command
b9c7b50e 596
b4ab14c2 597 unset ERR
27c21012 598 (exec echo "$input" | $docker_path run --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
b4ab14c2
S
599 /bin/bash -c "$run_command") || ERR=$?
600
601 unset FAILED
602 # magic exit code that indicates a retry
603 if [[ "$ERR" == 77 ]]; then
382c8e40
S
604 $docker_path rm `cat $cidbootstrap`
605 rm $cidbootstrap
b4ab14c2 606 exit 77
382c8e40 607 elif [[ "$ERR" > 0 ]]; then
b4ab14c2
S
608 FAILED=TRUE
609 fi
19e3a6c0
S
610
611 if [[ $FAILED = "TRUE" ]]; then
612 if [[ ! -z "$DEBUG" ]]; then
613 $docker_path commit `cat $cidbootstrap` $local_discourse/$config-debug || echo 'FAILED TO COMMIT'
614 echo "** DEBUG ** Maintaining image for diagnostics $local_discourse/$config-debug"
615 fi
88126eba 616
19e3a6c0
S
617 $docker_path rm `cat $cidbootstrap`
618 rm $cidbootstrap
619 echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one"
620 exit 1
621 fi
9fb5f2d3 622
680dd4ea 623 sleep 5
2162f1d4 624
4807b1b8
MB
625 $docker_path commit `cat $cidbootstrap` $local_discourse/$config || echo 'FAILED TO COMMIT'
626 $docker_path rm `cat $cidbootstrap` && rm $cidbootstrap
680dd4ea 627}
9fb5f2d3 628
8877f99e
S
629
630
680dd4ea
S
631case "$command" in
632 bootstrap)
680dd4ea 633 run_bootstrap
2dd2e330 634 echo "Successfully bootstrapped, to startup use ./launcher start $config"
4b3aebe1 635 exit 0
5f803fb4 636 ;;
1acce9e4 637
2fc6ff36 638 enter)
0c456e8c 639 exec $docker_path exec -it $config /bin/bash --login
2fc6ff36
S
640 ;;
641
5f803fb4 642 stop)
337a89aa
S
643 run_stop
644 exit 0
5f803fb4 645 ;;
7e738616 646
5f803fb4 647 logs)
7e738616 648
30835a52
S
649 $docker_path logs $config
650 exit 0
5f803fb4 651 ;;
7e738616 652
337a89aa
S
653 restart)
654 run_stop
655 run_start
656 exit 0
657 ;;
80c11be3 658
337a89aa
S
659 start)
660 run_start
661 exit 0
5f803fb4 662 ;;
7e738616 663
680dd4ea 664 rebuild)
4b6456ef 665 if [ "$(git symbolic-ref --short HEAD)" == "master" ]; then
c2d3ee4a 666 echo "Ensuring launcher is up to date"
098533cb
S
667
668 git remote update
669
670 LOCAL=$(git rev-parse @)
671 REMOTE=$(git rev-parse @{u})
672 BASE=$(git merge-base @ @{u})
673
674 if [ $LOCAL = $REMOTE ]; then
c2d3ee4a 675 echo "Launcher is up-to-date"
098533cb
S
676
677 elif [ $LOCAL = $BASE ]; then
c2d3ee4a 678 echo "Updating Launcher"
098533cb 679 git pull || (echo 'failed to update' && exit 1)
88ee2e35 680
8100fab0
PD
681 for (( i=${#BASH_ARGV[@]}-1,j=0; i>=0,j<${#BASH_ARGV[@]}; i--,j++ ))
682 do
683 args[$j]=${BASH_ARGV[$i]}
684 done
685 exec /bin/bash $0 "${args[@]}" # $@ is empty, because of shift at the beginning. Use BASH_ARGV instead.
098533cb
S
686
687 elif [ $REMOTE = $BASE ]; then
c2d3ee4a 688 echo "Your version of Launcher is ahead of origin"
098533cb
S
689
690 else
c2d3ee4a 691 echo "Launcher has diverged source, this is only expected in Dev mode"
098533cb
S
692 fi
693
4b6456ef 694 fi
30835a52
S
695
696 set_existing_container
697
698 if [ ! -z $existing ]
680dd4ea
S
699 then
700 echo "Stopping old container"
30835a52
S
701 (
702 set -x
703 $docker_path stop -t 10 $config
704 )
680dd4ea
S
705 fi
706
707 run_bootstrap
708
30835a52 709 if [ ! -z $existing ]
680dd4ea 710 then
30835a52
S
711 echo "Removing old container"
712 (
713 set -x
714 $docker_path rm $config
715 )
680dd4ea
S
716 fi
717
718 run_start
719 exit 0
720 ;;
721
7e738616 722
5f803fb4 723 destroy)
98bd0edf 724 (set -x; $docker_path stop -t 10 $config && $docker_path rm $config) || (echo "$config was not found" && exit 0)
30835a52 725 exit 0
5f803fb4
SS
726 ;;
727esac
7e738616 728
5f803fb4 729usage