Incorporating comments from code review (refs #2438, refs #2291)
[arvados.git] / docker / arvdock
1 #!/bin/bash
2
3 ENABLE_SSH=false
4
5 function usage {
6     echo >&2
7     echo >&2 "usage: $0 (start|stop|restart|test) [options]"
8     echo >&2
9     echo >&2 "$0 start/stop/restart options:"
10     echo >&2 "  -d [port], --doc[=port]        Documentation server (default port 9898)"
11     echo >&2 "  -w [port], --workbench[=port]  Workbench server (default port 9899)"
12     echo >&2 "  -s [port], --sso[=port]        SSO server (default port 9901)"
13     echo >&2 "  -a [port], --api[=port]        API server (default port 9900)"
14     echo >&2 "  -k, --keep                     Keep servers"
15     echo >&2 "  --ssh                          Enable SSH access to server containers"
16     echo >&2 "  -h, --help                     Display this help and exit"
17     echo >&2
18     echo >&2 "  If no options are given, the action is applied to all servers."
19     echo >&2
20     echo >&2 "$0 test [testname] [testname] ..."
21     echo >&2 "  By default, all tests are run."
22 }
23
24 function ip_address {
25     local container=$1
26     echo `docker inspect $container  |grep IPAddress |cut -f4 -d\"`
27 }
28
29 function start_container {
30     local args="-d -i -t"
31     if [[ "$1" != '' ]]; then
32       local port="$1"
33       args="$args -p $port"
34     fi
35     if [[ "$2" != '' ]]; then
36       local name="$2"
37       args="$args -name $name"
38     fi
39     if [[ "$3" != '' ]]; then
40       local volume="$3"
41       args="$args -v $volume"
42     fi
43     if [[ "$4" != '' ]]; then
44       local link="$4"
45       args="$args -link $link"
46     fi
47     local image=$5
48
49     if $ENABLE_SSH
50     then
51       args="$args -e ENABLE_SSH=$ENABLE_SSH"
52     fi
53
54     `docker ps |grep -P "$name[^/]" -q`
55     if [[ "$?" == "0" ]]; then
56       echo "You have a running container with name $name -- skipping."
57       return
58     fi
59
60     # Remove any existing container by this name.
61     docker rm "$name" 2>/dev/null
62
63     echo "Starting container:"
64     echo "  docker run $args $image"
65     container=`docker run $args $image`
66     if [[ "$?" != "0" ]]; then
67       echo "Unable to start container"
68       exit 1
69     fi
70     if $ENABLE_SSH
71     then
72       ip=$(ip_address $container )
73       echo
74       echo "You can ssh into the container with:"
75       echo
76       echo "    ssh root@$ip"
77       echo
78     fi
79 }
80
81 declare -a keep_volumes
82
83 # Initialize the global `keep_volumes' array. If any keep volumes
84 # already appear to exist (mounted volumes with a top-level "keep"
85 # directory), use them; create temporary volumes if necessary.
86 #
87 function make_keep_volumes () {
88     # Mount a keep volume if we don't already have one
89     for mountpoint in $(cut -d ' ' -f 2 /proc/mounts); do
90       if [[ -d "$mountpoint/keep" && "$mountpoint" != "/" ]]; then
91         keep_volumes+=($mountpoint)
92       fi
93     done
94
95     # Create any keep volumes that do not yet exist.
96     while [ ${#keep_volumes[*]} -lt 2 ]
97     do
98         new_keep=$(mktemp -d)
99         echo >&2 "mounting 512M tmpfs keep volume in $new_keep"
100         sudo mount -t tmpfs -o size=512M tmpfs $new_keep
101         mkdir $new_keep/keep
102         keep_volumes+=($new_keep)
103     done
104 }
105
106 function do_start {
107     local start_doc=false
108     local start_sso=false
109     local start_api=false
110     local start_workbench=false
111     local start_keep=false
112
113     # NOTE: This requires GNU getopt (part of the util-linux package on Debian-based distros).
114     local TEMP=`getopt -o d::s::a::w::kh \
115                   --long doc::,sso::,api::,workbench::,keep,help,ssh \
116                   -n "$0" -- "$@"`
117
118     if [ $? != 0 ] ; then echo "Use -h for help"; exit 1 ; fi
119
120     # Note the quotes around `$TEMP': they are essential!
121     eval set -- "$TEMP"
122
123     while [ $# -ge 1 ]
124     do
125         case $1 in
126             -d | --doc)
127                 case "$2" in
128                     "") start_doc=9898; shift 2 ;;
129                     *)  start_doc=$2; shift 2 ;;
130                 esac
131                 ;;
132             -s | --sso)
133                 case "$2" in
134                     "") start_sso=9901; shift 2 ;;
135                     *)  start_sso=$2; shift 2 ;;
136                 esac
137                 ;;
138             -a | --api)
139                 case "$2" in
140                     "") start_api=9900; shift 2 ;;
141                     *)  start_api=$2; shift 2 ;;
142                 esac
143                 ;;
144             -w | --workbench)
145                 case "$2" in
146                     "") start_workbench=9899; shift 2 ;;
147                     *)  start_workbench=$2; shift 2 ;;
148                 esac
149                 ;;
150             -k | --keep )
151                 start_keep=true
152                 shift
153                 ;;
154             --ssh)
155                 # ENABLE_SSH is a global variable
156                 ENABLE_SSH=true
157                 shift
158                 ;;
159             --)
160                 shift
161                 break
162                 ;;
163             *)
164                 usage
165                 exit 1
166                 ;;
167         esac
168     done
169
170     # If no options were selected, then start all servers.
171     if [[ $start_doc == false &&
172           $start_sso == false &&
173           $start_api == false &&
174           $start_workbench == false &&
175           $start_keep == false ]]
176     then
177         start_doc=9898
178         start_sso=9901
179         start_api=9900
180         start_workbench=9899
181         start_keep=true
182     fi
183
184     if [[ $start_doc != false ]]
185     then
186         start_container "9898:80" "doc_server" '' '' "arvados/doc"
187     fi
188
189     if [[ $start_sso != false ]]
190     then
191         start_container "9901:443" "sso_server" '' '' "arvados/sso"
192     fi
193
194     if [[ $start_api != false ]]
195     then
196         start_container "9900:443" "api_server" '' "sso_server:sso" "arvados/api"
197     fi
198
199     if [[ $start_workbench != false ]]
200     then
201         start_container "9899:80" "workbench_server" '' "api_server:api" "arvados/workbench"
202     fi
203
204     if [[ $start_keep != false ]]
205     then
206         # create `keep_volumes' array with a list of keep mount points
207         # remove any stale metadata from those volumes before starting them
208         make_keep_volumes
209         for v in ${keep_volumes[*]}
210         do
211             [ -f $v/keep/.metadata.yml ] && sudo rm $v/keep/.metadata.yml
212         done
213         start_container "25107:25107" "keep_server_0" \
214             "${keep_volumes[0]}:/dev/keep-0" \
215             "api_server:api" \
216             "arvados/warehouse"
217         start_container "25108:25107" "keep_server_1" \
218             "${keep_volumes[1]}:/dev/keep-0" \
219             "api_server:api" \
220             "arvados/warehouse"
221     fi
222
223     if [ -d $HOME/.config/arvados ] || mkdir -p $HOME/.config/arvados
224     then
225         cat >$HOME/.config/arvados/settings.conf <<EOF
226 ARVADOS_API_HOST=$(ip_address "api_server")
227 ARVADOS_API_HOST_INSECURE=yes
228 ARVADOS_API_TOKEN=$(cat api/generated/superuser_token)
229 EOF
230     fi
231 }
232
233 function do_stop {
234     local stop_doc=""
235     local stop_sso=""
236     local stop_api=""
237     local stop_workbench=""
238     local stop_keep=""
239
240     # NOTE: This requires GNU getopt (part of the util-linux package on Debian-based distros).
241     local TEMP=`getopt -o d::s::a::w::kh \
242                   --long doc::,sso::,api::,workbench::,keep,help,ssh \
243                   -n "$0" -- "$@"`
244
245     if [ $? != 0 ] ; then echo "Use -h for help"; exit 1 ; fi
246
247     # Note the quotes around `$TEMP': they are essential!
248     eval set -- "$TEMP"
249
250     while [ $# -ge 1 ]
251     do
252         case $1 in
253             -d | --doc)
254                 stop_doc=doc_server ; shift 2 ;;
255             -s | --sso)
256                 stop_sso=sso_server ; shift 2 ;;
257             -a | --api)
258                 stop_api=api_server ; shift 2 ;;
259             -w | --workbench)
260                 stop_workbench=workbench_server ; shift 2 ;;
261             -k | --keep )
262                 stop_keep="keep_server_0 keep_server_1" ; shift ;;
263             --ssh)
264                 shift
265                 ;;
266             --)
267                 shift
268                 break
269                 ;;
270             *)
271                 usage
272                 exit 1
273                 ;;
274         esac
275     done
276
277     # If no options were selected, then start all servers.
278     if [[ $stop_doc == "" &&
279           $stop_sso == "" &&
280           $stop_api == "" &&
281           $stop_workbench == "" &&
282           $stop_keep == "" ]]
283     then
284         stop_doc=doc_server
285         stop_sso=sso_server
286         stop_api=api_server
287         stop_workbench=workbench_server
288         stop_keep="keep_server_0 keep_server_1"
289     fi
290
291     docker stop $stop_doc $stop_sso $stop_api $stop_workbench $stop_keep \
292         2>/dev/null
293 }
294
295 function do_test {
296     local alltests
297     if [ $# -lt 1 ]
298     then
299         alltests="python-sdk api"
300     else
301         alltests="$@"
302     fi
303
304     for testname in $alltests
305     do
306         echo "testing $testname..."
307         case $testname in
308             python-sdk)
309                 do_start --api --keep --sso
310                 export ARVADOS_API_HOST=$(ip_address "api_server")
311                 export ARVADOS_API_HOST_INSECURE=yes
312                 export ARVADOS_API_TOKEN=$(cat api/generated/superuser_token)
313                 python -m unittest discover ../sdk/python
314                 ;;
315             api)
316                 docker run -t -i arvados/api \
317                     /usr/src/arvados/services/api/script/rake_test.sh
318                 ;;
319             *)
320                 echo >&2 "unknown test $testname"
321                 ;;
322         esac
323     done
324 }
325
326 if [ $# -lt 1 ]
327 then
328   usage
329   exit 1
330 fi
331
332 case $1 in
333     start)
334         shift
335         do_start $@
336         ;;
337     stop)
338         shift
339         do_stop $@
340         ;;
341     restart)
342         shift
343         do_stop $@
344         do_start $@
345         ;;
346     test)
347         shift
348         do_test $@
349         ;;
350     *)
351         usage
352         exit 1
353         ;;
354 esac