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