remove space for now
[discourse_docker.git] / launcher
1 #!/bin/bash
2
3 command=$1
4 config=$2
5 config_file=containers/"$config".yml
6 cidfile=cids/"$config".cid
7 cidbootstrap=cids/"$config"_boostrap.cid
8 local_discourse=local_discourse
9 image=samsaffron/discourse
10 docker_path=`which docker`
11
12 docker_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
19 usage () {
20 echo "Usage: launcher COMMAND CONFIG"
21 echo "Commands:"
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"
26 echo " ssh: Start a bash shell in a running container"
27 echo " logs: Docker logs for container"
28 echo " bootstrap: Bootstrap a container for the config based on a template"
29 exit 1
30 }
31
32 install_docker() {
33
34 echo "Docker is not installed, make sure you are running on the 3.8 kernel"
35 echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following"
36 echo
37 echo "sudo apt-get update"
38 echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
39 echo "sudo reboot"
40 echo
41
42 echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\""
43 echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
44 echo "sudo apt-get update"
45 echo "sudo apt-get install lxc-docker"
46
47 exit 1
48 }
49
50 set_volumes() {
51 volumes=`cat $config_file | docker run -rm -i -a stdout -a stdin $image ruby -e \
52 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"`
53 }
54
55 set_template_info() {
56
57 templates=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
58 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
59
60
61 arrTemplates=(${templates// / })
62 config_data=$(cat $config_file)
63
64 input="hack: true"
65
66
67 for template in "${arrTemplates[@]}"
68 do
69 [ ! -z $template ] && {
70 input="$input _FILE_SEPERATOR_ $(cat $template)"
71 }
72 done
73
74 # we always want our config file last so it takes priority
75 input="$input _FILE_SEPERATOR_ $config_data"
76
77 read -r -d '' env_ruby << 'RUBY'
78 require 'yaml'
79
80 input=STDIN.readlines.join
81 env = {}
82 input.split('_FILE_SEPERATOR_').each do |yml|
83 yml.strip!
84 begin
85 env.merge!(YAML.load(yml)['env'] || {})
86 rescue => e
87 puts yml
88 p e
89 end
90 end
91 puts env.map{|k,v| "-e #{k}=#{v}" }.join(" ")
92 RUBY
93
94 env=`exec echo "$input" | docker run -rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
95 echo "Calculated ENV: $env"
96 }
97
98 [ -z $docker_path ] && {
99 install_docker
100 }
101
102
103 [ $# -ne 2 ] && {
104 usage
105 }
106
107 if [ ! -e $config_file ]
108 then
109 echo "Config file was not found, ensure $config_file exists"
110 exit 1
111 fi
112
113 case "$command" in
114 bootstrap)
115
116 set_template_info
117
118 base_image=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
119 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"`
120
121 update_pups=`cat $config_file | docker run -rm -i -a stdin -a stdout $image ruby -e \
122 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"`
123
124 if [[ ! X"" = X"$base_image" ]]; then
125 image=$base_image
126 fi
127
128 set_volumes
129
130 rm -f $cidbootstrap
131
132 run_command="cd /pups &&"
133 if [[ ! "false" = $update_pups ]]; then
134 run_command="$run_command git pull &&"
135 fi
136 run_command="$run_command /pups/bin/pups --stdin"
137
138 (exec echo "$input" | docker run $env -e DOCKER_HOST_IP=$docker_ip -cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
139 /bin/bash -c "$run_command") \
140 || (docker rm `cat $cidbootstrap` && rm $cidbootstrap)
141
142 [ ! -e $cidbootstrap ] && echo "FAILED TO BOOTSTRAP" && exit 1
143
144 sleep 5
145
146 docker commit `cat $cidbootstrap` $local_discourse/$config || echo 'FAILED TO COMMIT'
147 docker rm `cat $cidbootstrap` && rm $cidbootstrap
148
149 echo "Successfully bootstrapped, to startup use ./launcher start $config"
150 exit 0
151 ;;
152
153 ssh)
154 if [ ! -e $cidfile ]
155 then
156 echo "No cid found"
157 exit 1
158 else
159 cid="`cat $cidfile`"
160 address="`docker port $cid 22`"
161 split=(${address//:/ })
162 exec ssh root@${split[0]} -p ${split[1]}
163 fi
164 ;;
165
166 stop)
167 if [ ! -e $cidfile ]
168 then
169 echo "No cid found"
170 exit 1
171 else
172 docker stop -t 10 `cat $cidfile`
173 exit 0
174 fi
175 ;;
176
177 logs)
178
179 if [ ! -e $cidfile ]
180 then
181 echo "No cid found"
182 exit 1
183 else
184 docker logs `cat $cidfile`
185 exit 0
186 fi
187 ;;
188
189 start)
190
191 if [ ! -e $cidfile ]
192 then
193 echo "No cid found, creating a new container"
194 ports=`cat $config_file | docker run -rm -i -a stdout -a stdin $image ruby -e \
195 "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
196
197 set_template_info
198 set_volumes
199
200 existing=`docker ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
201 if [ ! -z $existing ]
202 then
203 echo "Found an existing container by its name, recovering cidfile, please rerun"
204 echo $existing > $cidfile
205 exit 1
206 fi
207
208 docker run $env -e DOCKER_HOST_IP=$docker_ip -name $config -cidfile $cidfile $ports \
209 -d $volumes $local_discourse/$config /usr/bin/runsvdir -P /etc/service
210
211 exit 0
212 else
213 cid=`cat $cidfile`
214
215 if [ -z $cid ]
216 then
217 echo "Detected empty cid file, deleting, please re-run"
218 rm $cidfile
219 exit 1
220 fi
221
222 found=`docker ps -q -a -notrunc | grep $cid`
223 if [ -z $found ]
224 then
225 echo "Invalid cid file, deleting, please re-run"
226 rm $cidfile
227 exit 1
228 fi
229
230 echo "cid found, ensuring container is started"
231 docker start `cat $cidfile`
232 exit 0
233 fi
234 ;;
235
236
237 destroy)
238 if [ -e $cidfile ]
239 then
240 echo "destroying container $cidfile"
241 docker stop -t 10 `cat $cidfile`
242 docker rm `cat $cidfile` && rm $cidfile
243 exit 0
244 else
245 echo "nothing to destroy cidfile does not exist"
246 exit 1
247 fi
248 ;;
249 esac
250
251 usage