Add support for detecting & pulling in DSA key
[discourse_docker.git] / launcher
index 7b107a1974a41a3b0331c4f790f1b4a4a8bf80d9..a1140d4ec65017e6f73dc84b169c2cf5b48c4668 100755 (executable)
--- a/launcher
+++ b/launcher
@@ -6,7 +6,7 @@ config_file=containers/"$config".yml
 cidfile=cids/"$config".cid
 cidbootstrap=cids/"$config"_boostrap.cid
 local_discourse=local_discourse
-image=samsaffron/discourse
+image=samsaffron/discourse:0.1.2
 docker_path=`which docker`
 
 docker_ip=`/sbin/ifconfig | \
@@ -29,6 +29,61 @@ usage () {
   exit 1
 }
 
+prereqs() {
+
+  # 1. running aufs
+  test=`docker info 2> /dev/null | grep 'Driver: aufs'`
+  if [[ "$test" =~ "aufs" ]] ; then : ; else
+    echo "Your Docker installation is not using aufs"
+    echo "Device mapper and other experimental drivers are unstable"
+    echo
+    echo "Please ensure your kernel is running linux extras and aufs"
+    echo "Please follow the installation guide for Docker here: http://docs.docker.io/en/latest/installation/ubuntulinux/"
+    exit 1
+  fi
+
+  # 2. running docker 0.9+
+  test=`docker --version | grep 0.9`
+
+  if [[ "$test" =~ "0.9" ]] ; then : ; else
+    echo "Your Docker installation is old, please upgrade to 0.9.0 or up"
+    exit 1
+  fi
+
+  # 3. able to attach stderr / out / tty
+  test=`docker run -i --rm -a stdin -a stdout -a stderr $image echo working`
+  if [[ "$test" =~ "working" ]] ; then : ; else
+    echo "Your Docker installation is not working correctly"
+    echo
+    echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
+    exit 1
+  fi
+}
+
+prereqs
+
+get_ssh_pub_key() {
+  if tty -s ; then
+    if [[ ! -e ~/.ssh/id_rsa.pub && ! -e ~/.ssh/id_dsa.pub ]] ; then
+      echo You have no SSH key associated to this profile
+      echo "(This will allow you ssh access into your container)"
+      read -p "Generate SSH key at ~/.ssh/id_rsa.pub? (y/N) " -n 1 -r
+      if [[ $REPLY =~ ^[Yy]$ ]] ; then
+        echo
+        echo Generating SSH key
+        mkdir -p ~/.ssh && ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
+      else
+        echo
+        echo WARNING: You may not be able to log in to your container.
+        echo
+      fi
+    fi
+  fi
+
+  ssh_pub_key="$(cat ~/.ssh/id_rsa.pub 2>/dev/null || cat ~/.ssh/id_dsa.pub)"
+}
+
+
 install_docker() {
 
   echo "Docker is not installed, make sure you are running on the 3.8 kernel"
@@ -48,13 +103,13 @@ install_docker() {
 }
 
 set_volumes() {
-  volumes=`cat $config_file | docker run -rm -i -a stdout -a stdin $image ruby -e \
+  volumes=`cat $config_file | docker run --rm -i -a stdout -a stdin $image ruby -e \
         "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
 }
 
 set_template_info() {
 
-    templates=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
+    templates=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
       "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
 
 
@@ -88,11 +143,17 @@ set_template_info() {
         p e
        end
     end
-    puts env.map{|k,v| "-e #{k}=#{v}" }.join(" ")
+    puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n")
 RUBY
 
-    env=`exec echo "$input" | docker run -rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
-    echo "Calculated ENV: $env"
+    raw=`exec echo "$input" | docker run --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
+
+    env=()
+    while read i; do
+      env[${#env[@]}]=$i
+    done <<< "$raw"
+
+    echo "Calculated ENV: ${env[@]}"
 }
 
 [ -z $docker_path ] && {
@@ -110,15 +171,80 @@ if [ ! -e $config_file ]
     exit 1
 fi
 
+
+run_stop(){
+  if [ ! -e $cidfile ]
+     then
+       echo "No cid found"
+       exit 1
+     else
+       docker stop -t 10 `cat $cidfile`
+  fi
+}
+
+run_start(){
+
+  if [ ! -e $cidfile ]
+     then
+       echo "No cid found, creating a new container"
+       ports=`cat $config_file | docker run --rm -i -a stdout -a stdin $image ruby -e \
+              "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
+
+       set_template_info
+       set_volumes
+
+       existing=`docker ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
+       if [ ! -z $existing ]
+       then
+         echo "Found an existing container by its name, recovering cidfile, please rerun"
+         echo $existing > $cidfile
+         exit 1
+       fi
+
+       docker run "${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP=$docker_ip --name $config -t --cidfile $cidfile $ports \
+                  -d $volumes $local_discourse/$config /usr/bin/runsvdir -P /etc/service
+
+       exit 0
+     else
+       cid=`cat $cidfile`
+
+       if [ -z $cid ]
+       then
+         echo "Detected empty cid file, deleting, please re-run"
+         rm $cidfile
+         exit 1
+       fi
+
+       found=`docker ps -q -a --no-trunc | grep $cid`
+       if [ -z $found ]
+       then
+         echo "Invalid cid file, deleting, please re-run"
+         rm $cidfile
+         exit 1
+       fi
+
+       echo "cid found, ensuring container is started"
+       docker start `cat $cidfile`
+       exit 0
+  fi
+
+}
+
 case "$command" in
   bootstrap)
 
+      get_ssh_pub_key
+
+      # Is the image available?
+      # If not, pull it here so the user is aware what's happening.
+      docker history $image >/dev/null 2>&1 || docker pull $image
+
       set_template_info
 
-      base_image=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
+      base_image=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
         "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`
 
