FIX: Quote all strings in discourse.conf
[discourse_docker.git] / launcher
index b897b42702d7ec0137305e6703cb3d9d0e19616b..879d9b10a57292c5efb44ab78d32aa892d02f672 100755 (executable)
--- a/launcher
+++ b/launcher
@@ -56,15 +56,15 @@ fi
 
 cd "$(dirname "$0")"
 
-docker_min_version='1.8.0'
-docker_rec_version='1.8.0'
+docker_min_version='17.03.1'
+docker_rec_version='17.06.2'
 git_min_version='1.8.0'
 git_rec_version='1.8.0'
 
 config_file=containers/"$config".yml
 cidbootstrap=cids/"$config"_bootstrap.cid
 local_discourse=local_discourse
-image=discourse/discourse:1.3.5
+image=discourse/base:2.0.20171204
 docker_path=`which docker.io || which docker`
 git_path=`which git`
 
@@ -90,25 +90,27 @@ else
                   awk -F: '{ print $3 }';`
 fi
 
+# From https://stackoverflow.com/a/44660519/702738
 compare_version() {
-    declare -a ver_a
-    declare -a ver_b
-    IFS=. read -a ver_a <<< "$1"
-    IFS=. read -a ver_b <<< "$2"
-
-    while [[ -n $ver_a ]]; do
-        if (( ver_a > ver_b )); then
-            return 0
-        elif (( ver_b > ver_a )); then
+    if [[ $1 == $2 ]]; then
+        return 1
+    fi
+    local IFS=.
+    local i a=(${1%%[^0-9.]*}) b=(${2%%[^0-9.]*})
+    local arem=${1#${1%%[^0-9.]*}} brem=${2#${2%%[^0-9.]*}}
+    for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
+        if ((10#${a[i]:-0} < 10#${b[i]:-0})); then
             return 1
-        else
-            unset ver_a[0]
-            ver_a=("${ver_a[@]}")
-            unset ver_b[0]
-            ver_b=("${ver_b[@]}")
+        elif ((10#${a[i]:-0} > 10#${b[i]:-0})); then
+            return 0
         fi
     done
-    return 1  # They are equal
+    if [ "$arem" '<' "$brem" ]; then
+        return 1
+    elif [ "$arem" '>' "$brem" ]; then
+        return 0
+    fi
+    return 1
 }
 
 
@@ -133,15 +135,15 @@ check_prereqs() {
     exit 1
   fi
 
-  # 2. running aufs or btrfs
-  test=`$docker_path info 2> /dev/null | grep 'Driver: '`
-  if [[ "$test" =~ [aufs|btrfs|zfs|overlay] ]] ; then : ; else
-    echo "Your Docker installation is not using a supported filesystem if we were to proceed you may have a broken install."
-    echo "aufs is the recommended filesystem you should be using (zfs/btrfs and overlay may work as well)"
-    echo "You can tell what filesystem you are using by running \"docker info\" and looking at the driver"
+  # 2. running an approved storage driver?
+  if ! $docker_path info 2> /dev/null | egrep -q '^Storage Driver: (aufs|btrfs|zfs|overlay|overlay2)$'; then
+    echo "Your Docker installation is not using a supported storage driver.  If we were to proceed you may have a broken install."
+    echo "aufs is the recommended storage driver, although zfs/btrfs/overlay and overlay2 may work as well."
+    echo "Other storage drivers are known to be problematic."
+    echo "You can tell what filesystem you are using by running \"docker info\" and looking at the 'Storage Driver' line."
     echo
-    echo "If you wish to continue anyway using your existing unsupported filesystem, "
-    echo "read the source code of launcher and figure out how to bypass this."
+    echo "If you wish to continue anyway using your existing unsupported storage driver,"
+    echo "read the source code of launcher and figure out how to bypass this check."
     exit 1
   fi
 
@@ -196,10 +198,27 @@ check_prereqs() {
     exit 1
   fi
 
+  # 7. enough space for the bootstrap on docker folder
+  folder=`$docker_path info --format '{{.DockerRootDir}}'`
+  safe_folder=${folder:-/var/lib/docker}
+  test=$(($(stat -f --format="%a*%S" $safe_folder)/1024**3 < 5))
+  if [[ $test -ne 0 ]] ; then
+    echo "You have less than 5GB of free space on the disk where $safe_folder is located. You will need more space to continue"
+    df -h $safe_folder
+    echo
+    read -p "Would you like to attempt to recover space by cleaning docker images and containers in the system?(y/N)" -n 1 -r
+    echo
+    if [[ $REPLY =~ ^[Yy]$ ]]
+    then
+      docker system prune
+      echo "If the cleanup was successful, you may try again now"
+    fi
+    exit 1
+  fi
 }
 
 
-if [ -z "$SKIP_PREREQS" ] ; then
+if [ -z "$SKIP_PREREQS" ] && [ "$command" != "cleanup" ]; then
   check_prereqs
 fi
 
@@ -244,11 +263,31 @@ set_links() {
         "require 'yaml'; puts YAML.load(STDIN.readlines.join)['links'].map{|l| '--link ' << l['link']['name'] << ':' << l['link']['alias'] << ' '}.join"`
 }
 
