arvbox changes: yank Composer. Add link to documentation.
[arvados.git] / tools / arvbox / bin / arvbox
1 #!/bin/bash
2 # Copyright (C) The Arvados Authors. All rights reserved.
3 #
4 # SPDX-License-Identifier: AGPL-3.0
5
6 set -e
7
8 if ! test -d /sys/fs/cgroup ; then
9      echo "Arvbox requires cgroups to be mounted at /sys/fs/cgroup in order to use"
10      echo "Docker-in-Docker.  Older operating systems that put cgroups in other"
11      echo "places (such as /cgroup) are not supported."
12      exit 1
13 fi
14
15 if ! which docker >/dev/null 2>/dev/null ; then
16   echo "Arvbox requires Docker.  To install, run the following command as root:"
17   echo "curl -sSL https://get.docker.com/ | sh"
18   exit 1
19 fi
20
21 if test -z "$ARVBOX_DOCKER" ; then
22     set +e
23     if which greadlink >/dev/null 2>/dev/null ; then
24         ARVBOX_DOCKER=$(greadlink -f $(dirname $0)/../lib/arvbox/docker)
25     else
26         ARVBOX_DOCKER=$(readlink -f $(dirname $0)/../lib/arvbox/docker)
27     fi
28     set -e
29 fi
30
31 if test -z "$ARVBOX_CONTAINER" ; then
32     ARVBOX_CONTAINER=arvbox
33 fi
34
35 if test -z "$ARVBOX_BASE" ; then
36     ARVBOX_BASE="$HOME/.arvbox"
37 fi
38
39 if test -z "$ARVBOX_DATA" ; then
40     ARVBOX_DATA="$ARVBOX_BASE/$ARVBOX_CONTAINER"
41 fi
42
43 if test -z "$ARVADOS_ROOT" ; then
44     ARVADOS_ROOT="$ARVBOX_DATA/arvados"
45 fi
46
47 if test -z "$WORKBENCH2_ROOT" ; then
48     WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2"
49 fi
50
51 if test -z "$ARVADOS_BRANCH" ; then
52     ARVADOS_BRANCH=main
53 fi
54
55 if test -z "$WORKBENCH2_BRANCH" ; then
56     WORKBENCH2_BRANCH=main
57 fi
58
59 # Update this to the docker tag for the version on releases.
60 DEFAULT_TAG=
61
62 PG_DATA="$ARVBOX_DATA/postgres"
63 VAR_DATA="$ARVBOX_DATA/var"
64 PASSENGER="$ARVBOX_DATA/passenger"
65 GEMS="$ARVBOX_DATA/gems"
66 PIPCACHE="$ARVBOX_DATA/pip"
67 NPMCACHE="$ARVBOX_DATA/npm"
68 GOSTUFF="$ARVBOX_DATA/gopath"
69 RLIBS="$ARVBOX_DATA/Rlibs"
70 ARVADOS_CONTAINER_PATH="/var/lib/arvados-arvbox"
71
72 getip() {
73     docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
74 }
75
76 gethost() {
77     set +e
78     OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
79     CODE=$?
80     set -e
81     if test "$CODE" = 0 ; then
82        echo $OVERRIDE
83     else
84         getip
85     fi
86 }
87
88 getclusterid() {
89     docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix
90 }
91
92 updateconf() {
93     if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
94         sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
95         mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
96     else
97         mkdir -p $HOME/.config/arvados
98         cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
99 ARVADOS_API_HOST=$(gethost):8000
100 ARVADOS_API_TOKEN=
101 ARVADOS_API_HOST_INSECURE=true
102 EOF
103     fi
104 }
105
106 listusers() {
107     docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list
108 }
109
110 wait_for_arvbox() {
111     FF=/tmp/arvbox-fifo-$$
112     mkfifo $FF
113     docker logs -f $ARVBOX_CONTAINER > $FF &
114     LOGPID=$!
115     while read line ; do
116         if [[ $line =~ "ok: down: ready:" ]] ; then
117             kill $LOGPID
118             set +e
119             wait $LOGPID 2>/dev/null
120             set -e
121         else
122             echo $line
123         fi
124     done < $FF
125     rm $FF
126     echo
127     if test -n "$localip" ; then
128         echo "export ARVADOS_API_HOST=$localip:8000"
129     else
130         echo "export ARVADOS_API_HOST=$(gethost):8000"
131     fi
132 }
133
134 docker_run_dev() {
135     docker run \
136            "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
137            "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
138            "--volume=$PG_DATA:/var/lib/postgresql:rw" \
139            "--volume=$VAR_DATA:$ARVADOS_CONTAINER_PATH:rw" \
140            "--volume=$PASSENGER:/var/lib/passenger:rw" \
141            "--volume=$GEMS:/var/lib/arvados-arvbox/.gem:rw" \
142            "--volume=$PIPCACHE:/var/lib/pip:rw" \
143            "--volume=$NPMCACHE:/var/lib/npm:rw" \
144            "--volume=$GOSTUFF:/var/lib/gopath:rw" \
145            "--volume=$RLIBS:/var/lib/Rlibs:rw" \
146            --label "org.arvados.arvbox_config=$CONFIG" \
147            "$@"
148 }
149
150 running_config() {
151     docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
152 }
153
154 run() {
155     CONFIG=$1
156     TAG=$2
157
158     shift
159
160     need_setup=1
161
162     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
163         if [[ $(running_config) != "$CONFIG" ]] ; then
164             echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
165             return 1
166         fi
167         if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
168             need_setup=0
169         else
170             echo "Container $ARVBOX_CONTAINER is already running"
171             return 0
172         fi
173     fi
174
175     if test $need_setup = 1 ; then
176         if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
177             echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
178             return 1
179         fi
180     fi
181
182     if test -n "$TAG"
183     then
184         if test $(echo $TAG | cut -c1-1) != '-' ; then
185             TAG=":$TAG"
186             shift
187         else
188             if [[ $TAG = '-' ]] ; then
189                 shift
190             fi
191             unset TAG
192         fi
193     fi
194
195     if test -z "$TAG" -a -n "$DEFAULT_TAG"; then
196         TAG=":$DEFAULT_TAG"
197     fi
198
199     if [[ "$CONFIG" =~ ^public ]] ; then
200         if test -n "$ARVBOX_PUBLISH_IP" ; then
201             localip=$ARVBOX_PUBLISH_IP
202         else
203             defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
204             localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
205         fi
206         echo "Public arvbox will use address $localip"
207         iptemp=$(mktemp)
208         echo $localip > $iptemp
209         chmod og+r $iptemp
210         PUBLIC="--volume=$iptemp:/var/run/localip_override
211               --publish=443:443
212               --publish=3001:3001
213               --publish=8000:8000
214               --publish=8900:8900
215               --publish=9000:9000
216               --publish=9002:9002
217               --publish=9004:9004
218               --publish=25101:25101
219               --publish=8001:8001
220               --publish=8002:8002
221               --publish=4202:4202
222               --publish=45000-45020:45000-45020"
223     else
224         PUBLIC=""
225     fi
226
227     if [[ "$CONFIG" =~ demo$ ]] ; then
228         if test -d "$ARVBOX_DATA" ; then
229             echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
230             echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
231             exit 1
232         fi
233
234         if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
235             docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo$TAG /bin/true
236         fi
237
238         docker run \
239                --detach \
240                --name=$ARVBOX_CONTAINER \
241                --privileged \
242                --volumes-from $ARVBOX_CONTAINER-data \
243                --label "org.arvados.arvbox_config=$CONFIG" \
244                $PUBLIC \
245                arvados/arvbox-demo$TAG
246         updateconf
247         wait_for_arvbox
248     else
249         mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
250
251         if ! test -d "$ARVADOS_ROOT" ; then
252             git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
253             git -C "$ARVADOS_ROOT" checkout $ARVADOS_BRANCH
254         fi
255         if ! test -d "$WORKBENCH2_ROOT" ; then
256             git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
257             git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH
258         fi
259
260         if [[ "$CONFIG" = test ]] ; then
261
262             mkdir -p $VAR_DATA/test
263
264             if test "$need_setup" = 1 ; then
265                 docker_run_dev \
266                        --detach \
267                        --name=$ARVBOX_CONTAINER \
268                        --privileged \
269                        "--env=SVDIR=/etc/test-service" \
270                        arvados/arvbox-dev$TAG
271
272                 docker exec -ti \
273                        $ARVBOX_CONTAINER \
274                        /usr/local/lib/arvbox/runsu.sh \
275                        /usr/local/lib/arvbox/waitforpostgres.sh
276             fi
277
278             interactive=""
279             if [[ -z "$@" ]] ; then
280                 interactive=--interactive
281             fi
282
283             docker exec -ti \
284                    -e LINES=$(tput lines) \
285                    -e COLUMNS=$(tput cols) \
286                    -e TERM=$TERM \
287                    -e WORKSPACE=/usr/src/arvados \
288                    -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
289                    $ARVBOX_CONTAINER \
290                    /usr/local/lib/arvbox/runsu.sh \
291                    /usr/src/arvados/build/run-tests.sh \
292                    --temp $ARVADOS_CONTAINER_PATH/test \
293                    $interactive \
294                    "$@"
295         elif [[ "$CONFIG" = devenv ]] ; then
296             if [[ $need_setup = 1 ]] ; then
297                     docker_run_dev \
298                     --detach \
299                     --name=${ARVBOX_CONTAINER} \
300                     "--env=SVDIR=/etc/devenv-service" \
301                         "--volume=$HOME:$HOME:rw" \
302                     --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
303                         arvados/arvbox-dev$TAG
304             fi
305             exec docker exec --interactive --tty \
306                  -e LINES=$(tput lines) \
307                  -e COLUMNS=$(tput cols) \
308                  -e TERM=$TERM \
309                  -e "ARVBOX_HOME=$HOME" \
310                  -e "DISPLAY=$DISPLAY" \
311                  --workdir=$PWD \
312                  ${ARVBOX_CONTAINER} \
313                  /usr/local/lib/arvbox/devenv.sh "$@"
314         elif [[ "$CONFIG" =~ dev$ ]] ; then
315             docker_run_dev \
316                    --detach \
317                    --name=$ARVBOX_CONTAINER \
318                    --privileged \
319                    $PUBLIC \
320                    arvados/arvbox-dev$TAG
321             updateconf
322             wait_for_arvbox
323             echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
324             echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
325             if [[ "$(listusers)" =~ ^\{\} ]] ; then
326                 echo "No users defined, use 'arvbox adduser' to add user logins"
327             else
328                 echo "Use 'arvbox listusers' to see user logins"
329             fi
330         else
331             echo "Unknown configuration '$CONFIG'"
332         fi
333     fi
334 }
335
336 update() {
337     CONFIG=$1
338     TAG=$2
339
340     if test -n "$TAG"
341     then
342         if test $(echo $TAG | cut -c1-1) != '-' ; then
343             TAG=":$TAG"
344             shift
345         else
346             unset TAG
347         fi
348     fi
349
350     if echo "$CONFIG" | grep 'demo$' ; then
351         docker pull arvados/arvbox-demo$TAG
352     else
353         docker pull arvados/arvbox-dev$TAG
354     fi
355 }
356
357 stop() {
358     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
359         docker stop $ARVBOX_CONTAINER
360     fi
361
362     VOLUMES=--volumes=true
363     if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
364         docker rm $VOLUMES $ARVBOX_CONTAINER
365     fi
366     if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
367         docker rm $VOLUMES $ARVBOX_CONTAINER
368     fi
369 }
370
371 build() {
372     export DOCKER_BUILDKIT=1
373     if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ;  then
374         echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
375         exit 1
376     fi
377     if docker --version |grep " 1\.[0-9]\." ; then
378         # Docker version prior 1.10 require -f flag
379         # -f flag removed in Docker 1.12
380         FORCE=-f
381     fi
382     GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
383
384     set +e
385     if which greadlink >/dev/null 2>/dev/null ; then
386         LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
387     else
388         LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
389     fi
390     set -e
391
392     # Get the go version we should use for bootstrapping
393     GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'`
394
395     if test "$1" = localdemo -o "$1" = publicdemo ; then
396         BUILDTYPE=demo
397     else
398         BUILDTYPE=dev
399     fi
400
401     if test "$ARVADOS_BRANCH" = "main" ; then
402         ARVADOS_BRANCH=$GITHEAD
403     fi
404
405     docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \
406            --build-arg=go_version=$GO_VERSION \
407            --build-arg=arvados_version=$ARVADOS_BRANCH \
408            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
409            --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
410            -t arvados/arvbox-base:$GITHEAD \
411            -f "$ARVBOX_DOCKER/Dockerfile.base" \
412            "$LOCAL_ARVADOS_ROOT"
413     docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
414     docker build $NO_CACHE \
415            --build-arg=go_version=$GO_VERSION \
416            --build-arg=arvados_version=$ARVADOS_BRANCH \
417            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
418            -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
419            -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
420            "$ARVBOX_DOCKER"
421     docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
422 }
423
424 check() {
425     case "$1" in
426         localdemo|publicdemo|dev|publicdev|test|devenv)
427             true
428             ;;
429         *)
430             echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
431             exit 1
432         ;;
433     esac
434 }
435
436 subcmd="$1"
437 if test -n "$subcmd" ; then
438     shift
439 fi
440 case "$subcmd" in
441     build)
442         check $@
443         build $@
444         ;;
445
446     rebuild)
447         check $@
448         NO_CACHE=--no-cache build $@
449         ;;
450
451     start|run)
452         check $@
453         run $@
454         ;;
455
456     sh*)
457         exec docker exec --interactive --tty \
458                -e LINES=$(tput lines) \
459                -e COLUMNS=$(tput cols) \
460                -e TERM=$TERM \
461                $ARVBOX_CONTAINER /bin/bash
462         ;;
463
464     ash*)
465         exec docker exec --interactive --tty \
466                -e LINES=$(tput lines) \
467                -e COLUMNS=$(tput cols) \
468                -e TERM=$TERM \
469                -u arvbox \
470                -w /usr/src/arvados \
471                $ARVBOX_CONTAINER /bin/bash --login
472         ;;
473
474     pipe)
475         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash -
476         ;;
477
478     stop)
479         stop
480         ;;
481
482     restart)
483         check $@
484         stop
485         run $@
486         ;;
487
488     reboot)
489         check $@
490         stop
491         build $@
492         run $@
493         ;;
494
495     update)
496         check $@
497         stop
498         update $@
499         run $@
500         ;;
501
502     ip)
503         getip
504         ;;
505
506     host)
507         gethost
508         ;;
509
510     open)
511         exec xdg-open http://$(gethost)
512         ;;
513
514     status)
515         echo "Container: $ARVBOX_CONTAINER"
516         if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
517             echo "Cluster id: $(getclusterid)"
518             echo "Status: running"
519             echo "Container IP: $(getip)"
520             echo "Published host: $(gethost)"
521             echo "Workbench: https://$(gethost)"
522         else
523             echo "Status: not running"
524         fi
525         if test -d "$ARVBOX_DATA" ; then
526             echo "Data: $ARVBOX_DATA"
527         elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
528             echo "Data: $ARVBOX_CONTAINER-data"
529         else
530             echo "Data: none"
531         fi
532         ;;
533
534     reset|destroy)
535         stop
536         if test -d "$ARVBOX_DATA" ; then
537             if test "$subcmd" = destroy ; then
538                 if test "$1" != -f ; then
539                     echo "WARNING!  This will delete your entire arvbox ($ARVBOX_DATA)."
540                     echo "Use destroy -f if you really mean it."
541                     exit 1
542                 fi
543                 set -x
544                 chmod -R u+w "$ARVBOX_DATA"
545                 rm -rf "$ARVBOX_DATA"
546             else
547                 if test "$1" != -f ; then
548                     echo "WARNING!  This will delete your arvbox data ($ARVBOX_DATA)."
549                     echo "Code and downloaded packages will be preserved."
550                     echo "Use reset -f if you really mean it."
551                     exit 1
552                 fi
553                 set -x
554                 rm -rf "$ARVBOX_DATA/postgres"
555                 rm -rf "$ARVBOX_DATA/var"
556             fi
557         else
558             if test "$1" != -f ; then
559                 echo "WARNING!  This will delete your data container $ARVBOX_CONTAINER-data.  Use -f if you really mean it."
560                 exit 1
561             fi
562             set -x
563             docker rm "$ARVBOX_CONTAINER-data"
564         fi
565         ;;
566
567     log)
568         if test -n "$1" ; then
569             exec docker exec -ti -e LINES=$(tput lines) -e COLUMNS=$(tput cols) -e TERM=$TERM $ARVBOX_CONTAINER less --follow-name -R +GF "/etc/service/$1/log/main/current"
570         else
571             exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
572         fi
573         ;;
574
575     cat)
576         if test -n "$1" ; then
577             exec docker exec $ARVBOX_CONTAINER cat "$@"
578         else
579             echo "Usage: $0 $subcmd <files>"
580         fi
581         ;;
582
583     ls)
584         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
585         ;;
586
587     sv)
588         if test -n "$1" -a -n "$2" ; then
589             exec docker exec $ARVBOX_CONTAINER sv "$@"
590         else
591             echo "Usage: $0 $subcmd <start|stop|restart> <service>"
592             echo "Available services:"
593             exec docker exec $ARVBOX_CONTAINER ls /etc/service
594         fi
595         ;;
596
597     clone)
598         if test -n "$2" ; then
599             mkdir -p "$ARVBOX_BASE/$2"
600             cp -a "$ARVBOX_BASE/$1/passenger" \
601                "$ARVBOX_BASE/$1/gems" \
602                "$ARVBOX_BASE/$1/pip" \
603                "$ARVBOX_BASE/$1/npm" \
604                "$ARVBOX_BASE/$1/gopath" \
605                "$ARVBOX_BASE/$1/Rlibs" \
606                "$ARVBOX_BASE/$1/arvados" \
607                "$ARVBOX_BASE/$1/workbench2" \
608                "$ARVBOX_BASE/$2"
609             echo "Created new arvbox $2"
610             echo "export ARVBOX_CONTAINER=$2"
611         else
612             echo "clone <from> <to>   clone an arvbox"
613             echo "available arvboxes: $(ls $ARVBOX_BASE)"
614         fi
615         ;;
616
617     root-cert)
618         CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
619         if test -n "$1" ; then
620             CERT="$1"
621         fi
622         docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
623         echo "Certificate copied to $CERT"
624         ;;
625
626     psql)
627         exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados'
628         ;;
629
630     checkpoint)
631         exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec pg_dump --host=localhost --username=arvados --clean arvados_development > $ARVADOS_CONTAINER_PATH/checkpoint.sql'
632         ;;
633
634     restore)
635         exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados --quiet --file=$ARVADOS_CONTAINER_PATH/checkpoint.sql'
636         ;;
637
638     hotreset)
639         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash - <<EOF
640 sv stop api
641 sv stop controller
642 sv stop websockets
643 sv stop keepstore0
644 sv stop keepstore1
645 sv stop keepproxy
646 cd /usr/src/arvados/services/api
647 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
648 export RAILS_ENV=development
649 bin/bundle exec rake db:drop
650 rm $ARVADOS_CONTAINER_PATH/api_database_setup
651 rm $ARVADOS_CONTAINER_PATH/superuser_token
652 sv start api
653 sv start controller
654 sv start websockets
655 sv restart keepstore0
656 sv restart keepstore1
657 sv restart keepproxy
658 EOF
659         ;;
660
661     adduser)
662 if [[ -n "$2" ]] ; then
663           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
664           docker exec $ARVBOX_CONTAINER sv restart controller
665         else
666             echo "Usage: adduser <username> <email> [password]"
667         fi
668         ;;
669
670     removeuser)
671         if [[ -n "$1" ]] ; then
672           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
673           docker exec $ARVBOX_CONTAINER sv restart controller
674         else
675             echo "Usage: removeuser <username>"
676         fi
677         ;;
678
679     listusers)
680         listusers
681         ;;
682
683     *)
684         echo "Arvados-in-a-box             https://doc.arvados.org/install/arvbox.html"
685         echo
686         echo "start|run <config> [tag]   start $ARVBOX_CONTAINER container"
687         echo "stop               stop arvbox container"
688         echo "restart <config>   stop, then run again"
689         echo "status             print some information about current arvbox"
690         echo "ip                 print arvbox docker container ip address"
691         echo "host               print arvbox published host"
692         echo "shell              enter shell as root"
693         echo "ashell             enter shell as 'arvbox'"
694         echo "psql               enter postgres console"
695         echo "open               open arvbox workbench in a web browser"
696         echo "root-cert          get copy of root certificate"
697         echo "update  <config>   stop, pull latest image, run"
698         echo "build   <config>   build arvbox Docker image"
699         echo "reboot  <config>   stop, build arvbox Docker image, run"
700         echo "rebuild <config>   build arvbox Docker image, no layer cache"
701         echo "checkpoint         create database backup"
702         echo "restore            restore checkpoint"
703         echo "hotreset           reset database and restart API without restarting container"
704         echo "reset              delete arvbox arvados data (be careful!)"
705         echo "destroy            delete all arvbox code and data (be careful!)"
706         echo "log <service>      tail log of specified service"
707         echo "ls <options>       list directories inside arvbox"
708         echo "cat <files>        get contents of files inside arvbox"
709         echo "pipe               run a bash script piped in from stdin"
710         echo "sv <start|stop|restart> <service> "
711         echo "                   change state of service inside arvbox"
712         echo "clone <from> <to>  clone dev arvbox"
713         echo "adduser <username> <email> [password]"
714         echo "                   add a user login"
715         echo "removeuser <username>"
716         echo "                   remove user login"
717         echo "listusers          list user logins"
718         ;;
719 esac