-      update_pups=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
+      update_pups=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
         "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
 
       if [[ ! X"" = X"$base_image" ]]; then
@@ -135,7 +261,11 @@ case "$command" in
       fi
       run_command="$run_command /pups/bin/pups --stdin"
 
-      (exec echo "$input" | docker run $env -e DOCKER_HOST_IP=$docker_ip -cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
+      echo $run_command
+
+      env=("${env[@]}" "-e" "SSH_PUB_KEY=\"$ssh_pub_key\"")
+
+      (exec echo "$input" | docker run "${env[@]}" -e DOCKER_HOST_IP=$docker_ip --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
          /bin/bash -c "$run_command") \
          || (docker rm `cat $cidbootstrap` && rm $cidbootstrap)
 
@@ -159,19 +289,13 @@ case "$command" in
            cid="`cat $cidfile`"
            address="`docker port $cid 22`"
            split=(${address//:/ })
-           exec ssh root@${split[0]} -p ${split[1]}
+           exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]}
       fi
       ;;
 
   stop)
-      if [ ! -e $cidfile ]
-         then
-           echo "No cid found"
-           exit 1
-         else
-           docker stop -t 10 `cat $cidfile`
-           exit 0
-      fi
+      run_stop
+      exit 0
       ;;
 
   logs)
@@ -186,51 +310,15 @@ case "$command" in
       fi
       ;;
 
-  start)
-
-      if [ ! -e $cidfile ]
-         then
-           echo "No cid found, creating a new container"
-           ports=`cat $config_file | docker run -rm -i -a stdout -a stdin $image ruby -e \
-                  "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
-
-           set_template_info
-           set_volumes
-
-           existing=`docker ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
-           if [ ! -z $existing ]
-           then
-             echo "Found an existing container by its name, recovering cidfile, please rerun"
-             echo $existing > $cidfile
-             exit 1
-           fi
-
-           docker run $env -e DOCKER_HOST_IP=$docker_ip -name $config -cidfile $cidfile $ports \
-                      -d $volumes $local_discourse/$config /usr/bin/runsvdir -P /etc/service
+  restart)
+      run_stop
+      run_start
+      exit 0
+      ;;
 
-           exit 0
-         else
-           cid=`cat $cidfile`
-
-           if [ -z $cid ]
-           then
-             echo "Detected empty cid file, deleting, please re-run"
-             rm $cidfile
-             exit 1
-           fi
-
-           found=`docker ps -q -a -notrunc | grep $cid`
-           if [ -z $found ]
-           then
-             echo "Invalid cid file, deleting, please re-run"
-             rm $cidfile
-             exit 1
-           fi
-
-           echo "cid found, ensuring container is started"
-           docker start `cat $cidfile`
-           exit 0
-      fi
+  start)
+      run_start
+      exit 0
       ;;