8784: Fix test for latest firefox.
[arvados.git] / tools / arvbox / bin / arvbox
1 #!/bin/sh
2
3 set -e
4
5 if ! test -d /sys/fs/cgroup ; then
6      echo "Arvbox requires cgroups to be mounted at /sys/fs/cgroup in order to use"
7      echo "Docker-in-Docker.  Older operating systems that put cgroups in other"
8      echo "places (such as /cgroup) are not supported."
9      exit 1
10 fi
11
12 if ! which docker >/dev/null 2>/dev/null ; then
13   echo "Arvbox requires Docker.  To install, run the following command as root:"
14   echo "curl -sSL https://get.docker.com/ | sh"
15   exit 1
16 fi
17
18 if test -z "$ARVBOX_DOCKER" ; then
19     if which greadlink >/dev/null 2>/dev/null ; then
20         ARVBOX_DOCKER=$(greadlink -f $(dirname $0)/../lib/arvbox/docker)
21     else
22         ARVBOX_DOCKER=$(readlink -f $(dirname $0)/../lib/arvbox/docker)
23     fi
24 fi
25
26 if test -z "$ARVBOX_CONTAINER" ; then
27     ARVBOX_CONTAINER=arvbox
28 fi
29
30 if test -z "$ARVBOX_BASE" ; then
31     ARVBOX_BASE="$HOME/.arvbox"
32 fi
33
34 if test -z "$ARVBOX_DATA" ; then
35     ARVBOX_DATA="$ARVBOX_BASE/$ARVBOX_CONTAINER"
36 fi
37
38 if test -z "$ARVADOS_ROOT" ; then
39     ARVADOS_ROOT="$ARVBOX_DATA/arvados"
40 fi
41
42 if test -z "$SSO_ROOT" ; then
43     SSO_ROOT="$ARVBOX_DATA/sso-devise-omniauth-provider"
44 fi
45
46 PG_DATA="$ARVBOX_DATA/postgres"
47 VAR_DATA="$ARVBOX_DATA/var"
48 PASSENGER="$ARVBOX_DATA/passenger"
49 GEMS="$ARVBOX_DATA/gems"
50 PIPCACHE="$ARVBOX_DATA/pip"
51 GOSTUFF="$ARVBOX_DATA/gopath"
52
53 getip() {
54     docker inspect $ARVBOX_CONTAINER | grep \"IPAddress\" | head -n1 | tr -d ' ":,\n' | cut -c10-
55 }
56
57 gethost() {
58     set +e
59     OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
60     CODE=$?
61     set -e
62     if test "$CODE" = 0 ; then
63        echo $OVERRIDE
64     else
65         getip
66     fi
67 }
68
69 updateconf() {
70     if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
71         sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
72         mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
73     else
74         mkdir -p $HOME/.config/arvados
75         cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
76 ARVADOS_API_HOST=$(gethost):8000
77 ARVADOS_API_TOKEN=
78 ARVADOS_API_HOST_INSECURE=true
79 EOF
80     fi
81 }
82
83 wait_for_arvbox() {
84     FF=/tmp/arvbox-fifo-$$
85     mkfifo $FF
86     docker logs -f $ARVBOX_CONTAINER > $FF &
87     LOGPID=$!
88     while read line ; do
89         echo $line
90         if echo $line | grep "Workbench is running at" >/dev/null ; then
91             kill $LOGPID
92         fi
93     done < $FF
94     rm $FF
95     echo
96     if test -n "$localip" ; then
97         echo "export ARVADOS_API_HOST=$localip:8000"
98     else
99         echo "export ARVADOS_API_HOST=$(gethost):8000"
100     fi
101 }
102
103 run() {
104     CONFIG=$1
105     TAG=$2
106
107     shift
108
109     need_setup=1
110
111     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
112         if test "$CONFIG" = test ; then
113             need_setup=0
114         else
115             echo "Container $ARVBOX_CONTAINER is already running"
116             exit 0
117         fi
118     fi
119
120     if test $need_setup = 1 ; then
121         if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
122             echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
123             exit 1
124         fi
125     fi
126
127     if test -n "$TAG"
128     then
129         if test $(echo $TAG | cut -c1-1) != '-' ; then
130             TAG=":$TAG"
131             shift
132         else
133             unset TAG
134         fi
135     fi
136
137     if echo "$CONFIG" | grep '^public' ; then
138         if test -n "$ARVBOX_PUBLISH_IP" ; then
139             localip=$ARVBOX_PUBLISH_IP
140         else
141             defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
142             localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
143         fi
144         iptemp=$(tempfile)
145         echo $localip > $iptemp
146         chmod og+r $iptemp
147         PUBLIC="--volume=$iptemp:/var/run/localip_override
148               --publish=80:80
149               --publish=8000:8000
150               --publish=8900:8900
151               --publish=9001:9001
152               --publish=9002:9002
153               --publish=25100:25100
154               --publish=25107:25107
155               --publish=25108:25108
156               --publish=8001:8001
157               --publish=8002:8002"
158     else
159         PUBLIC=""
160     fi
161
162     if echo "$CONFIG" | grep 'demo$' ; then
163         if test -d "$ARVBOX_DATA" ; then
164             echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
165             echo "Set ARVBOX_CONTAINER to set a different name for your demo container"
166             exit 1
167         fi
168
169         if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
170             docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
171         fi
172
173         docker run \
174                --detach \
175                --name=$ARVBOX_CONTAINER \
176                --privileged \
177                --volumes-from $ARVBOX_CONTAINER-data \
178                $PUBLIC \
179                arvados/arvbox-demo$TAG
180         updateconf
181         wait_for_arvbox
182     else
183         mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$GOSTUFF"
184
185
186         if ! test -d "$ARVADOS_ROOT" ; then
187             git clone https://github.com/curoverse/arvados.git "$ARVADOS_ROOT"
188         fi
189         if ! test -d "$SSO_ROOT" ; then
190             git clone https://github.com/curoverse/sso-devise-omniauth-provider.git "$SSO_ROOT"
191         fi
192
193         if test "$CONFIG" = test ; then
194
195             mkdir -p $VAR_DATA/test
196
197             if test "$need_setup" = 1 ; then
198                 docker run \
199                        --detach \
200                        --name=$ARVBOX_CONTAINER \
201                        --privileged \
202                        "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
203                        "--volume=$SSO_ROOT:/usr/src/sso:rw" \
204                        "--volume=$PG_DATA:/var/lib/postgresql:rw" \
205                        "--volume=$VAR_DATA:/var/lib/arvados:rw" \
206                        "--volume=$PASSENGER:/var/lib/passenger:rw" \
207                        "--volume=$GEMS:/var/lib/gems:rw" \
208                        "--volume=$PIPCACHE:/var/lib/pip:rw" \
209                        "--volume=$GOSTUFF:/var/lib/gopath:rw" \
210                        arvados/arvbox-dev$TAG \
211                        /usr/local/bin/runsvinit -svdir=/etc/test-service
212
213                 docker exec -ti \
214                        $ARVBOX_CONTAINER \
215                        /usr/local/lib/arvbox/runsu.sh \
216                        /usr/local/lib/arvbox/waitforpostgres.sh
217
218                 docker exec -ti \
219                        $ARVBOX_CONTAINER \
220                        /usr/local/lib/arvbox/runsu.sh \
221                        /var/lib/arvbox/service/sso/run-service --only-setup
222
223                 docker exec -ti \
224                        $ARVBOX_CONTAINER \
225                        /usr/local/lib/arvbox/runsu.sh \
226                        /var/lib/arvbox/service/api/run-service --only-setup
227             fi
228
229             docker exec -ti \
230                    $ARVBOX_CONTAINER \
231                    /usr/local/lib/arvbox/runsu.sh \
232                    /usr/src/arvados/build/run-tests.sh \
233                    --temp /var/lib/arvados/test \
234                    WORKSPACE=/usr/src/arvados \
235                    GEM_HOME=/var/lib/gems \
236                    "$@"
237         elif echo "$CONFIG" | grep 'dev$' ; then
238             docker run \
239                    --detach \
240                    --name=$ARVBOX_CONTAINER \
241                    --privileged \
242                    "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
243                    "--volume=$SSO_ROOT:/usr/src/sso:rw" \
244                    "--volume=$PG_DATA:/var/lib/postgresql:rw" \
245                    "--volume=$VAR_DATA:/var/lib/arvados:rw" \
246                    "--volume=$PASSENGER:/var/lib/passenger:rw" \
247                    "--volume=$GEMS:/var/lib/gems:rw" \
248                    "--volume=$PIPCACHE:/var/lib/pip:rw" \
249                    "--volume=$GOSTUFF:/var/lib/gopath:rw" \
250                    $PUBLIC \
251                    arvados/arvbox-dev$TAG
252             updateconf
253             wait_for_arvbox
254             echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
255         else
256             echo "Unknown configuration '$CONFIG'"
257         fi
258     fi
259 }
260
261 stop() {
262     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
263         docker stop $ARVBOX_CONTAINER
264     fi
265
266     VOLUMES=--volumes=true
267     if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
268         docker rm $VOLUMES $ARVBOX_CONTAINER
269     fi
270     if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
271         docker rm $VOLUMES $ARVBOX_CONTAINER
272     fi
273 }
274
275 build() {
276     if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ;  then
277         echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
278         exit 1
279     fi
280     if docker --version |grep " 1\.[0-9]\." ; then
281         # Docker version prior 1.10 require -f flag
282         # -f flag removed in Docker 1.12
283         FORCE=-f
284     fi
285     GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
286     docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
287     docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
288     if test "$1" = localdemo -o "$1" = publicdemo ; then
289         docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
290         docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
291     else
292         docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
293         docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
294     fi
295 }
296
297 check() {
298     case "$1" in
299         localdemo|publicdemo|dev|publicdev|test)
300             true
301             ;;
302         *)
303             echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test"
304             exit 1
305         ;;
306     esac
307 }
308
309 subcmd="$1"
310 if test -n "$subcmd" ; then
311     shift
312 fi
313 case "$subcmd" in
314     build)
315         check $@
316         build $@
317         ;;
318
319     rebuild)
320         check $@
321         NO_CACHE=--no-cache build $@
322         ;;
323
324     start|run)
325         check $@
326         run $@
327         ;;
328
329     sh*)
330         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM GEM_HOME=/var/lib/gems /bin/bash
331         ;;
332
333     pipe)
334         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
335         ;;
336
337     stop)
338         stop
339         ;;
340
341     restart)
342         check $@
343         stop
344         run $@
345         ;;
346
347     reboot)
348         check $@
349         stop
350         build $@
351         run $@
352         ;;
353
354     ip)
355         getip
356         ;;
357
358     host)
359         gethost
360         ;;
361
362     open)
363         exec xdg-open http://$(gethost)
364         ;;
365
366     status)
367         echo "Selected: $ARVBOX_CONTAINER"
368         if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
369             echo "Status: running"
370             echo "Container IP: $(getip)"
371             echo "Published host: $(gethost)"
372         else
373             echo "Status: not running"
374         fi
375         if test -d "$ARVBOX_DATA" ; then
376             echo "Data: $ARVBOX_DATA"
377         elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
378             echo "Data: $ARVBOX_CONTAINER-data"
379         else
380             echo "Data: none"
381         fi
382         ;;
383
384     reset|destroy)
385         stop
386         if test -d "$ARVBOX_DATA" ; then
387             if test "$subcmd" = destroy ; then
388                 if test "$1" != -f ; then
389                     echo "WARNING!  This will delete your entire arvbox ($ARVBOX_DATA)."
390                     echo "Use destroy -f if you really mean it."
391                     exit 1
392                 fi
393                 set -x
394                 rm -rf "$ARVBOX_DATA"
395             else
396                 if test "$1" != -f ; then
397                     echo "WARNING!  This will delete your arvbox data ($ARVBOX_DATA)."
398                     echo "Code and downloaded packages will be preserved."
399                     echo "Use reset -f if you really mean it."
400                     exit 1
401                 fi
402                 set -x
403                 rm -rf "$ARVBOX_DATA/postgres"
404                 rm -rf "$ARVBOX_DATA/var"
405             fi
406         else
407             if test "$1" != -f ; then
408                 echo "WARNING!  This will delete your data container $ARVBOX_CONTAINER-data.  Use -f if you really mean it."
409                 exit 1
410             fi
411             set -x
412             docker rm "$ARVBOX_CONTAINER-data"
413         fi
414         ;;
415
416     log)
417         if test -n "$1" ; then
418             exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM less --follow-name -R +GF "/etc/service/$1/log/main/current"
419         else
420             exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
421         fi
422         ;;
423
424     cat)
425         if test -n "$1" ; then
426             exec docker exec $ARVBOX_CONTAINER cat "$@"
427         else
428             echo "Usage: $0 $subcmd <files>"
429         fi
430         ;;
431
432     ls)
433         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
434         ;;
435
436     sv)
437         if test -n "$1" -a -n "$2" ; then
438             exec docker exec -ti $ARVBOX_CONTAINER sv "$@"
439         else
440             echo "Usage: $0 $subcmd <start|stop|restart> <service>"
441             echo "Available services:"
442             exec docker exec -ti $ARVBOX_CONTAINER ls /etc/service
443         fi
444         ;;
445
446     clone)
447         if test -n "$2" ; then
448             cp -r "$ARVBOX_BASE/$1" "$ARVBOX_BASE/$2"
449             echo "Created new arvbox $2"
450             echo "export ARVBOX_CONTAINER=$2"
451         else
452             echo "clone <from> <to>   clone an arvbox"
453             echo "available arvboxes: $(ls $ARVBOX_BASE)"
454         fi
455         ;;
456
457     *)
458         echo "Arvados-in-a-box                      http://arvados.org"
459         echo
460         echo "build   <config>      build arvbox Docker image"
461         echo "rebuild <config>      build arvbox Docker image, no layer cache"
462         echo "start|run <config> [tag]  start $ARVBOX_CONTAINER container"
463         echo "open       open arvbox workbench in a web browser"
464         echo "shell      enter arvbox shell"
465         echo "ip         print arvbox docker container ip address"
466         echo "host       print arvbox published host"
467         echo "status     print some information about current arvbox"
468         echo "stop       stop arvbox container"
469         echo "restart <config>  stop, then run again"
470         echo "reboot  <config>  stop, build arvbox Docker image, run"
471         echo "reset      delete arvbox arvados data (be careful!)"
472         echo "destroy    delete all arvbox code and data (be careful!)"
473         echo "log <service> tail log of specified service"
474         echo "ls <options>  list directories inside arvbox"
475         echo "cat <files>   get contents of files inside arvbox"
476         echo "pipe       run a bash script piped in from stdin"
477         echo "sv <start|stop|restart> <service> change state of service inside arvbox"
478         echo "clone <from> <to>   clone an arvbox"
479         ;;
480 esac