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