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