263 lines
7.0 KiB
Bash
Executable File
263 lines
7.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
command=$1
|
|
config=$2
|
|
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`
|
|
|
|
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 " ssh: Start a bash shell in a running container"
|
|
echo " logs: Docker logs for container"
|
|
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\n#{k}=#{v}" }.join("\n")
|
|
RUBY
|
|
|
|
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 ] && {
|
|
install_docker
|
|
}
|
|
|
|
|
|
[ $# -ne 2 ] && {
|
|
usage
|
|
}
|
|
|
|
if [ ! -e $config_file ]
|
|
then
|
|
echo "Config file was not found, ensure $config_file exists"
|
|
exit 1
|
|
fi
|
|
|
|
case "$command" in
|
|
bootstrap)
|
|
# 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 \
|
|
"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 \
|
|
"require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
|
|
|
|
if [[ ! X"" = X"$base_image" ]]; then
|
|
image=$base_image
|
|
fi
|
|
|
|
set_volumes
|
|
|
|
rm -f $cidbootstrap
|
|
|
|
run_command="cd /pups &&"
|
|
if [[ ! "false" = $update_pups ]]; then
|
|
run_command="$run_command git pull &&"
|
|
fi
|
|
run_command="$run_command /pups/bin/pups --stdin"
|
|
|
|
echo $run_command
|
|
|
|
(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
|
|
|
|
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 -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
|
|
;;
|
|
|
|
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[@]}" -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
|
|
;;
|
|
|
|
|
|
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
|