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