Merge pull request #100 from wmark/fix-launcher
[discourse_docker.git] / launcher
old mode 100755 (executable)
new mode 100644 (file)
index 8f72682..3bf9f8d
--- a/launcher
+++ b/launcher
@@ -6,21 +6,35 @@ opt=$3
 
 cd "$(dirname "$0")"
 
-docker_min_version='0.9.1'
-docker_rec_version='0.11.1'
+docker_min_version='1.2.0'
+docker_rec_version='1.2.0'
 
 config_file=containers/"$config".yml
 cidfile=cids/"$config".cid
 cidbootstrap=cids/"$config"_boostrap.cid
 local_discourse=local_discourse
-image=samsaffron/discourse:1.0.3
+image=samsaffron/discourse:1.0.5
 docker_path=`which docker.io || which docker`
 
-docker_ip=`/sbin/ifconfig | \
-                grep -B1 "inet addr" | \
-                awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
-                grep docker0 | \
-                awk -F: '{ print $3 }';`
+if [ "${SUPERVISED}" = "true" ]; then
+  restart_policy="--restart=no"
+  attach_on_start="-a"
+  attach_on_run="-a stdout -a stderr"
+else
+  attach_on_run="-d"
+fi
+
+if [ -x "$(which ip 2>/dev/null)" ]; then
+  docker_ip=`ip addr show docker0 | \
+                  grep 'inet ' | \
+                  awk '{ split($2,a,"/"); print a[1] }';`
+else
+  docker_ip=`ifconfig | \
+                  grep -B1 "inet addr" | \
+                  awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
+                  grep docker0 | \
+                  awk -F: '{ print $3 }';`
+fi
 
 
 usage () {
@@ -73,11 +87,11 @@ prereqs() {
     exit 1
   fi
 
-  # 2. running aufs 
-  test=`$docker_path info 2> /dev/null | grep 'Driver: aufs'`
-  if [[ "$test" =~ "aufs" ]] ; then : ; else
-    echo "Your Docker installation is not using aufs, in the past we have had issues with it"
-    echo "If you are unable to bootstrap your image (or stop it) please report the issue at:"
+  # 2. running aufs or btrfs
+  test=`$docker_path info 2> /dev/null | grep 'Driver: '`
+  if [[ "$test" =~ [aufs|btrfs] ]] ; then : ; else
+    echo "Your Docker installation is not using the recommended AuFS (union filesystem) and may be unstable."
+    echo "If you are unable to bootstrap / stop your image please report the issue at:"
     echo "https://meta.discourse.org/t/discourse-docker-installation-without-aufs/15639"
   fi
 
@@ -113,24 +127,41 @@ if [ "$opt" != "--skip-prereqs" ] ; then
 fi
 
 get_ssh_pub_key() {
+  local ${ssh_key_locations}
+  ssh_key_locations=(
+    ~/.ssh/id_ed25519.pub
+    ~/.ssh/id_ecdsa.pub
+    ~/.ssh/id_rsa.pub
+    ~/.ssh/id_dsa.pub
+    ~core/.ssh/authorized_keys
+  )
+
+  local $keyfile
+  for keyfile in "${ssh_key_locations[@]}"; do
+    if [[ -e ${keyfile} ]] ; then
+      ssh_pub_key="$(cat ${keyfile})"
+      return 0
+    fi
+  done
+
   if tty -s ; then
-    if [[ ! -e ~/.ssh/id_rsa.pub && ! -e ~/.ssh/id_dsa.pub ]] ; then
-      echo "This user has no SSH key, but a SSH key is required to access the Discourse Docker container."
-      read -p "Generate a SSH key? (Y/n) " -n 1 -r
-      if [[ $REPLY =~ ^[Nn]$ ]] ; then
-        echo
-        echo WARNING: You may not be able to log in to your container.
-        echo
-      else
-        echo
-        echo Generating SSH key
-        mkdir -p ~/.ssh && ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
-        echo
-      fi
+    echo "This user has no SSH key, but a SSH key is required to access the Discourse Docker container."
+    read -p "Generate a SSH key? (Y/n) " -n 1 -r
+    if [[ $REPLY =~ ^[Nn]$ ]] ; then
+      echo
+      echo WARNING: You may not be able to log in to your container.
+      echo
+    else
+      echo
+      echo Generating SSH key
+      mkdir -p ~/.ssh && ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
+      echo
+      ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)"
+      return 0
     fi
   fi
 
-  ssh_pub_key="$(cat ~/.ssh/id_rsa.pub 2>/dev/null || cat ~/.ssh/id_dsa.pub)"
+  return 1
 }
 
 
@@ -152,11 +183,47 @@ install_docker() {
   exit 1
 }
 
+host_run() {
+  read -r -d '' env_ruby << 'RUBY'
+  require 'yaml'
+
+  input = STDIN.readlines.join
+  yaml = YAML.load(input)
+
+  if host_run = yaml['host_run']
+    params = yaml['params'] || {}
+    host_run.each do |run|
+      params.each do |k,v|
+        run = run.gsub("$#{k}", v)
+      end
+      STDOUT.write "#{run}--SEP--"
+    end
+  end
+RUBY
+
+  host_run=`cat $config_file | $docker_path run --rm -i -a stdout -a stdin $image ruby -e "$env_ruby"`
+
+  while [ "$host_run" ] ; do
+    iter=${host_run%%--SEP--*}
+    echo
+    echo "Host run: $iter"
+    $iter || exit 1
+    echo
+    host_run="${host_run#*--SEP--}"
+  done
+}
+
+
 set_volumes() {
   volumes=`cat $config_file | $docker_path 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_links() {
+    links=`cat $config_file | $docker_path run --rm -i -a stdout -a stdin $image ruby -e \
+        "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 --rm -i -a stdin -a stdout $image ruby -e \
@@ -245,7 +312,7 @@ if compare_version "1.2.0" "$docker_version"; then
   echo "We recommend you upgrade docker, the version you are running has no restart policies, on reboot your container may not start up"
   restart_policy=""
 else
-  restart_policy="--restart=always "
+  restart_policy=${restart_policy:---restart=always}
 fi
 
 
@@ -269,6 +336,8 @@ run_stop(){
 
 run_start(){
 
+  host_run
+
   if [ ! -e $cidfile ]
      then
        echo "No cid found, creating a new container"
@@ -277,6 +346,7 @@ run_start(){
 
        set_template_info
        set_volumes
+       set_links
 
        existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
        if [ ! -z $existing ]
@@ -286,13 +356,8 @@ run_start(){
          exit 1
        fi
 
-       run="run"
-       if [ -n "${restart_policy}" ]; then
-          run="$run $restart_policy"
-       fi
-
-       $docker_path $run "${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP=$docker_ip --name $config -t --cidfile $cidfile $ports \
-                  -d $volumes $local_discourse/$config /sbin/runit
+       $docker_path run $links $attach_on_run $restart_policy "${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP=$docker_ip --name $config -t --cidfile $cidfile $ports \
+                  $volumes $local_discourse/$config /sbin/boot
 
        exit 0
      else
@@ -314,13 +379,16 @@ run_start(){
        fi
 
        echo "cid found, ensuring container is started"
-       $docker_path start `cat $cidfile`
+       $docker_path start $attach_on_start `cat $cidfile`
        exit 0
   fi
 
 }
 
 run_bootstrap(){
+
+  host_run
+
   get_ssh_pub_key
 
   # Is the image available?
@@ -340,6 +408,7 @@ run_bootstrap(){
   fi
 
   set_volumes
+  set_links
 
   rm -f $cidbootstrap
 
@@ -353,7 +422,7 @@ run_bootstrap(){
 
   env=("${env[@]}" "-e" "SSH_PUB_KEY=$ssh_pub_key")
 
-  (exec echo "$input" | $docker_path run "${env[@]}" -e DOCKER_HOST_IP=$docker_ip --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
+  (exec echo "$input" | $docker_path run $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)