-set_template_info() {
-
-    templates=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
+find_templates() {
+    local templates=`cat $1 | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
       "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
 
+    local arrTemplates=${templates// / }
+
+    if [ ! -z "$templates" ]; then
+      for template in "${arrTemplates[@]}"
+      do
+        local nested_templates=$(find_templates $template)
+
+        if [ ! -z "$nested_templates" ]; then
+          templates="$templates $nested_templates"
+        fi
+      done
+
+      echo $templates
+    else
+      echo ""
+    fi
+}
+
+set_template_info() {
+    templates=$(find_templates $config_file)
+
     arrTemplates=(${templates// / })
     config_data=$(cat $config_file)
 
@@ -302,6 +341,45 @@ RUBY
       echo "YAML syntax error. Please check your containers/*.yml config files."
       exit 1
     fi
+
+    read -r -d '' labels_ruby << 'RUBY'
+    require 'yaml'
+
+    input=STDIN.readlines.join
+    # default to UTF-8 for the dbs sake
+    labels = {}
+    input.split('_FILE_SEPERATOR_').each do |yml|
+       yml.strip!
+       begin
+         labels.merge!(YAML.load(yml)['labels'] || {})
+       rescue Psych::SyntaxError => e
+        puts e
+        puts "*ERROR."
+       rescue => e
+        puts yml
+        p e
+       end
+    end
+    puts labels.map{|k,v| "-l\n#{k}=#{v}" }.join("\n")
+RUBY
+
+    raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$labels_ruby"`
+
+    labels=()
+    ok=1
+    while read i; do
+      if [ "$i" == "*ERROR." ]; then
+        ok=0
+      elif [ -n "$i" ]; then
+        labels[${#labels[@]}]=$(echo $i | sed s/{{config}}/${config}/g)
+      fi
+    done <<< "$raw"
+
+    if [ "$ok" -ne 1 ]; then
+      echo "${labels[@]}"
+      echo "YAML syntax error. Please check your containers/*.yml config files."
+      exit 1
+    fi
 }
 
 if [ -z $docker_path ]; then
@@ -458,8 +536,8 @@ run_start() {
      fi
 
      set -x
-     $docker_path run $user_args $links $attach_on_run $restart_policy "${env[@]}" -h "$hostname" \
-        -e DOCKER_HOST_IP=$docker_ip --name $config -t $ports $volumes $mac_address $docker_args \
+     $docker_path run $links $attach_on_run $restart_policy "${env[@]}" "${labels[@]}" -h "$hostname" \
+        -e DOCKER_HOST_IP="$docker_ip" --name $config -t $ports $volumes $mac_address $docker_args $user_args \
         $run_image $boot_command
 
    )
@@ -503,7 +581,7 @@ run_bootstrap() {
   echo $run_command
 
   unset ERR
-  (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 \
+  (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 \
     /bin/bash -c "$run_command") || ERR=$?
 
   unset FAILED
@@ -585,7 +663,12 @@ case "$command" in
         elif [ $LOCAL = $BASE ]; then
           echo "Updating Launcher"
           git pull || (echo 'failed to update' && exit 1)
-          exec /bin/bash $0 $@
+
+          for (( i=${#BASH_ARGV[@]}-1,j=0; i>=0,j<${#BASH_ARGV[@]}; i--,j++ ))
+          do
+            args[$j]=${BASH_ARGV[$i]}
+          done
+          exec /bin/bash $0 "${args[@]}" # $@ is empty, because of shift at the beginning. Use BASH_ARGV instead.
 
         elif [ $REMOTE = $BASE ]; then
           echo "Your version of Launcher is ahead of origin"