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