Add pre-flight tests
[discourse_docker.git] / launcher
CommitLineData
ace450bd 1#!/bin/bash
7e738616
S
2
3command=$1
4config=$2
8dea575c 5config_file=containers/"$config".yml
7e738616 6cidfile=cids/"$config".cid
1acce9e4 7cidbootstrap=cids/"$config"_boostrap.cid
5efded6a 8local_discourse=local_discourse
d69fe0fb 9image=samsaffron/discourse:0.1.2
52388b87 10docker_path=`which docker`
7e738616 11
80c11be3
SS
12docker_ip=`/sbin/ifconfig | \
13 grep -B1 "inet addr" | \
14 awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \
15 grep docker0 | \
16 awk -F: '{ print $3 }';`
17
18
5f803fb4 19usage () {
7e738616
S
20 echo "Usage: launcher COMMAND CONFIG"
21 echo "Commands:"
1acce9e4
SS
22 echo " start: Start/initialize a container"
23 echo " stop: Stop a running container"
24 echo " restart: Restart a container"
25 echo " destroy: Stop and remove a container"
5f803fb4 26 echo " ssh: Start a bash shell in a running container"
1acce9e4 27 echo " logs: Docker logs for container"
408a9c19 28 echo " bootstrap: Bootstrap a container for the config based on a template"
7e738616
S
29 exit 1
30}
31
a3e18d95
S
32prereqs() {
33
34 # 1. running aufs
35 test=`docker info 2> /dev/null | grep 'Driver: aufs'`
36 if [[ "$test" =~ "aufs" ]] ; then : ; else
37 echo "Your Docker installation is not using aufs"
38 echo "Device mapper and other experimental drivers are unstable"
39 echo
40 echo "Please ensure your kernel is running linux extras and aufs"
41 echo "Please follow the installation guide for Docker here: http://docs.docker.io/en/latest/installation/ubuntulinux/"
42 exit 1
43 fi
44
45 # 2. running docker 0.9+
46 test=`docker --version | grep 0.9`
47
48 if [[ "$test" =~ "0.9" ]] ; then : ; else
49 echo "Your Docker installation is old, please upgrade to 0.9.0 or up"
50 exit 1
51 fi
52
53 # 3. able to attach stderr / out / tty
54 test=`docker run -i -t --rm -a stdin -a stdout -a stderr $image echo working`
55 if [[ "$test" =~ "working" ]] ; then : ; else
56 echo "Your Docker installation is not working correctly"
57 echo
58 echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
59 exit 1
60 fi
61}
62
63prereqs
64
52388b87
SS
65install_docker() {
66
67 echo "Docker is not installed, make sure you are running on the 3.8 kernel"
68 echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following"
69 echo
70 echo "sudo apt-get update"
71 echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
72 echo "sudo reboot"
73 echo
74
75 echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\""
76 echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
77 echo "sudo apt-get update"
78 echo "sudo apt-get install lxc-docker"
79
80 exit 1
81}
82
d90671f3 83set_volumes() {
c4498636 84 volumes=`cat $config_file | docker run --rm -i -a stdout -a stdin $image ruby -e \
d90671f3
SS
85 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
86}
87
7f77c274
SS
88set_template_info() {
89
c4498636 90 templates=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
7f77c274
SS
91 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
92
93
94 arrTemplates=(${templates// / })
95 config_data=$(cat $config_file)
96
97 input="hack: true"
98
99
100 for template in "${arrTemplates[@]}"
101 do
102 [ ! -z $template ] && {
103 input="$input _FILE_SEPERATOR_ $(cat $template)"
104 }
105 done
106
107 # we always want our config file last so it takes priority
108 input="$input _FILE_SEPERATOR_ $config_data"
109
110 read -r -d '' env_ruby << 'RUBY'
111 require 'yaml'
112
113 input=STDIN.readlines.join
114 env = {}
115 input.split('_FILE_SEPERATOR_').each do |yml|
116 yml.strip!
117 begin
118 env.merge!(YAML.load(yml)['env'] || {})
119 rescue => e
120 puts yml
121 p e
122 end
123 end
4b563ee8 124 puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n")
7f77c274
SS
125RUBY
126
c4498636 127 raw=`exec echo "$input" | docker run --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
4b563ee8
SS
128
129 env=()
130 while read i; do
131 env[${#env[@]}]=$i
132 done <<< "$raw"
133
134 echo "Calculated ENV: ${env[@]}"
7f77c274
SS
135}
136
52388b87
SS
137[ -z $docker_path ] && {
138 install_docker
139}
140
5f803fb4
SS
141
142[ $# -ne 2 ] && {
143 usage
144}
145
7e738616
S
146if [ ! -e $config_file ]
147 then
148 echo "Config file was not found, ensure $config_file exists"
149 exit 1
150fi
151
5f803fb4
SS
152case "$command" in
153 bootstrap)
38c09f5e
MB
154 # Is the image available?
155 # If not, pull it here so the user is aware what's happening.
156 docker history $image >/dev/null 2>&1 || docker pull $image
93149421 157
7f77c274 158 set_template_info
93149421 159
c4498636 160 base_image=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
b9c7b50e
SS
161 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`
162
c4498636 163 update_pups=`cat $config_file | docker run --rm -i -a stdin -a stdout $image ruby -e \
b9c7b50e
SS
164 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
165
b9c7b50e
SS
166 if [[ ! X"" = X"$base_image" ]]; then
167 image=$base_image
168 fi
169
d90671f3
SS
170 set_volumes
171
2162f1d4
SS
172 rm -f $cidbootstrap
173
b9c7b50e
SS
174 run_command="cd /pups &&"
175 if [[ ! "false" = $update_pups ]]; then
176 run_command="$run_command git pull &&"
177 fi
178 run_command="$run_command /pups/bin/pups --stdin"
179
c4498636
S
180 echo $run_command
181
182 (exec echo "$input" | docker run "${env[@]}" -e DOCKER_HOST_IP=$docker_ip --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
b9c7b50e 183 /bin/bash -c "$run_command") \
2162f1d4 184 || (docker rm `cat $cidbootstrap` && rm $cidbootstrap)
9fb5f2d3 185
2162f1d4
SS
186 [ ! -e $cidbootstrap ] && echo "FAILED TO BOOTSTRAP" && exit 1
187
188 sleep 5
9fb5f2d3 189
5efded6a 190 docker commit `cat $cidbootstrap` $local_discourse/$config || echo 'FAILED TO COMMIT'
4b3aebe1 191 docker rm `cat $cidbootstrap` && rm $cidbootstrap
2162f1d4 192
2dd2e330 193 echo "Successfully bootstrapped, to startup use ./launcher start $config"
4b3aebe1 194 exit 0
5f803fb4 195 ;;
1acce9e4 196
5f803fb4
SS
197 ssh)
198 if [ ! -e $cidfile ]
199 then
200 echo "No cid found"
201 exit 1
202 else
203 cid="`cat $cidfile`"
204 address="`docker port $cid 22`"
205 split=(${address//:/ })
38c09f5e 206 exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]}
5f803fb4
SS
207 fi
208 ;;
7e738616 209
5f803fb4
SS
210 stop)
211 if [ ! -e $cidfile ]
212 then
213 echo "No cid found"
214 exit 1
215 else
216 docker stop -t 10 `cat $cidfile`
217 exit 0
218 fi
219 ;;
7e738616 220
5f803fb4 221 logs)
7e738616 222
5f803fb4
SS
223 if [ ! -e $cidfile ]
224 then
225 echo "No cid found"
226 exit 1
227 else
228 docker logs `cat $cidfile`
229 exit 0
230 fi
231 ;;
7e738616 232
5f803fb4 233 start)
7e738616 234
5f803fb4
SS
235 if [ ! -e $cidfile ]
236 then
237 echo "No cid found, creating a new container"
c4498636 238 ports=`cat $config_file | docker run --rm -i -a stdout -a stdin $image ruby -e \
36941588 239 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
d90671f3 240
7f77c274 241 set_template_info
d90671f3
SS
242 set_volumes
243
2aa2732e 244 existing=`docker ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
90506274
SS
245 if [ ! -z $existing ]
246 then
247 echo "Found an existing container by its name, recovering cidfile, please rerun"
248 echo $existing > $cidfile
249 exit 1
250 fi
251
a2d22fdf 252 docker run "${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP=$docker_ip --name $config -t --cidfile $cidfile $ports \
80c11be3
SS
253 -d $volumes $local_discourse/$config /usr/bin/runsvdir -P /etc/service
254
5f803fb4
SS
255 exit 0
256 else
90506274
SS
257 cid=`cat $cidfile`
258
259 if [ -z $cid ]
260 then
261 echo "Detected empty cid file, deleting, please re-run"
262 rm $cidfile
263 exit 1
264 fi
265
a2d22fdf 266 found=`docker ps -q -a --no-trunc | grep $cid`
90506274
SS
267 if [ -z $found ]
268 then
269 echo "Invalid cid file, deleting, please re-run"
270 rm $cidfile
271 exit 1
272 fi
273
5f803fb4
SS
274 echo "cid found, ensuring container is started"
275 docker start `cat $cidfile`
276 exit 0
277 fi
278 ;;
7e738616 279
7e738616 280
5f803fb4
SS
281 destroy)
282 if [ -e $cidfile ]
283 then
284 echo "destroying container $cidfile"
285 docker stop -t 10 `cat $cidfile`
286 docker rm `cat $cidfile` && rm $cidfile
287 exit 0
288 else
289 echo "nothing to destroy cidfile does not exist"
290 exit 1
291 fi
292 ;;
293esac
7e738616 294
5f803fb4 295usage