ba3f2cd07eb211527be10c5ed46366678f5771af
[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             git -C "$ARVADOS_ROOT" pull
254         fi
255         if ! test -d "$COMPOSER_ROOT" ; then
256             git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
257             git -C "$COMPOSER_ROOT" checkout arvados-fork
258             git -C "$COMPOSER_ROOT" pull
259         fi
260         if ! test -d "$WORKBENCH2_ROOT" ; then
261             git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
262             git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH
263             git -C "$ARVADOS_ROOT" pull
264         fi
265
266         if [[ "$CONFIG" = test ]] ; then
267
268             mkdir -p $VAR_DATA/test
269
270             if test "$need_setup" = 1 ; then
271                 docker_run_dev \
272                        --detach \
273                        --name=$ARVBOX_CONTAINER \
274                        --privileged \
275                        "--env=SVDIR=/etc/test-service" \
276                        arvados/arvbox-dev$TAG
277
278                 docker exec -ti \
279                        $ARVBOX_CONTAINER \
280                        /usr/local/lib/arvbox/runsu.sh \
281                        /usr/local/lib/arvbox/waitforpostgres.sh
282             fi
283
284             interactive=""
285             if [[ -z "$@" ]] ; then
286                 interactive=--interactive
287             fi
288
289             docker exec -ti \
290                    -e LINES=$(tput lines) \
291                    -e COLUMNS=$(tput cols) \
292                    -e TERM=$TERM \
293                    -e WORKSPACE=/usr/src/arvados \
294                    -e GEM_HOME=$GEM_HOME \
295                    -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
296                    $ARVBOX_CONTAINER \
297                    /usr/local/lib/arvbox/runsu.sh \
298                    /usr/src/arvados/build/run-tests.sh \
299                    --temp $ARVADOS_CONTAINER_PATH/test \
300                    $interactive \
301                    "$@"
302         elif [[ "$CONFIG" = devenv ]] ; then
303             if [[ $need_setup = 1 ]] ; then
304                     docker_run_dev \
305                     --detach \
306                     --name=${ARVBOX_CONTAINER} \
307                     "--env=SVDIR=/etc/devenv-service" \
308                         "--volume=$HOME:$HOME:rw" \
309                     --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
310                         arvados/arvbox-dev$TAG
311             fi
312             exec docker exec --interactive --tty \
313                  -e LINES=$(tput lines) \
314                  -e COLUMNS=$(tput cols) \
315                  -e TERM=$TERM \
316                  -e "ARVBOX_HOME=$HOME" \
317                  -e "DISPLAY=$DISPLAY" \
318                  --workdir=$PWD \
319                  ${ARVBOX_CONTAINER} \
320                  /usr/local/lib/arvbox/devenv.sh "$@"
321         elif [[ "$CONFIG" =~ dev$ ]] ; then
322             docker_run_dev \
323                    --detach \
324                    --name=$ARVBOX_CONTAINER \
325                    --privileged \
326                    $PUBLIC \
327                    arvados/arvbox-dev$TAG
328             updateconf
329             wait_for_arvbox
330             echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
331             echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
332             if [[ "$(listusers)" =~ ^\{\} ]] ; then
333                 echo "No users defined, use 'arvbox adduser' to add user logins"
334             else
335                 echo "Use 'arvbox listusers' to see user logins"
336             fi
337         else
338             echo "Unknown configuration '$CONFIG'"
339         fi
340     fi
341 }
342
343 update() {
344     CONFIG=$1
345     TAG=$2
346
347     if test -n "$TAG"
348     then
349         if test $(echo $TAG | cut -c1-1) != '-' ; then
350             TAG=":$TAG"
351             shift
352         else
353             unset TAG
354         fi
355     fi
356
357     if echo "$CONFIG" | grep 'demo$' ; then
358         docker pull arvados/arvbox-demo$TAG
359     else
360         docker pull arvados/arvbox-dev$TAG
361     fi
362 }
363
364 stop() {
365     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
366         docker stop $ARVBOX_CONTAINER
367     fi
368
369     VOLUMES=--volumes=true
370     if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
371         docker rm $VOLUMES $ARVBOX_CONTAINER
372     fi
373     if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
374         docker rm $VOLUMES $ARVBOX_CONTAINER
375     fi
376 }
377
378 build() {
379     export DOCKER_BUILDKIT=1
380     if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ;  then
381         echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
382         exit 1
383     fi
384     if docker --version |grep " 1\.[0-9]\." ; then
385         # Docker version prior 1.10 require -f flag
386         # -f flag removed in Docker 1.12
387         FORCE=-f
388     fi
389     GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
390
391     set +e
392     if which greadlink >/dev/null 2>/dev/null ; then
393         LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
394     else
395         LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
396     fi
397     set -e
398
399     if test "$1" = localdemo -o "$1" = publicdemo ; then
400         BUILDTYPE=demo
401     else
402         BUILDTYPE=dev
403     fi
404
405     if test "$ARVADOS_BRANCH" = "main" ; then
406         ARVADOS_BRANCH=$GITHEAD
407     fi
408
409     docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \
410            --build-arg=arvados_version=$ARVADOS_BRANCH \
411            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
412            --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
413            -t arvados/arvbox-base:$GITHEAD \
414            -f "$ARVBOX_DOCKER/Dockerfile.base" \
415            "$LOCAL_ARVADOS_ROOT"
416     docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
417     docker build $NO_CACHE \
418            --build-arg=arvados_version=$ARVADOS_BRANCH \
419            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
420            -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
421            -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
422            "$ARVBOX_DOCKER"
423     docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
424 }
425
426 check() {
427     case "$1" in
428         localdemo|publicdemo|dev|publicdev|test|devenv)
429             true
430             ;;
431         *)
432             echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
433             exit 1
434         ;;
435     esac
436 }
437
438 subcmd="$1"
439 if test -n "$subcmd" ; then
440     shift
441 fi
442 case "$subcmd" in
443     build)
444         check $@
445         build $@
446         ;;
447
448     rebuild)
449         check $@
450         NO_CACHE=--no-cache build $@
451         ;;
452
453     start|run)
454         check $@
455         run $@
456         ;;
457
458     sh*)
459         exec docker exec --interactive --tty \
460                -e LINES=$(tput lines) \
461                -e COLUMNS=$(tput cols) \
462                -e TERM=$TERM \
463                -e GEM_HOME=$GEM_HOME \
464                $ARVBOX_CONTAINER /bin/bash
465         ;;
466
467     ash*)
468         exec docker exec --interactive --tty \
469                -e LINES=$(tput lines) \
470                -e COLUMNS=$(tput cols) \
471                -e TERM=$TERM \
472                -e GEM_HOME=$GEM_HOME \
473                -u arvbox \
474                -w /usr/src/arvados \
475                $ARVBOX_CONTAINER /bin/bash --login
476         ;;
477
478     pipe)
479         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash -
480         ;;
481
482     stop)
483         stop
484         ;;
485
486     restart)
487         check $@
488         stop
489         run $@
490         ;;
491
492     reboot)
493         check $@
494         stop
495         build $@
496         run $@
497         ;;
498
499     update)
500         check $@
501         stop
502         update $@
503         run $@
504         ;;
505
506     ip)
507         getip
508         ;;
509
510     host)
511         gethost
512         ;;
513
514     open)
515         exec xdg-open http://$(gethost)
516         ;;
517
518     status)
519         echo "Container: $ARVBOX_CONTAINER"
520         if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
521             echo "Cluster id: $(getclusterid)"
522             echo "Status: running"
523             echo "Container IP: $(getip)"
524             echo "Published host: $(gethost)"
525         else
526             echo "Status: not running"
527         fi
528         if test -d "$ARVBOX_DATA" ; then
529             echo "Data: $ARVBOX_DATA"
530         elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
531             echo "Data: $ARVBOX_CONTAINER-data"
532         else
533             echo "Data: none"
534         fi
535         ;;
536
537     reset|destroy)
538         stop
539         if test -d "$ARVBOX_DATA" ; then
540             if test "$subcmd" = destroy ; then
541                 if test "$1" != -f ; then
542                     echo "WARNING!  This will delete your entire arvbox ($ARVBOX_DATA)."
543                     echo "Use destroy -f if you really mean it."
544                     exit 1
545                 fi
546                 set -x
547                 chmod -R u+w "$ARVBOX_DATA"
548                 rm -rf "$ARVBOX_DATA"
549             else
550                 if test "$1" != -f ; then
551                     echo "WARNING!  This will delete your arvbox data ($ARVBOX_DATA)."
552                     echo "Code and downloaded packages will be preserved."
553                     echo "Use reset -f if you really mean it."
554                     exit 1
555                 fi
556                 set -x
557                 rm -rf "$ARVBOX_DATA/postgres"
558                 rm -rf "$ARVBOX_DATA/var"
559             fi
560         else
561             if test "$1" != -f ; then
562                 echo "WARNING!  This will delete your data container $ARVBOX_CONTAINER-data.  Use -f if you really mean it."
563                 exit 1
564             fi
565             set -x
566             docker rm "$ARVBOX_CONTAINER-data"
567         fi
568         ;;
569
570     log)
571         if test -n "$1" ; then
572             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"
573         else
574             exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
575         fi
576         ;;
577
578     cat)
579         if test -n "$1" ; then
580             exec docker exec $ARVBOX_CONTAINER cat "$@"
581         else
582             echo "Usage: $0 $subcmd <files>"
583         fi
584         ;;
585
586     ls)
587         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
588         ;;
589
590     sv)
591         if test -n "$1" -a -n "$2" ; then
592             exec docker exec $ARVBOX_CONTAINER sv "$@"
593         else
594             echo "Usage: $0 $subcmd <start|stop|restart> <service>"
595             echo "Available services:"
596             exec docker exec $ARVBOX_CONTAINER ls /etc/service
597         fi
598         ;;
599
600     clone)
601         if test -n "$2" ; then
602             mkdir -p "$ARVBOX_BASE/$2"
603             cp -a "$ARVBOX_BASE/$1/passenger" \
604                "$ARVBOX_BASE/$1/gems" \
605                "$ARVBOX_BASE/$1/pip" \
606                "$ARVBOX_BASE/$1/npm" \
607                "$ARVBOX_BASE/$1/gopath" \
608                "$ARVBOX_BASE/$1/Rlibs" \
609                "$ARVBOX_BASE/$1/arvados" \
610                "$ARVBOX_BASE/$1/composer" \
611                "$ARVBOX_BASE/$1/workbench2" \
612                "$ARVBOX_BASE/$2"
613             echo "Created new arvbox $2"
614             echo "export ARVBOX_CONTAINER=$2"
615         else
616             echo "clone <from> <to>   clone an arvbox"
617             echo "available arvboxes: $(ls $ARVBOX_BASE)"
618         fi
619         ;;
620
621     root-cert)
622         CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
623         if test -n "$1" ; then
624             CERT="$1"
625         fi
626         docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
627         echo "Certificate copied to $CERT"
628         ;;
629
630     psql)
631         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'
632         ;;
633
634     checkpoint)
635         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'
636         ;;
637
638     restore)
639         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'
640         ;;
641
642     hotreset)
643         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash - <<EOF
644 sv stop api
645 sv stop controller
646 sv stop websockets
647 sv stop keepstore0
648 sv stop keepstore1
649 sv stop keepproxy
650 cd /usr/src/arvados/services/api
651 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
652 export RAILS_ENV=development
653 flock $GEM_HOME/gems.lock bin/bundle exec rake db:drop
654 rm $ARVADOS_CONTAINER_PATH/api_database_setup
655 rm $ARVADOS_CONTAINER_PATH/superuser_token
656 sv start api
657 sv start controller
658 sv start websockets
659 sv restart keepstore0
660 sv restart keepstore1
661 sv restart keepproxy
662 EOF
663         ;;
664
665     adduser)
666 if [[ -n "$2" ]] ; then
667           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
668           docker exec $ARVBOX_CONTAINER sv restart controller
669         else
670             echo "Usage: adduser <username> <email> [password]"
671         fi
672         ;;
673
674     removeuser)
675         if [[ -n "$1" ]] ; then
676           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
677           docker exec $ARVBOX_CONTAINER sv restart controller
678         else
679             echo "Usage: removeuser <username>"
680         fi
681         ;;
682
683     listusers)
684         listusers
685         ;;
686
687     *)
688         echo "Arvados-in-a-box             https://doc.arvados.org/install/arvbox.html"
689         echo
690         echo "start|run <config> [tag]   start $ARVBOX_CONTAINER container"
691         echo "stop               stop arvbox container"
692         echo "restart <config>   stop, then run again"
693         echo "status             print some information about current arvbox"
694         echo "ip                 print arvbox docker container ip address"
695         echo "host               print arvbox published host"
696         echo "shell              enter shell as root"
697         echo "ashell             enter shell as 'arvbox'"
698         echo "psql               enter postgres console"
699         echo "open               open arvbox workbench in a web browser"
700         echo "root-cert          get copy of root certificate"
701         echo "update  <config>   stop, pull latest image, run"
702         echo "build   <config>   build arvbox Docker image"
703         echo "reboot  <config>   stop, build arvbox Docker image, run"
704         echo "rebuild <config>   build arvbox Docker image, no layer cache"
705         echo "checkpoint         create database backup"
706         echo "restore            restore checkpoint"
707         echo "hotreset           reset database and restart API without restarting container"
708         echo "reset              delete arvbox arvados data (be careful!)"
709         echo "destroy            delete all arvbox code and data (be careful!)"
710         echo "log <service>      tail log of specified service"
711         echo "ls <options>       list directories inside arvbox"
712         echo "cat <files>        get contents of files inside arvbox"
713         echo "pipe               run a bash script piped in from stdin"
714         echo "sv <start|stop|restart> <service> "
715         echo "                   change state of service inside arvbox"
716         echo "clone <from> <to>  clone dev arvbox"
717         echo "adduser <username> <email> [password]"
718         echo "                   add a user login"
719         echo "removeuser <username>"
720         echo "                   remove user login"
721         echo "listusers          list user logins"
722         ;;
723 esac