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