9 docker_min_version
='0.9.1'
10 docker_rec_version
='0.11.0'
12 config_file
=containers
/"$config".yml
13 cidfile
=cids
/"$config".cid
14 cidbootstrap
=cids
/"$config"_boostrap.cid
15 local_discourse
=local_discourse
16 image
=samsaffron
/discourse
:0.2.0
17 docker_path
=`which docker.io || which docker`
19 docker_ip
=`/sbin/ifconfig | \
20 grep -B1 "inet addr" | \
21 awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
23 awk -F: '{ print $3 }';`
27 echo "Usage: launcher COMMAND CONFIG [--skip-prereqs]"
29 echo " start: Start/initialize a container"
30 echo " stop: Stop a running container"
31 echo " restart: Restart a container"
32 echo " destroy: Stop and remove a container"
33 echo " ssh: Start a bash shell in a running container"
34 echo " logs: Docker logs for container"
35 echo " mailtest: Test the mail settings in a container"
36 echo " bootstrap: Bootstrap a container for the config based on a template"
37 echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)"
40 echo " --skip-prereqs Don't check prerequisites"
47 IFS
=.
read -a ver_a
<<< "$1"
48 IFS
=.
read -a ver_b
<<< "$2"
50 while [[ -n $ver_a ]]; do
51 if (( ver_a
> ver_b
)); then
53 elif (( ver_b
> ver_a
)); then
62 return 1 # They are equal
67 # 1. docker daemon running?
68 test=`$docker_path info >/dev/null`
70 if [[ $?
-ne 0 ]] ; then
71 echo "Cannot connect to the docker daemon - verify it is running and you have access"
76 test=`$docker_path info 2> /dev/null | grep 'Driver: aufs'`
77 if [[ "$test" =~
"aufs" ]] ; then : ; else
78 echo "Your Docker installation is not using aufs"
79 echo "Device mapper and other experimental drivers are unstable"
81 echo "Please ensure your kernel is running linux extras and aufs"
82 echo "Please follow the installation guide for Docker here: http://docs.docker.io/en/latest/installation/ubuntulinux/"
86 # 3. running recommended docker version
87 test=($
($docker_path --version)) # Get docker version string
88 test=${test[2]//,/} # Get version alone and strip comma if exists
90 # At least minimum version
91 if compare_version
"${socker_min_version}" "${test}"; then
92 echo "ERROR: Docker version ${test} not supported, please upgrade to at least ${docker_min_version}, or recommended ${docker_rec_version}"
96 # Recommend best version
97 if compare_version
"${docker_rec_version}" "${test}"; then
98 echo "WARNING: Docker version ${test} deprecated, recommend upgrade to ${docker_rec_version} or newer."
101 # 4. able to attach stderr / out / tty
102 test=`$docker_path run -i --rm -a stdout -a stderr $image echo working`
103 if [[ "$test" =~
"working" ]] ; then : ; else
104 echo "Your Docker installation is not working correctly"
106 echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
111 if [ "$opt" != "--skip-prereqs" ] ; then
117 if [[ ! -e ~
/.ssh
/id_rsa.pub
&& ! -e ~
/.ssh
/id_dsa.pub
]] ; then
118 echo "This user has no SSH key, but a SSH key is required to access the Discourse Docker container."
119 read -p "Generate a SSH key? (Y/n) " -n 1 -r
120 if [[ $REPLY =~ ^
[Nn
]$
]] ; then
122 echo WARNING
: You may not be able to log
in to your container.
126 echo Generating SSH key
127 mkdir
-p ~
/.
ssh && ssh-keygen
-f ~
/.ssh
/id_rsa
-t rsa
-N ''
133 ssh_pub_key
="$(cat ~/.ssh/id_rsa.pub 2>/dev/null || cat ~/.ssh/id_dsa.pub)"
139 echo "Docker is not installed, make sure you are running on the 3.8 kernel"
140 echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following"
142 echo "sudo apt-get update"
143 echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
147 echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\""
148 echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
149 echo "sudo apt-get update"
150 echo "sudo apt-get install lxc-docker"
156 volumes
=`cat $config_file | $docker_path run --rm -i -a stdout -a stdin $image ruby -e \
157 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
160 set_template_info
() {
162 templates
=`cat $config_file | $docker_path run --rm -i -a stdin -a stdout $image ruby -e \
163 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
166 arrTemplates
=(${templates// / })
167 config_data
=$
(cat $config_file)
172 for template
in "${arrTemplates[@]}"
174 [ ! -z $template ] && {
175 input
="$input _FILE_SEPERATOR_ $(cat $template)"
179 # we always want our config file last so it takes priority
180 input
="$input _FILE_SEPERATOR_ $config_data"
182 read -r -d '' env_ruby
<< 'RUBY'
185 input
=STDIN.readlines.
join
187 input.
split('_FILE_SEPERATOR_').each
do |yml|
190 env.merge
!(YAML.load
(yml
)['env'] ||
{})
196 puts env.map
{|k
,v|
"-e\n#{k}=#{v}" }.
join("\n")
199 raw
=`exec echo "$input" | $docker_path run --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
208 echo "Calculated ENV: ${env[@]}"
211 [ -z $docker_path ] && {
220 if [ ! -e $config_file ]
222 echo "Config file was not found, ensure $config_file exists"
228 if [ ! -e $config_file ]; then
229 echo "Config does not exist: $config_file" >&2
232 exec scripts
/mailtest
$config_file
241 $docker_path stop
-t 10 `cat $cidfile`
249 echo "No cid found, creating a new container"
250 ports
=`cat $config_file | $docker_path run --rm -i -a stdout -a stdin $image ruby -e \
251 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
256 existing
=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
257 if [ ! -z $existing ]
259 echo "Found an existing container by its name, recovering cidfile, please rerun"
260 echo $existing > $cidfile
264 $docker_path run
"${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP
=$docker_ip --name $config -t --cidfile $cidfile $ports \
265 -d $volumes $local_discourse/$config /usr
/bin
/runsvdir
-P /etc
/service
273 echo "Detected empty cid file, deleting, please re-run"
278 found
=`$docker_path ps -q -a --no-trunc | grep $cid`
281 echo "Invalid cid file, deleting, please re-run"
286 echo "cid found, ensuring container is started"
287 $docker_path start
`cat $cidfile`
296 # Is the image available?
297 # If not, pull it here so the user is aware what's happening.
298 $docker_path history $image >/dev
/null
2>&1 ||
$docker_path pull
$image
302 base_image
=`cat $config_file | $docker_path run --rm -i -a stdin -a stdout $image ruby -e \
303 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`
305 update_pups
=`cat $config_file | $docker_path run --rm -i -a stdin -a stdout $image ruby -e \
306 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
308 if [[ ! X
"" = X
"$base_image" ]]; then
316 run_command
="cd /pups &&"
317 if [[ ! "false" = $update_pups ]]; then
318 run_command
="$run_command git pull &&"
320 run_command
="$run_command /pups/bin/pups --stdin"
324 env
=("${env[@]}" "-e" "SSH_PUB_KEY=$ssh_pub_key")
326 (exec echo "$input" |
$docker_path run
"${env[@]}" -e DOCKER_HOST_IP
=$docker_ip --cidfile $cidbootstrap -i -a stdin
-a stdout
-a stderr
$volumes $image \
327 /bin
/bash
-c "$run_command") \
328 ||
($docker_path rm `cat $cidbootstrap` && rm $cidbootstrap)
330 [ ! -e $cidbootstrap ] && echo "FAILED TO BOOTSTRAP" && exit 1
334 $docker_path commit
`cat $cidbootstrap` $local_discourse/$config ||
echo 'FAILED TO COMMIT'
335 $docker_path rm `cat $cidbootstrap` && rm $cidbootstrap
341 echo "Successfully bootstrapped, to startup use ./launcher start $config"
357 address
="`$docker_path port $cid 22`"
358 split=(${address//:/ })
359 exec ssh -o StrictHostKeyChecking
=no root@
${split[0]} -p ${split[1]}
375 $docker_path logs
`cat $cidfile`
394 echo "Stopping old container"
395 $docker_path stop
-t 10 `cat $cidfile`
402 $docker_path rm `cat $cidfile` && rm $cidfile
413 echo "destroying container $cidfile"
414 $docker_path stop
-t 10 `cat $cidfile`
415 $docker_path rm `cat $cidfile` && rm $cidfile
418 echo "nothing to destroy cidfile does not exist"