FIX discourse-setup--better sanity checking
[discourse_docker.git] / discourse-setup
1 #!/usr/bin/env bash
2 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
3 cd $DIR
4
5 ##
6 ## Make sure only root can run our script
7 ##
8 check_root() {
9 if [[ $EUID -ne 0 ]]; then
10 echo "This script must be run as root. Please sudo or log in as root first." 1>&2
11 exit 1
12 fi
13 }
14
15 ##
16 ## Check whether a connection to HOSTNAME ($1) on PORT ($2) is possible
17 ##
18 connect_to_port () {
19 HOST="$1"
20 PORT="$2"
21 VERIFY=`date +%s | sha256sum | base64 | head -c 20`
22 echo -e "HTTP/1.1 200 OK\n\n $VERIFY" | nc -w 4 -l -p $PORT >/dev/null 2>&1 &
23 if curl --proto =http -s $HOST:$PORT --connect-timeout 3 | grep $VERIFY >/dev/null 2>&1
24 then
25 return 0
26 else
27 curl --proto =http -s localhost:$PORT >/dev/null 2>&1
28 return 1
29 fi
30 }
31
32 check_IP_match () {
33 HOST="$1"
34 echo
35 echo Checking your domain name . . .
36 if connect_to_port $HOST 443
37 then
38 echo
39 echo "Connection to $HOST succeeded."
40 else
41 echo WARNING:: This server does not appear to be accessible at $HOST:443.
42 echo
43 if connect_to_port $HOST 80
44 then
45 echo A connection to port 80 succeeds, however.
46 echo This suggests that your DNS settings are correct,
47 echo but something is keeping traffic to port 443 from getting to your server.
48 echo Check your networking configuration to see that connections to port 443 are allowed.
49 else
50 echo "A connection to http://$HOST (port 80) also fails."
51 echo
52 echo This suggests that $HOST resolves to the wrong IP address
53 echo or that traffic is not being routed to your server.
54 fi
55 echo
56 echo Google: \"open ports YOUR CLOUD SERVICE\" for information for resolving this problem.
57 echo
58 echo You should probably answer \"n\" at the next prompt and disable Let\'s Encrypt.
59 echo
60 echo This test might not work for all situations,
61 echo so if you can access Discourse at http://$HOST, you might try anyway.
62 sleep 3
63 fi
64 }
65
66 ##
67 ## Do we have docker?
68 ##
69 check_and_install_docker () {
70 docker_path=`which docker.io || which docker`
71 if [ -z $docker_path ]; then
72 read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
73 curl https://get.docker.com/ | sh
74 fi
75 docker_path=`which docker.io || which docker`
76 if [ -z $docker_path ]; then
77 echo Docker install failed. Quitting.
78 exit
79 fi
80 }
81
82 ##
83 ## What are we running on
84 ##
85 check_OS() {
86 echo `uname -s`
87 }
88
89 ##
90 ## OS X available memory
91 ##
92 check_osx_memory() {
93 echo `free -m | awk '/Mem:/ {print $2}'`
94 }
95
96 ##
97 ## Linux available memory
98 ##
99 check_linux_memory() {
100 echo `free -g --si | awk ' /Mem:/ {print $2} '`
101 }
102
103 ##
104 ## Do we have enough memory and disk space for Discourse?
105 ##
106 check_disk_and_memory() {
107
108 os_type=$(check_OS)
109 avail_mem=0
110 if [ "$os_type" == "Darwin" ]; then
111 avail_mem=$(check_osx_memory)
112 else
113 avail_mem=$(check_linux_memory)
114 fi
115
116 if [ "$avail_mem" -lt 1 ]; then
117 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
118 echo "to have sufficient memory."
119 echo
120 echo "Your site may not work properly, or future upgrades of Discourse may not"
121 echo "complete successfully."
122 exit 1
123 fi
124
125 if [ "$avail_mem" -le 2 ]; then
126 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
127
128 if [ "$total_swap" -lt 2 ]; then
129 echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
130 echo "or less. This system does not appear to have sufficient swap space."
131 echo
132 echo "Without sufficient swap space, your site may not work properly, and future"
133 echo "upgrades of Discourse may not complete successfully."
134 echo
135 echo "Ctrl+C to exit or wait 5 seconds to have a 2GB swapfile created."
136 sleep 5
137
138 ##
139 ## derived from https://meta.discourse.org/t/13880
140 ##
141 install -o root -g root -m 0600 /dev/null /swapfile
142 dd if=/dev/zero of=/swapfile bs=1k count=2048k
143 mkswap /swapfile
144 swapon /swapfile
145 echo "/swapfile swap swap auto 0 0" | tee -a /etc/fstab
146 sysctl -w vm.swappiness=10
147 echo vm.swappiness = 10 | tee -a /etc/sysctl.conf
148
149 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
150 if [ "$total_swap" -lt 2 ]; then
151 echo "Failed to create swap: are you root? Are you running on real hardware, or a fully virtualized server?"
152 exit 1
153 fi
154
155 fi
156 fi
157
158
159 free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
160 if [ "$free_disk" -lt 5000 ]; then
161 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
162 echo "does not appear to have sufficient disk space."
163 echo
164 echo "Insufficient disk space may result in problems running your site, and"
165 echo "may not even allow Discourse installation to complete successfully."
166 echo
167 echo "Please free up some space, or expand your disk, before continuing."
168 echo
169 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
170 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
171 exit 1
172 fi
173
174 }
175
176
177 ##
178 ## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
179 ##
180 scale_ram_and_cpu() {
181
182 local changelog=/tmp/changelog.$PPID
183 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
184 avail_gb=0
185 avail_cores=0
186 os_type=$(check_OS)
187 if [ "$os_type" == "Darwin" ]; then
188 avail_gb=$(check_osx_memory)
189 avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
190 else
191 avail_gb=$(check_linux_memory)
192 avail_cores=$((`awk '/cpu cores/ {print $4;exit}' /proc/cpuinfo`*`sort /proc/cpuinfo | uniq | grep -c "physical id"`))
193 fi
194 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
195
196 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
197 if [ "$avail_gb" -eq "1" ]
198 then
199 db_shared_buffers=128
200 else
201 if [ "$avail_gb" -eq "2" ]
202 then
203 db_shared_buffers=256
204 else
205 db_shared_buffers=$(( 256 * $avail_gb ))
206 fi
207 fi
208 db_shared_buffers=$(( db_shared_buffers < 4096 ? db_shared_buffers : 4096 ))
209
210 sed -i -e "s/^ #\?db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $data_file
211 if [ -s $changelog ]
212 then
213 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
214 rm $changelog
215 fi
216
217 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
218 if [ "$avail_gb" -le "2" ]
219 then
220 unicorn_workers=$(( 2 * $avail_gb ))
221 else
222 unicorn_workers=$(( 2 * $avail_cores ))
223 fi
224 unicorn_workers=$(( unicorn_workers < 8 ? unicorn_workers : 8 ))
225
226 sed -i -e "s/^ #\?UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $web_file
227 if [ -s $changelog ]
228 then
229 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
230 rm $changelog
231 fi
232
233 echo $data_file memory parameters updated.
234 }
235
236
237 ##
238 ## standard http / https ports must not be occupied
239 ##
240 check_ports() {
241 check_port "80"
242 check_port "443"
243 echo "Ports 80 and 443 are free for use"
244 }
245
246
247 ##
248 ## check a port to see if it is already in use
249 ##
250 check_port() {
251
252 local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
253
254 if [ -n "$valid" ]; then
255 echo "Port ${1} appears to already be in use."
256 echo
257 echo "This will show you what command is using port ${1}"
258 lsof -i tcp:${1} -s tcp:listen
259 echo
260 echo "If you are trying to run Discourse simultaneously with another web"
261 echo "server like Apache or nginx, you will need to bind to a different port"
262 echo
263 echo "See https://meta.discourse.org/t/17247"
264 echo
265 echo "If you are reconfiguring an already-configured Discourse, use "
266 echo
267 echo "./launcher stop app"
268 echo
269 echo "to stop Discourse before you reconfigure it and try again."
270 exit 1
271 fi
272 }
273
274 ##
275 ## read a variable from the config file
276 ##
277 read_config() {
278 config_line=`egrep "^ #?$1:" $web_file`
279 read_config_result=`echo $config_line | awk --field-separator=":" '{print $2}'`
280 read_config_result=`echo $read_config_result | sed "s/^\([\"']\)\(.*\)\1\$/\2/g"`
281 }
282
283
284
285 ##
286 ## prompt user for typical Discourse config file values
287 ##
288 ask_user_for_config() {
289
290 # NOTE: Defaults now come from standalone.yml
291
292 local changelog=/tmp/changelog.$PPID
293 read_config "DISCOURSE_SMTP_ADDRESS"
294 local smtp_address=$read_config_result
295 # NOTE: if there are spaces between emails, this breaks, but a human should be paying attention
296 read_config "DISCOURSE_DEVELOPER_EMAILS"
297 local developer_emails=$read_config_result
298 read_config "DISCOURSE_SMTP_PASSWORD"
299 local smtp_password=$read_config_result
300 read_config "DISCOURSE_SMTP_PORT"
301 local smtp_port=$read_config_result
302 read_config "DISCOURSE_SMTP_USER_NAME"
303 local smtp_user_name=$read_config_result
304 if [ "$smtp_password" = "pa$$word" ]
305 then
306 smtp_password = ""
307 fi
308 read_config "LETSENCRYPT_ACCOUNT_EMAIL"
309 local letsencrypt_account_email=$read_config_result
310 if [ -z $letsencrypt_account_email ]
311 then
312 letsencrypt_account_email="me@example.com"
313 fi
314 if [ "$letsencrypt_account_email" = "me@example.com" ]
315 then
316 local letsencrypt_status="ENTER to skip"
317 else
318 local letsencrypt_status="Enter 'OFF' to disable."
319 fi
320
321 read_config "DISCOURSE_HOSTNAME"
322 hostname=$read_config_result
323
324 local new_value=""
325 local config_ok="n"
326 local update_ok="y"
327
328 echo ""
329
330 while [[ "$config_ok" == "n" ]]
331 do
332 if [ ! -z $hostname ]
333 then
334 read -p "Hostname for your Discourse? [$hostname]: " new_value
335 if [ ! -z "$new_value" ]
336 then
337 hostname="$new_value"
338 fi
339 if [[ $hostname =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
340 then
341 echo
342 echo "Discourse requires a DNS hostname. IP addresses are unsupported and will not work."
343 echo
344 hostname="discourse.example.com"
345 fi
346 fi
347
348 if [ ! -z $developer_emails ]
349 then
350 read -p "Email address for admin account(s)? [$developer_emails]: " new_value
351 if [ ! -z "$new_value" ]
352 then
353 developer_emails="$new_value"
354 fi
355 fi
356
357 if [ ! -z $smtp_address ]
358 then
359 read -p "SMTP server address? [$smtp_address]: " new_value
360 if [ ! -z "$new_value" ]
361 then
362 smtp_address="$new_value"
363 fi
364 fi
365
366 if [ ! -z $smtp_port ]
367 then
368 read -p "SMTP port? [$smtp_port]: " new_value
369 if [ ! -z "$new_value" ]
370 then
371 smtp_port="$new_value"
372 fi
373 fi
374
375 ##
376 ## automatically set correct user name based on common mail providers unless it's been set
377 ##
378 if [ "$smtp_user_name" == "user@example.com" ]
379 then
380 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
381 then
382 smtp_user_name="SMTP_Injection"
383 fi
384 if [ "$smtp_address" == "smtp.sendgrid.net" ]
385 then
386 smtp_user_name="apikey"
387 fi
388 if [ "$smtp_address" == "smtp.mailgun.org" ]
389 then
390 smtp_user_name="postmaster@$hostname"
391 fi
392 fi
393
394 if [ ! -z "$smtp_user_name" ]
395 then
396 read -p "SMTP user name? [$smtp_user_name]: " new_value
397 if [ ! -z "$new_value" ]
398 then
399 smtp_user_name="$new_value"
400 fi
401 fi
402
403 read -p "SMTP password? [$smtp_password]: " new_value
404 if [ ! -z "$new_value" ]
405 then
406 smtp_password="$new_value"
407 fi
408
409 if [ ! -z $letsencrypt_account_email ]
410 then
411 read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
412 if [ ! -z "$new_value" ]
413 then
414 letsencrypt_account_email="$new_value"
415 if [ "${new_value,,}" = "off" ]
416 then
417 letsencrypt_status="ENTER to skip"
418 else
419 letsencrypt_status="Enter 'OFF' to disable."
420 fi
421 fi
422 fi
423
424 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
425 then
426 check_IP_match $hostname
427 fi
428
429 echo -e "\nDoes this look right?\n"
430 echo "Hostname : $hostname"
431 echo "Email : $developer_emails"
432 echo "SMTP address : $smtp_address"
433 echo "SMTP port : $smtp_port"
434 echo "SMTP username : $smtp_user_name"
435 echo "SMTP password : $smtp_password"
436
437 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
438 then
439 echo "Let's Encrypt : $letsencrypt_account_email"
440 fi
441
442
443 echo ""
444 read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
445 done
446
447 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $web_file
448 if [ -s $changelog ]
449 then
450 rm $changelog
451 else
452 echo "DISCOURSE_HOSTNAME change failed."
453 update_ok="n"
454 fi
455
456 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $web_file
457 if [ -s $changelog ]
458 then
459 rm $changelog
460 else
461 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
462 update_ok="n"
463 fi
464
465 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $web_file
466 if [ -s $changelog ]
467 then
468 rm $changelog
469 else
470 echo "DISCOURSE_SMTP_ADDRESS change failed."
471 update_ok="n"
472 fi
473
474 sed -i -e "s/^ #\?DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $web_file
475 if [ -s $changelog ]
476 then
477 rm $changelog
478 else
479 echo "DISCOURSE_SMTP_PORT change failed."
480 update_ok="n"
481 fi
482
483 sed -i -e "s/^ #\?DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $web_file
484 if [ -s $changelog ]
485 then
486 rm $changelog
487 else
488 echo "DISCOURSE_SMTP_USER_NAME change failed."
489 update_ok="n"
490 fi
491
492 if [[ "$smtp_password" == *"\""* ]]
493 then
494 SLASH="BROKEN"
495 echo "========================================"
496 echo "WARNING!!!"
497 echo "Your password contains a quote (\")"
498 echo "Your SMTP Password will not be set. You will need to edit app.yml to enter it."
499 echo "========================================"
500 update_ok="n"
501 else
502 SLASH="|"
503 if [[ "$smtp_password" == *"$SLASH"* ]]
504 then SLASH="+"
505 if [[ "$smtp_password" == *"$SLASH"* ]]
506 then
507 SLASH="Q"
508 if [[ "$smtp_password" == *"$SLASH"* ]]
509 then
510 SLASH="BROKEN"
511 echo "========================================"
512 echo "WARNING!!!"
513 echo "Your password contains all available delimiters (+, |, and Q). "
514 echo "Your SMTP Password will not be set. You will need to edit app.yml to enter it."
515 echo "========================================"
516 update_ok="n"
517 fi
518 fi
519 fi
520 fi
521 if [[ "$SLASH" != "BROKEN" ]]
522 then
523 sed -i -e "s${SLASH}^ #\?DISCOURSE_SMTP_PASSWORD:.*${SLASH} DISCOURSE_SMTP_PASSWORD: \"${smtp_password}\"${SLASH}w $changelog" $web_file
524
525 if [ -s $changelog ]
526 then
527 rm $changelog
528 else
529 echo "DISCOURSE_SMTP_PASSWORD change failed."
530 update_ok="n"
531 fi
532 fi
533 if [ "$letsencrypt_status" = "ENTER to skip" ]
534 then
535 local src='^ #\?- "templates\/web.ssl.template.yml"'
536 local dst=' #\- "templates\/web.ssl.template.yml"'
537 sed -i -e "s/$src/$dst/w $changelog" $web_file
538 if [ ! -s $changelog ]
539 then
540 update_ok="n"
541 echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
542 fi
543 local src='^ #\?- "templates\/web.letsencrypt.ssl.template.yml"'
544 local dst=' #- "templates\/web.letsencrypt.ssl.template.yml"'
545
546 sed -i -e "s/$src/$dst/w $changelog" $web_file
547 if [ ! -s $changelog ]
548 then
549 update_ok="n"
550 echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
551 fi
552 else # enable let's encrypt
553 echo "Let's Encrypt will be enabled for $letsencrypt_account_email"
554 sed -i -e "s/^ #\?LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $web_file
555 if [ -s $changelog ]
556 then
557 rm $changelog
558 else
559 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
560 update_ok="n"
561 fi
562 local src='^ #\?- "templates\/web.ssl.template.yml"'
563 local dst=' \- "templates\/web.ssl.template.yml"'
564 sed -i -e "s/$src/$dst/w $changelog" $web_file
565 if [ -s $changelog ]
566 then
567 echo "web.ssl.template.yml enabled"
568 else
569 update_ok="n"
570 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
571 fi
572 local src='^ #\?- "templates\/web.letsencrypt.ssl.template.yml"'
573 local dst=' - "templates\/web.letsencrypt.ssl.template.yml"'
574
575 sed -i -e "s/$src/$dst/w $changelog" $web_file
576 if [ -s $changelog ]
577 then
578 echo "letsencrypt.ssl.template.yml enabled"
579 else
580 update_ok="n"
581 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
582 fi
583 fi
584
585 if [ "$update_ok" == "y" ]
586 then
587 echo -e "\nConfiguration file at $config_file updated successfully!\n"
588 else
589 echo -e "\nUnfortunately, there was an error changing $config_file\n"
590 echo -d "This may happen if you have made unexpected changes."
591 exit 1
592 fi
593 }
594
595 ##
596 ## is our config file valid? Does it have the required fields set?
597 ##
598 validate_config() {
599
600 valid_config="y"
601
602 for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
603 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
604 do
605 config_line=`grep "^ $x:" $web_file`
606 local result=$?
607 local default="example.com"
608
609 if (( result == 0 ))
610 then
611 if [[ "$config_line" = *"$default"* ]]
612 then
613 echo "$x left at incorrect default of example.com"
614 valid_config="n"
615 fi
616 config_val=`echo $config_line | awk '{print $2}'`
617 if [ -z $config_val ]
618 then
619 echo "$x was left blank"
620 valid_config="n"
621 fi
622 else
623 echo "$x not present"
624 valid_config="n"
625 fi
626 done
627
628 if [ "$valid_config" != "y" ]; then
629 echo -e "\nSorry, these $web_file settings aren't valid -- can't continue!"
630 echo "If you have unusual requirements, edit $web_file and then: "
631 echo "./launcher bootstrap $app_name"
632 exit 1
633 fi
634 }
635
636
637 ##
638 ## template file names
639 ##
640
641 if [ "$1" == "2container" ]
642 then
643 app_name=web_only
644 data_name=data
645 web_template=samples/web_only.yml
646 data_template=samples/data.yml
647 web_file=containers/$app_name.yml
648 data_file=containers/$data_name.yml
649 else
650 app_name=app
651 data_name=app
652 web_template=samples/standalone.yml
653 data_template=""
654 web_file=containers/$app_name.yml
655 data_file=containers/$app_name.yml
656 fi
657 changelog=/tmp/changelog
658
659 ##
660 ## Check requirements before creating a copy of a config file we won't edit
661 ##
662 check_root
663 check_and_install_docker
664 check_disk_and_memory
665
666 if [ -a "$web_file" ]
667 then
668 echo "The configuration file $web_file already exists!"
669 echo
670 echo ". . . reconfiguring . . ."
671 echo
672 echo
673 DATE=`date +"%Y-%m-%d-%H%M%S"`
674 BACKUP=$app_name.yml.$DATE.bak
675 echo Saving old file as $BACKUP
676 cp $web_file containers/$BACKUP
677 echo "Stopping existing container in 5 seconds or Control-C to cancel."
678 sleep 5
679 ./launcher stop app
680 echo
681 else
682 check_ports
683 cp -v $web_template $web_file
684 if [ "$data_name" == "data" ]
685 then
686 echo "--------------------------------------------------"
687 echo "This two container setup is currently unsupported. Use at your own risk!"
688 echo "--------------------------------------------------"
689 DISCOURSE_DB_PASSWORD=`date +%s | sha256sum | base64 | head -c 20`
690
691 sed -i -e "s/DISCOURSE_DB_PASSWORD: SOME_SECRET/DISCOURSE_DB_PASSWORD: $DISCOURSE_DB_PASSWORD/w $changelog" $web_file
692 if [ -s $changelog ]
693 then
694 rm $changelog
695 else
696 echo "Problem changing DISCOURSE_DB_PASSWORD" in $web_file
697 fi
698
699 cp -v $data_template $data_file
700 quote=\'
701 sed -i -e "s/password ${quote}SOME_SECRET${quote}/password '$DISCOURSE_DB_PASSWORD'/w $changelog" $data_file
702 if [ -s $changelog ]
703 then
704 rm $changelog
705 else
706 echo "Problem changing DISCOURSE_DB_PASSWORD" in $data_file
707 fi
708 fi
709 fi
710
711 scale_ram_and_cpu
712 ask_user_for_config
713 validate_config
714
715 ##
716 ## if we reach this point without exiting, OK to proceed
717 ## rebuild won't fail if there's nothing to rebuild and does the restart
718 ##
719 echo "Updates successful. Rebuilding in 5 seconds."
720 sleep 5 # Just a chance to ^C in case they were too fast on the draw
721 if [ "$data_name" == "$app_name" ]
722 then
723 echo Building $app_name
724 ./launcher rebuild $app_name
725 else
726 echo Building $data_name now . . .
727 ./launcher rebuild $data_name
728 echo Building $app_name now . . .
729 ./launcher rebuild $app_name
730 fi