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