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