Pin uglify-js to 2.x for now
[discourse_docker.git] / launcher
index 02687299951a029d2ebff763b22ca258e24e3698..61b22ab6da74949a6d29afd8f6d91085dac12ab9 100755 (executable)
--- a/launcher
+++ b/launcher
@@ -7,7 +7,7 @@ usage () {
   echo "    stop:       Stop a running container"
   echo "    restart:    Restart a container"
   echo "    destroy:    Stop and remove a container"
-  echo "    enter:      Use nsenter to get a shell into a container"
+  echo "    enter:      Open a shell to run commands inside the container"
   echo "    logs:       View the Docker logs for a container"
   echo "    bootstrap:  Bootstrap a container for the config based on a template"
   echo "    rebuild:    Rebuild a container (destroy old, bootstrap, start new)"
@@ -16,6 +16,7 @@ usage () {
   echo "Options:"
   echo "    --skip-prereqs             Don't check launcher prerequisites"
   echo "    --docker-args              Extra arguments to pass when running docker"
+  echo "    --skip-mac-address         Don't assign a mac address"
   exit 1
 }
 
@@ -25,9 +26,14 @@ user_args=""
 
 while [ ${#} -gt 0 ]; do
   case "${1}" in
-
+  --debug)
+    DEBUG="1"
+    ;;
   --skip-prereqs)
-    SKIP_PREREQ="1"
+    SKIP_PREREQS="1"
+    ;;
+  --skip-mac-address)
+    SKIP_MAC_ADDRESS="1"
     ;;
   --docker-args)
     user_args="$2"
@@ -50,15 +56,15 @@ fi
 
 cd "$(dirname "$0")"
 
-docker_min_version='1.6.0'
-docker_rec_version='1.6.0'
+docker_min_version='1.8.0'
+docker_rec_version='1.8.0'
 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.0.17
+image=discourse/discourse:1.3.10
 docker_path=`which docker.io || which docker`
 git_path=`which git`
 
@@ -108,10 +114,7 @@ compare_version() {
 
 install_docker() {
   echo "Docker is not installed, you will need to install Docker in order to run Launcher"
-  echo "Please visit https://docs.docker.com/installation/ for instructions on how to do this for your system"
-  echo
-  echo "If you are running a recent Ubuntu Server, try the following:"
-  echo "sudo apt-get install docker-engine"
+  echo "See https://docs.docker.com/installation/"
   exit 1
 }
 
@@ -241,11 +244,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)
 
@@ -299,6 +322,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[@]}]=$i
+      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
@@ -449,9 +511,15 @@ run_start() {
      # docker added more hostname rules
      hostname=${hostname//_/-}
 
+
+     if [ -z "$SKIP_MAC_ADDRESS" ] ; then
+      mac_address="--mac-address $($docker_path run $user_args -i --rm -a stdout -a stderr $image /bin/sh -c "echo $hostname | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'")"
+     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 $docker_args $run_image $boot_command
+     $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
 
    )
    exit 0
@@ -493,11 +561,31 @@ run_bootstrap() {
 
   echo $run_command
 
-  (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") \
-     || ($docker_path rm `cat $cidbootstrap` && rm $cidbootstrap)
+  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 \
+    /bin/bash -c "$run_command") || ERR=$?
+
+  unset FAILED
+  # magic exit code that indicates a retry
+  if [[ "$ERR" == 77 ]]; then
+    $docker_path rm `cat $cidbootstrap`
+    rm $cidbootstrap
+    exit 77
+  elif [[ "$ERR" > 0 ]]; then
+    FAILED=TRUE
+  fi
+
+  if [[ $FAILED = "TRUE" ]]; then
+    if [[ ! -z "$DEBUG" ]]; then
+      $docker_path commit `cat $cidbootstrap` $local_discourse/$config-debug || echo 'FAILED TO COMMIT'
+      echo "** DEBUG ** Maintaining image for diagnostics $local_discourse/$config-debug"
+    fi
 
-  [ ! -e $cidbootstrap ] && echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one" && exit 1
+    $docker_path rm `cat $cidbootstrap`
+    rm $cidbootstrap
+    echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one"
+    exit 1
+  fi
 
   sleep 5
 
@@ -556,7 +644,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"