-#/bin/bash
+#!/bin/bash
command=$1
config=$2
-config_file=shared/config/"$config"/conf.yml
+config_file=containers/"$config".yml
cidfile=cids/"$config".cid
cidbootstrap=cids/"$config"_boostrap.cid
-
+local_discourse=local_discourse
image=samsaffron/discourse
+docker_path=`which docker`
-[ $# -ne 2 ] && {
+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 }';`
+
+
+usage () {
echo "Usage: launcher COMMAND CONFIG"
echo "Commands:"
echo " start: Start/initialize a container"
echo " stop: Stop a running container"
echo " restart: Restart a container"
echo " destroy: Stop and remove a container"
- echo " shell: Start a bash shell in a running container"
+ echo " ssh: Start a bash shell in a running container"
echo " logs: Docker logs for container"
- echo " bootstrap: Bootstrap a container for the config base on an image"
+ echo " bootstrap: Bootstrap a container for the config based on a template"
exit 1
}
+install_docker() {
+
+ echo "Docker is not installed, make sure you are running on the 3.8 kernel"
+ echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following"
+ echo
+ echo "sudo apt-get update"
+ echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
+ echo "sudo reboot"
+ echo
+
+ echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\""
+ echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
+ echo "sudo apt-get update"
+ echo "sudo apt-get install lxc-docker"
+
+ exit 1
+}
+
+set_volumes() {
+ 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 \
+ "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
+
+
+ arrTemplates=(${templates// / })
+ config_data=$(cat $config_file)
+
+ input="hack: true"
+
+
+ for template in "${arrTemplates[@]}"
+ do
+ [ ! -z $template ] && {
+ input="$input _FILE_SEPERATOR_ $(cat $template)"
+ }
+ done
+
+ # we always want our config file last so it takes priority
+ input="$input _FILE_SEPERATOR_ $config_data"
+
+ read -r -d '' env_ruby << 'RUBY'
+ require 'yaml'
+
+ input=STDIN.readlines.join
+ env = {}
+ input.split('_FILE_SEPERATOR_').each do |yml|
+ yml.strip!
+ begin
+ env.merge!(YAML.load(yml)['env'] || {})
+ rescue => e
+ puts yml
+ p e
+ end
+ end
+ puts env.map{|k,v| "-e #{k}=#{v}" }.join(" ")
+RUBY
+
+ env=`exec echo "$input" | docker run -rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
+ echo "Calculated ENV: $env"
+}
+
+[ -z $docker_path ] && {
+ install_docker
+}
+
+
+[ $# -ne 2 ] && {
+ usage
+}
+
if [ ! -e $config_file ]
then
echo "Config file was not found, ensure $config_file exists"
exit 1
fi
-if [ "$command" == "bootstrap" ]
- then
- docker run -cidfile $cidbootstrap -i -t -v `pwd`/shared:/shared samsaffron/discourse /shared/pups/bin/pups /$config_file
- docker commit `cat $cidbootstrap` samsaffron/discourse $config
- docker rm `cat $cidbootstrap`
- rm $cidbootstrap
-fi
+case "$command" in
+ bootstrap)
-if [ "$command" == "shell" ]
- then
+ set_template_info
- if [ ! -e $cidfile ]
- then
- echo "No cid found"
- exit 1
- else
- docker attach `cat $cidfile`
- exit 0
- fi
-fi
+ 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']"`
-if [ "$command" == "stop" ]
- then
+ 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 [ ! -e $cidfile ]
- then
- echo "No cid found"
- exit 1
- else
- docker stop -t 10 `cat $cidfile`
- exit 0
- fi
-fi
+ if [[ ! X"" = X"$base_image" ]]; then
+ image=$base_image
+ fi
-if [ "$command" == "logs" ]
- then
+ set_volumes
- if [ ! -e $cidfile ]
- then
- echo "No cid found"
- exit 1
- else
- docker logs `cat $cidfile`
- exit 0
- fi
-fi
+ rm -f $cidbootstrap
-if [ "$command" == "start" ]
- then
+ run_command="cd /pups &&"
+ if [[ ! "false" = $update_pups ]]; then
+ run_command="$run_command git pull &&"
+ fi
+ run_command="$run_command /pups/bin/pups --stdin"
- if [ ! -e $cidfile ]
- then
- echo "No cid found, creating a new container"
- docker run -cidfile $cidfile -p 22 -p 80 -p 3000 -d -v `pwd`/shared:/shared samsaffron/discourse:$config /usr/bin/runsvdir -P /etc/service
- exit 0
- else
- echo "cid found, ensuring container is started"
- docker start `cat $cidfile`
- exit 0
- fi
-fi
+ (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)
+ [ ! -e $cidbootstrap ] && echo "FAILED TO BOOTSTRAP" && exit 1
-if [ "$command" == "destroy" ]
- then
- if [ -e $cidfile ]
- then
- echo "destroying container $cidfile"
- docker stop -t 10 `cat $cidfile`
- docker rm `cat $cidfile` && rm $cidfile
- exit 0
- else
- echo "nothing to destroy cidfile does not exist"
- exit 1
- fi
-fi
+ sleep 5
+
+ docker commit `cat $cidbootstrap` $local_discourse/$config || echo 'FAILED TO COMMIT'
+ docker rm `cat $cidbootstrap` && rm $cidbootstrap
+
+ echo "Successfully bootstrapped, to startup use ./launcher start $config"
+ exit 0
+ ;;
+
+ ssh)
+ if [ ! -e $cidfile ]
+ then
+ echo "No cid found"
+ exit 1
+ else
+ cid="`cat $cidfile`"
+ address="`docker port $cid 22`"
+ split=(${address//:/ })
+ exec ssh 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
+ ;;
+
+ logs)
+
+ if [ ! -e $cidfile ]
+ then
+ echo "No cid found"
+ exit 1
+ else
+ docker logs `cat $cidfile`
+ exit 0
+ 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
+
+ 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
+ ;;
+
+
+ destroy)
+ if [ -e $cidfile ]
+ then
+ echo "destroying container $cidfile"
+ docker stop -t 10 `cat $cidfile`
+ docker rm `cat $cidfile` && rm $cidfile
+ exit 0
+ else
+ echo "nothing to destroy cidfile does not exist"
+ exit 1
+ fi
+ ;;
+esac
+
+usage