Merge with auto branch
[discourse_docker.git] / discourse-setup
index 447884419e633777ae4410f3aec5358783516beb..b5f89f218785c0ce4b8ce57253b06d6e49a64a72 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
 ##
 ## Make sure only root can run our script
@@ -11,14 +11,58 @@ check_root() {
 }
 
 
-## 
+##
+## Does the current IP match the domain name?
+##
+check_IP_match () {
+  echo
+  echo Checking your domain name . . .
+  sleep 1
+  local IFACE=none
+  local IFCONFIG=`which ifconfig`
+  /sbin/route |grep default > /tmp/route$PPID
+
+  if grep default /tmp/route$PPID > /dev/null
+  then
+      local IFACE=`cut -c 73-100 /tmp/route$PPID |head -1`
+  else
+    echo WARNING: Cannot check your IP number.
+  fi
+  local IP=`$IFCONFIG $IFACE|grep  "inet addr:" |cut -d":" -f 2|cut -d" " -f1|head -1`
+  local RESOLVED_IP=`dig +short $1`
+
+  IP_LOOKS_GOOD=0
+  if [[ ! -z $RESOLVED_IP ]]
+  then
+      if [ $IP == $RESOLVED_IP ]
+      then
+         echo $1 resolves to $IP. Looks good!
+         echo
+         local IP_LOOKS_GOOD=1
+      fi
+  fi
+  if [ $IP_LOOKS_GOOD == 0 ]
+  then
+      echo "-----------------------------------------"
+      echo $1 does not resolve to $IP.
+      echo IT IS ALMOST CERTAINLY A BAD IDEA TO TURN ON LET\'S ENCRYPT!!
+      echo Unless you know why this check failed, DO NOT USE Let\'s Encrypt.
+      echo
+      echo You should answer \"n\" at the next prompt and disable Let\'s Encrypt.
+      echo You have been warned.
+      echo "-----------------------------------------"
+  fi
+  sleep 1
+}
+
+##
 ## Do we have docker?
 ##
 check_and_install_docker () {
   docker_path=`which docker.io || which docker`
   if [ -z $docker_path ]; then
     read  -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
-    curl https://get.docker.com/ | sh    
+    curl https://get.docker.com/ | sh
   fi
   docker_path=`which docker.io || which docker`
   if [ -z $docker_path ]; then
@@ -27,36 +71,63 @@ check_and_install_docker () {
   fi
 }
 
+##
+## What are we running on
+##
+check_OS() {
+  echo `uname -s`
+}
+
+##
+## OS X available memory
+##
+check_osx_memory() {
+  echo `top -l 1 | awk '/PhysMem:/ {print $2}' | sed s/G//`
+}
+
+##
+## Linux available memory
+##
+check_linux_memory() {
+  echo `free -g --si | awk ' /Mem:/  {print $2} '`
+}
+
 ##
 ## Do we have enough memory and disk space for Discourse?
 ##
 check_disk_and_memory() {
-  
-  avail_mem=`free -g --si | awk ' /Mem:/  {print $2} '`
+
+  os_type=$(check_OS)
+  avail_mem=0
+  if [ $os_type == "Darwin" ]; then
+    avail_mem=$(check_osx_memory)
+  else
+    avail_mem=$(check_linux_memory)
+  fi
+
   if [ "$avail_mem" -lt 1 ]; then
     echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
     echo "to have sufficient memory."
     echo
     echo "Your site may not work properly, or future upgrades of Discourse may not"
     echo "complete successfully."
-    echo exit 1
+    exit 1
   fi
-    
-  if [ "$avail_mem" -lt 2 ]; then
+
+  if [ "$avail_mem" -le 2 ]; then
     total_swap=`free -g --si | awk ' /Swap:/  {print $2} '`
     if [ "$total_swap" -lt 2 ]; then
-      echo "WARNING: Discourse requires at least 2GB of swap when running with less "
-      echo "than 2GB of RAM. This system does not appear to have sufficient swap space."
+      echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
+      echo "or less. This system does not appear to have sufficient swap space."
       echo
       echo "Without sufficient swap space, your site may not work properly, and future"
       echo "upgrades of Discourse may not complete successfully."
       echo
       read -p "ENTER to create a 2GB swapfile now, or Ctrl+C to exit"
-      
+
       ##
       ## derived from https://meta.discourse.org/t/13880
-      ## 
+      ##
       install -o root -g root -m 0600 /dev/null /swapfile
       dd if=/dev/zero of=/swapfile bs=1k count=2048k
       mkswap /swapfile
@@ -70,7 +141,7 @@ check_disk_and_memory() {
         echo "Failed to create swap, sorry!"
         exit 1
       fi
-      
+
     fi
   fi
 
@@ -100,8 +171,16 @@ scale_ram_and_cpu() {
 
   local changelog=/tmp/changelog.$PPID
   # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
-  avail_gb="$(LANG=C free -g --si | grep '^Mem:' | awk '{print $2}')"
-  avail_cores=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
+  avail_gb=0
+  avail_cores=0
+  os_type=$(check_OS)
+  if [ $os_type == "Darwin" ]; then
+    avail_gb=$(check_osx_memory)
+    avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
+  else
+    avail_gb=$(check_linux_memory)
+    avail_cores=$((`awk '/cpu cores/ {print $4;exit}' /proc/cpuinfo`*`sort /proc/cpuinfo | uniq | grep -c "physical id"`))
+  fi
   echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
 
   # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
@@ -118,7 +197,7 @@ scale_ram_and_cpu() {
   fi
   db_shared_buffers=$(( db_shared_buffers < 4096 ? db_shared_buffers : 4096 ))
 
-  sed -i -e "s/^  #db_shared_buffers:.*/  db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
+  sed -i -e "s/^  #\?db_shared_buffers:.*/  db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
   if [ -s $changelog ]
   then
     echo "setting db_shared_buffers = ${db_shared_buffers}MB"
@@ -134,7 +213,7 @@ scale_ram_and_cpu() {
   fi
   unicorn_workers=$(( unicorn_workers < 8 ? unicorn_workers : 8 ))
 
-  sed -i -e "s/^  #UNICORN_WORKERS:.*/  UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
+  sed -i -e "s/^  #\?UNICORN_WORKERS:.*/  UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
   if [ -s $changelog ]
   then
       echo "setting UNICORN_WORKERS = ${unicorn_workers}"
@@ -144,7 +223,7 @@ scale_ram_and_cpu() {
 }
 
 
-## 
+##
 ## standard http / https ports must not be occupied
 ##
 check_ports() {
@@ -158,7 +237,7 @@ check_ports() {
 ## check a port to see if it is already in use
 ##
 check_port() {
-  
+
   local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
 
   if [ -n "$valid" ]; then
@@ -166,31 +245,69 @@ check_port() {
     echo
     echo "If you are trying to run Discourse simultaneously with another web"
     echo "server like Apache or nginx, you will need to bind to a different port"
-    echo 
+    echo
     echo "See https://meta.discourse.org/t/17247"
+    echo
+    echo "If you are reconfiguring an already-configured Discourse, use "
+    echo
+    echo "./launcher stop app"
+    echo
+    echo "to stop Discourse before you reconfigure it and try again."
     exit 1
   fi
 }
 
+##
+## read a variable from the config file
+##
+read_config() {
+
+  config_line=`egrep "^  #?$1:" $config_file`
+  read_config_result=`echo $config_line | awk '{print $2}'`
+  read_config_result=`echo $read_config_result | sed "s/^\([\"']\)\(.*\)\1\$/\2/g"`
+}
+
+
+
 ##
 ## prompt user for typical Discourse config file values
 ##
 ask_user_for_config() {
-  
+
+  # NOTE: Defaults now come from standalone.yml
+
   local changelog=/tmp/changelog.$PPID
-  local hostname="discourse.example.com"
-  local developer_emails="me@example.com,you@example.com"
-  local smtp_address="smtp.example.com"
-  local smtp_port="587"
-  local smtp_user_name="postmaster@discourse.example.com"  
-  local smtp_password=""
-  local letsencrypt_account_email="me@example.com"
-  local letsencrypt_status="ENTER to skip"
+  read_config "DISCOURSE_SMTP_ADDRESS"
+  local smtp_address=$read_config_result
+  # NOTE: if there are spaces between emails, this breaks, but a human should be paying attention
+  read_config "DISCOURSE_DEVELOPER_EMAILS"
+  local developer_emails=$read_config_result
+  read_config "DISCOURSE_SMTP_PASSWORD"
+  local smtp_password=$read_config_result
+  read_config "DISCOURSE_SMTP_PORT"
+  local smtp_port=$read_config_result
+  read_config "DISCOURSE_SMTP_USER_NAME"
+  local smtp_user_name=$read_config_result
+  if [ "$smtp_password" = "pa$$word" ]
+  then
+      smtp_password = ""
+  fi
+  read_config "LETSENCRYPT_ACCOUNT_EMAIL"
+  local letsencrypt_account_email=$read_config_result
+  if [ $letsencrypt_account_email = "me@example.com" ]
+  then
+      local letsencrypt_status="ENTER to skip"
+  else
+    local letsencrypt_status="Enter 'OFF' to disable."
+  fi
+
+  read_config "DISCOURSE_HOSTNAME"
+  hostname=$read_config_result
 
   local new_value=""
   local config_ok="n"
   local update_ok="y"
-  
+
   echo ""
 
   while [[ "$config_ok" == "n" ]]
@@ -203,16 +320,16 @@ ask_user_for_config() {
           hostname=$new_value
       fi
     fi
-    
+
     if [ ! -z $developer_emails ]
     then
-      read -p "Email address for admin account? [$developer_emails]: " new_value
+      read -p "Email address for admin account(s)? [$developer_emails]: " new_value
       if [ ! -z $new_value ]
       then
           developer_emails=$new_value
       fi
     fi
-    
+
     if [ ! -z $smtp_address ]
     then
       read -p "SMTP server address? [$smtp_address]: " new_value
@@ -221,7 +338,7 @@ ask_user_for_config() {
         smtp_address=$new_value
       fi
     fi
-    
+
     if [ ! -z $smtp_port ]
     then
       read -p "SMTP port? [$smtp_port]: " new_value
@@ -230,14 +347,14 @@ ask_user_for_config() {
         smtp_port=$new_value
       fi
     fi
-    
+
     ##
     ## automatically set correct user name based on common mail providers
     ##
     if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
     then
        smtp_user_name="SMTP_Injection"
-    fi    
+    fi
     if [ "$smtp_address" == "smtp.sendgrid.net" ]
     then
            smtp_user_name="apikey"
@@ -246,7 +363,7 @@ ask_user_for_config() {
     then
            smtp_user_name="postmaster@$hostname"
     fi
-    
+
     if [ ! -z $smtp_user_name ]
     then
       read -p "SMTP user name? [$smtp_user_name]: " new_value
@@ -255,20 +372,20 @@ ask_user_for_config() {
           smtp_user_name=$new_value
       fi
     fi
-    
+
     read -p "SMTP password? [$smtp_password]: " new_value
     if [ ! -z $new_value ]
     then
         smtp_password=$new_value
     fi
-    
+
     if [ ! -z $letsencrypt_account_email ]
     then
       read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
       if [ ! -z $new_value ]
       then
           letsencrypt_account_email=$new_value
-          if [ "$new_value" == "off" ]
+          if [ "${new_value,,}" = "off" ]
           then
             letsencrypt_status="ENTER to skip"
           else
@@ -277,6 +394,11 @@ ask_user_for_config() {
       fi
     fi
 
+    if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
+    then
+       check_IP_match $hostname
+    fi
+
     echo -e "\nDoes this look right?\n"
     echo "Hostname      : $hostname"
     echo "Email         : $developer_emails"
@@ -284,12 +406,13 @@ ask_user_for_config() {
     echo "SMTP port     : $smtp_port"
     echo "SMTP username : $smtp_user_name"
     echo "SMTP password : $smtp_password"
-    
+
     if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
     then
       echo "Let's Encrypt : $letsencrypt_account_email"
     fi
-    
+
+
     echo ""
     read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
   done
@@ -321,7 +444,7 @@ ask_user_for_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  #DISCOURSE_SMTP_PORT:.*/  DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
+  sed -i -e "s/^  #\?DISCOURSE_SMTP_PORT:.*/  DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
   if [ -s $changelog ]
   then
     rm $changelog
@@ -330,7 +453,7 @@ ask_user_for_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  #DISCOURSE_SMTP_USER_NAME:.*/  DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
+  sed -i -e "s/^  #\?DISCOURSE_SMTP_USER_NAME:.*/  DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
   if [ -s $changelog ]
   then
     rm $changelog
@@ -339,7 +462,7 @@ ask_user_for_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  #DISCOURSE_SMTP_PASSWORD:.*/  DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
+  sed -i -e "s/^  #\?DISCOURSE_SMTP_PASSWORD:.*/  DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
   if [ -s $changelog ]
   then
       rm $changelog
@@ -348,9 +471,28 @@ ask_user_for_config() {
     update_ok="n"
   fi
 
-  if [ "$letsencrypt_status" != "ENTER to skip" ]
+  if [ "$letsencrypt_status" = "ENTER to skip" ]
   then
-      sed -i -e "s/^  #LETSENCRYPT_ACCOUNT_EMAIL:.*/  LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
+      local src='^  #\?- "templates\/web.ssl.template.yml"'
+      local dst='  #\- "templates\/web.ssl.template.yml"'
+      sed -i -e "s/$src/$dst/w $changelog" $config_file
+      if [ ! -s $changelog ]
+      then
+        update_ok="n"
+        echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
+      fi
+      local src='^  #\?- "templates\/web.letsencrypt.ssl.template.yml"'
+      local dst='  #- "templates\/web.letsencrypt.ssl.template.yml"'
+
+      sed -i -e "s/$src/$dst/w $changelog" $config_file
+      if [ ! -s $changelog ]
+      then
+        update_ok="n"
+        echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
+      fi
+  else # enable let's encrypt
+    echo "Let's Encrypt will be enabled for $letsencrypt_account_email"
+      sed -i -e "s/^  #\?LETSENCRYPT_ACCOUNT_EMAIL:.*/  LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
       if [ -s $changelog ]
       then
         rm $changelog
@@ -358,7 +500,7 @@ ask_user_for_config() {
         echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
         update_ok="n"
       fi
-      local src='^  #- "templates\/web.ssl.template.yml"'
+      local src='^  #\?- "templates\/web.ssl.template.yml"'
       local dst='  \- "templates\/web.ssl.template.yml"'
       sed -i -e "s/$src/$dst/w $changelog" $config_file
       if [ -s $changelog ]
@@ -368,7 +510,7 @@ ask_user_for_config() {
         update_ok="n"
         echo "web.ssl.template.yml NOT ENABLED--was it on already?"
       fi
-      local src='^  #- "templates\/web.letsencrypt.ssl.template.yml"'
+      local src='^  #\?- "templates\/web.letsencrypt.ssl.template.yml"'
       local dst='  - "templates\/web.letsencrypt.ssl.template.yml"'
 
       sed -i -e "s/$src/$dst/w $changelog" $config_file
@@ -379,7 +521,7 @@ ask_user_for_config() {
         update_ok="n"
         echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
       fi
-  fi 
+  fi
 
   if [ "$update_ok" == "y" ]
   then
@@ -396,11 +538,11 @@ ask_user_for_config() {
 validate_config() {
 
   valid_config="y"
-  
+
   for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
            DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
   do
-    config_line=`grep "^  $x:" $config_file` 
+    config_line=`grep "^  $x:" $config_file`
     local result=$?
     local default="example.com"
 
@@ -422,7 +564,7 @@ validate_config() {
       valid_config="n"
     fi
   done
-  
+
   if [ "$valid_config" != "y" ]; then
     echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
     echo "If you have unusual requirements, edit $config_file and then: "
@@ -454,10 +596,9 @@ check_ports
 if [ -a $config_file ]
 then
   echo "The configuration file $config_file already exists!"
-  echo ""
-  echo "If you want to delete your old configuration file and start over:"
-  echo "rm $config_file"
-  exit 1
+  echo
+  echo ". . . reconfiguring . . ."
+  echo
 else
   cp $template_path $config_file
 fi
@@ -468,5 +609,7 @@ validate_config
 
 ##
 ## if we reach this point without exiting, OK to proceed
+## rebuild won't fail if there's nothing to rebuild and does the restart
 ##
-./launcher bootstrap $app_name && ./launcher start $app_name
+sleep 5 # Just a chance to ^C in case they were too fast on the draw
+time ./launcher rebuild $app_name