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