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