dd53d89c0f8ac8a6b0438ea2daa883d2c0199b60
[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
76 getip() {
77     docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
78 }
79
80 gethost() {
81     set +e
82     OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
83     CODE=$?
84     set -e
85     if test "$CODE" = 0 ; then
86        echo $OVERRIDE
87     else
88         getip
89     fi
90 }
91
92 getclusterid() {
93     docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix
94 }
95
96 updateconf() {
97     if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
98         sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
99         mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
100     else
101         mkdir -p $HOME/.config/arvados
102         cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
103 ARVADOS_API_HOST=$(gethost):8000
104 ARVADOS_API_TOKEN=
105 ARVADOS_API_HOST_INSECURE=true
106 EOF
107     fi
108 }
109
110 listusers() {
111     docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list
112 }
113
114 wait_for_arvbox() {
115     FF=/tmp/arvbox-fifo-$$
116     mkfifo $FF
117     docker logs -f $ARVBOX_CONTAINER > $FF &
118     LOGPID=$!
119     while read line ; do
120         if [[ $line =~ "ok: down: ready:" ]] ; then
121             kill $LOGPID
122             set +e
123             wait $LOGPID 2>/dev/null
124             set -e
125         else
126             echo $line
127         fi
128     done < $FF
129     rm $FF
130     echo
131     if test -n "$localip" ; then
132         echo "export ARVADOS_API_HOST=$localip:8000"
133     else
134         echo "export ARVADOS_API_HOST=$(gethost):8000"
135     fi
136 }
137
138 docker_run_dev() {
139     docker run \
140            "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
141            "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
142            "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
143            "--volume=$PG_DATA:/var/lib/postgresql:rw" \
144            "--volume=$VAR_DATA:$ARVADOS_CONTAINER_PATH:rw" \
145            "--volume=$PASSENGER:/var/lib/passenger:rw" \
146            "--volume=$PIPCACHE:/var/lib/pip:rw" \
147            "--volume=$NPMCACHE:/var/lib/npm:rw" \
148            "--volume=$GOSTUFF:/var/lib/gopath:rw" \
149            "--volume=$RLIBS:/var/lib/Rlibs:rw" \
150            --label "org.arvados.arvbox_config=$CONFIG" \
151            "$@"
152 }
153
154 running_config() {
155     docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
156 }
157
158 run() {
159     CONFIG=$1
160     TAG=$2
161
162     shift
163
164     need_setup=1
165
166     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
167         if [[ $(running_config) != "$CONFIG" ]] ; then
168             echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
169             return 1
170         fi
171         if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
172             need_setup=0
173         else
174             echo "Container $ARVBOX_CONTAINER is already running"
175             return 0
176         fi
177     fi
178
179     if test $need_setup = 1 ; then
180         if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
181             echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
182             return 1
183         fi
184     fi
185
186     if test -n "$TAG"
187     then
188         if test $(echo $TAG | cut -c1-1) != '-' ; then
189             TAG=":$TAG"
190             shift
191         else
192             if [[ $TAG = '-' ]] ; then
193                 shift
194             fi
195             unset TAG
196         fi
197     fi
198
199     if test -z "$TAG" -a -n "$DEFAULT_TAG"; then
200         TAG=":$DEFAULT_TAG"
201     fi
202
203     if [[ "$CONFIG" =~ ^public ]] ; then
204         if test -n "$ARVBOX_PUBLISH_IP" ; then
205             localip=$ARVBOX_PUBLISH_IP
206         else
207             defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
208             localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
209         fi
210         echo "Public arvbox will use address $localip"
211         iptemp=$(mktemp)
212         echo $localip > $iptemp
213         chmod og+r $iptemp
214         PUBLIC="--volume=$iptemp:/var/run/localip_override
215               --publish=443:443
216               --publish=3001:3001
217               --publish=8000:8000
218               --publish=8900:8900
219               --publish=9000:9000
220               --publish=9002:9002
221               --publish=9004:9004
222               --publish=25101:25101
223               --publish=8001:8001
224               --publish=8002:8002
225               --publish=4202:4202
226               --publish=45000-45020:45000-45020"
227     else
228         PUBLIC=""
229     fi
230
231     if [[ "$CONFIG" =~ demo$ ]] ; then
232         if test -d "$ARVBOX_DATA" ; then
233             echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
234             echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
235             exit 1
236         fi
237
238         if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
239             docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
240         fi
241
242         docker run \
243                --detach \
244                --name=$ARVBOX_CONTAINER \
245                --privileged \
246                --volumes-from $ARVBOX_CONTAINER-data \
247                --label "org.arvados.arvbox_config=$CONFIG" \
248                $PUBLIC \
249                arvados/arvbox-demo$TAG
250         updateconf
251         wait_for_arvbox
252     else
253         mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
254
255         if ! test -d "$ARVADOS_ROOT" ; then
256             git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
257             git -C "$ARVADOS_ROOT" checkout $ARVADOS_BRANCH
258         fi
259         if ! test -d "$COMPOSER_ROOT" ; then
260             git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
261             git -C "$COMPOSER_ROOT" checkout arvados-fork
262         fi
263         if ! test -d "$WORKBENCH2_ROOT" ; then
264             git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
265             git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH
266         fi
267
268         if [[ "$CONFIG" = test ]] ; then
269
270             mkdir -p $VAR_DATA/test
271
272             if test "$need_setup" = 1 ; then
273                 docker_run_dev \
274                        --detach \
275                        --name=$ARVBOX_CONTAINER \
276                        --privileged \
277                        "--env=SVDIR=/etc/test-service" \
278                        arvados/arvbox-dev$TAG
279
280                 docker exec -ti \
281                        $ARVBOX_CONTAINER \
282                        /usr/local/lib/arvbox/runsu.sh \
283                        /usr/local/lib/arvbox/waitforpostgres.sh
284             fi
285
286             interactive=""
287             if [[ -z "$@" ]] ; then
288                 interactive=--interactive
289             fi
290
291             docker exec -ti \
292                    -e LINES=$(tput lines) \
293                    -e COLUMNS=$(tput cols) \
294                    -e TERM=$TERM \
295                    -e WORKSPACE=/usr/src/arvados \
296                    -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
297                    $ARVBOX_CONTAINER \
298                    /usr/local/lib/arvbox/runsu.sh \
299                    /usr/src/arvados/build/run-tests.sh \
300                    --temp $ARVADOS_CONTAINER_PATH/test \
301                    $interactive \
302                    "$@"
303         elif [[ "$CONFIG" = devenv ]] ; then
304             if [[ $need_setup = 1 ]] ; then
305                     docker_run_dev \
306                     --detach \
307                     --name=${ARVBOX_CONTAINER} \
308                     "--env=SVDIR=/etc/devenv-service" \
309                         "--volume=$HOME:$HOME:rw" \
310                     --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
311                         arvados/arvbox-dev$TAG
312             fi
313             exec docker exec --interactive --tty \
314                  -e LINES=$(tput lines) \
315                  -e COLUMNS=$(tput cols) \
316                  -e TERM=$TERM \
317                  -e "ARVBOX_HOME=$HOME" \
318                  -e "DISPLAY=$DISPLAY" \
319                  --workdir=$PWD \
320                  ${ARVBOX_CONTAINER} \
321                  /usr/local/lib/arvbox/devenv.sh "$@"
322         elif [[ "$CONFIG" =~ dev$ ]] ; then
323             docker_run_dev \
324                    --detach \
325                    --name=$ARVBOX_CONTAINER \
326                    --privileged \
327                    $PUBLIC \
328                    arvados/arvbox-dev$TAG
329             updateconf
330             wait_for_arvbox
331             echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
332             echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
333             if [[ "$(listusers)" =~ ^\{\} ]] ; then
334                 echo "No users defined, use 'arvbox adduser' to add user logins"
335             else
336                 echo "Use 'arvbox listusers' to see user logins"
337             fi
338         else
339             echo "Unknown configuration '$CONFIG'"
340         fi
341     fi
342 }
343
344 update() {
345     CONFIG=$1
346     TAG=$2
347
348     if test -n "$TAG"
349     then
350         if test $(echo $TAG | cut -c1-1) != '-' ; then
351             TAG=":$TAG"
352             shift
353         else
354             unset TAG
355         fi
356     fi
357
358     if echo "$CONFIG" | grep 'demo$' ; then
359         docker pull arvados/arvbox-demo$TAG
360     else
361         docker pull arvados/arvbox-dev$TAG
362     fi
363 }
364
365 stop() {
366     if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
367         docker stop $ARVBOX_CONTAINER
368     fi
369
370     VOLUMES=--volumes=true
371     if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
372         docker rm $VOLUMES $ARVBOX_CONTAINER
373     fi
374     if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
375         docker rm $VOLUMES $ARVBOX_CONTAINER
376     fi
377 }
378
379 build() {
380     export DOCKER_BUILDKIT=1
381     if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ;  then
382         echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
383         exit 1
384     fi
385     if docker --version |grep " 1\.[0-9]\." ; then
386         # Docker version prior 1.10 require -f flag
387         # -f flag removed in Docker 1.12
388         FORCE=-f
389     fi
390     GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
391
392     set +e
393     if which greadlink >/dev/null 2>/dev/null ; then
394         LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
395     else
396         LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
397     fi
398     set -e
399
400     # Get the go version we should use for bootstrapping
401     GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'`
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=go_version=$GO_VERSION \
415            --build-arg=arvados_version=$ARVADOS_BRANCH \
416            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
417            --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
418            -t arvados/arvbox-base:$GITHEAD \
419            -f "$ARVBOX_DOCKER/Dockerfile.base" \
420            "$LOCAL_ARVADOS_ROOT"
421     docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
422     docker build $NO_CACHE \
423            --build-arg=go_version=$GO_VERSION \
424            --build-arg=arvados_version=$ARVADOS_BRANCH \
425            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
426            -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
427            -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
428            "$ARVBOX_DOCKER"
429     docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
430 }
431
432 check() {
433     case "$1" in
434         localdemo|publicdemo|dev|publicdev|test|devenv)
435             true
436             ;;
437         *)
438             echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
439             exit 1
440         ;;
441     esac
442 }
443
444 subcmd="$1"
445 if test -n "$subcmd" ; then
446     shift
447 fi
448 case "$subcmd" in
449     build)
450         check $@
451         build $@
452         ;;
453
454     rebuild)
455         check $@
456         NO_CACHE=--no-cache build $@
457         ;;
458
459     start|run)
460         check $@
461         run $@
462         ;;
463
464     sh*)
465         exec docker exec --interactive --tty \
466                -e LINES=$(tput lines) \
467                -e COLUMNS=$(tput cols) \
468                -e TERM=$TERM \
469                $ARVBOX_CONTAINER /bin/bash
470         ;;
471
472     ash*)
473         exec docker exec --interactive --tty \
474                -e LINES=$(tput lines) \
475                -e COLUMNS=$(tput cols) \
476                -e TERM=$TERM \
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 /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 /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 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