inject env from the outside
[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 bootstrappd, to starup 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 docker run $env -e DOCKER_HOST_IP=$docker_ip -name $config -cidfile $cidfile $ports \
201 -d $volumes $local_discourse/$config /usr/bin/runsvdir -P /etc/service
202
203 exit 0
204 else
205 echo "cid found, ensuring container is started"
206 docker start `cat $cidfile`
207 exit 0
208 fi
209 ;;
210
211
212 destroy)
213 if [ -e $cidfile ]
214 then
215 echo "destroying container $cidfile"
216 docker stop -t 10 `cat $cidfile`
217 docker rm `cat $cidfile` && rm $cidfile
218 exit 0
219 else
220 echo "nothing to destroy cidfile does not exist"
221 exit 1
222 fi
223 ;;
224 esac
225
226 usage