Merge branch '17857-lsf-cpus'
[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         else
530             echo "Status: not running"
531         fi
532         if test -d "$ARVBOX_DATA" ; then
533             echo "Data: $ARVBOX_DATA"
534         elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
535             echo "Data: $ARVBOX_CONTAINER-data"
536         else
537             echo "Data: none"
538         fi
539         ;;
540
541     reset|destroy)
542         stop
543         if test -d "$ARVBOX_DATA" ; then
544             if test "$subcmd" = destroy ; then
545                 if test "$1" != -f ; then
546                     echo "WARNING!  This will delete your entire arvbox ($ARVBOX_DATA)."
547                     echo "Use destroy -f if you really mean it."
548                     exit 1
549                 fi
550                 set -x
551                 chmod -R u+w "$ARVBOX_DATA"
552                 rm -rf "$ARVBOX_DATA"
553             else
554                 if test "$1" != -f ; then
555                     echo "WARNING!  This will delete your arvbox data ($ARVBOX_DATA)."
556                     echo "Code and downloaded packages will be preserved."
557                     echo "Use reset -f if you really mean it."
558                     exit 1
559                 fi
560                 set -x
561                 rm -rf "$ARVBOX_DATA/postgres"
562                 rm -rf "$ARVBOX_DATA/var"
563             fi
564         else
565             if test "$1" != -f ; then
566                 echo "WARNING!  This will delete your data container $ARVBOX_CONTAINER-data.  Use -f if you really mean it."
567                 exit 1
568             fi
569             set -x
570             docker rm "$ARVBOX_CONTAINER-data"
571         fi
572         ;;
573
574     log)
575         if test -n "$1" ; then
576             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"
577         else
578             exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
579         fi
580         ;;
581
582     cat)
583         if test -n "$1" ; then
584             exec docker exec $ARVBOX_CONTAINER cat "$@"
585         else
586             echo "Usage: $0 $subcmd <files>"
587         fi
588         ;;
589
590     ls)
591         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
592         ;;
593
594     sv)
595         if test -n "$1" -a -n "$2" ; then
596             exec docker exec $ARVBOX_CONTAINER sv "$@"
597         else
598             echo "Usage: $0 $subcmd <start|stop|restart> <service>"
599             echo "Available services:"
600             exec docker exec $ARVBOX_CONTAINER ls /etc/service
601         fi
602         ;;
603
604     clone)
605         if test -n "$2" ; then
606             mkdir -p "$ARVBOX_BASE/$2"
607             cp -a "$ARVBOX_BASE/$1/passenger" \
608                "$ARVBOX_BASE/$1/gems" \
609                "$ARVBOX_BASE/$1/pip" \
610                "$ARVBOX_BASE/$1/npm" \
611                "$ARVBOX_BASE/$1/gopath" \
612                "$ARVBOX_BASE/$1/Rlibs" \
613                "$ARVBOX_BASE/$1/arvados" \
614                "$ARVBOX_BASE/$1/composer" \
615                "$ARVBOX_BASE/$1/workbench2" \
616                "$ARVBOX_BASE/$2"
617             echo "Created new arvbox $2"
618             echo "export ARVBOX_CONTAINER=$2"
619         else
620             echo "clone <from> <to>   clone an arvbox"
621             echo "available arvboxes: $(ls $ARVBOX_BASE)"
622         fi
623         ;;
624
625     root-cert)
626         CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
627         if test -n "$1" ; then
628             CERT="$1"
629         fi
630         docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
631         echo "Certificate copied to $CERT"
632         ;;
633
634     psql)
635         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'
636         ;;
637
638     checkpoint)
639         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'
640         ;;
641
642     restore)
643         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'
644         ;;
645
646     hotreset)
647         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash - <<EOF
648 sv stop api
649 sv stop controller
650 sv stop websockets
651 sv stop keepstore0
652 sv stop keepstore1
653 sv stop keepproxy
654 cd /usr/src/arvados/services/api
655 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
656 export RAILS_ENV=development
657 flock $GEM_HOME/gems.lock bin/bundle exec rake db:drop
658 rm $ARVADOS_CONTAINER_PATH/api_database_setup
659 rm $ARVADOS_CONTAINER_PATH/superuser_token
660 sv start api
661 sv start controller
662 sv start websockets
663 sv restart keepstore0
664 sv restart keepstore1
665 sv restart keepproxy
666 EOF
667         ;;
668
669     adduser)
670 if [[ -n "$2" ]] ; then
671           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
672           docker exec $ARVBOX_CONTAINER sv restart controller
673         else
674             echo "Usage: adduser <username> <email> [password]"
675         fi
676         ;;
677
678     removeuser)
679         if [[ -n "$1" ]] ; then
680           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
681           docker exec $ARVBOX_CONTAINER sv restart controller
682         else
683             echo "Usage: removeuser <username>"
684         fi
685         ;;
686
687     listusers)
688         listusers
689         ;;
690
691     *)
692         echo "Arvados-in-a-box             https://doc.arvados.org/install/arvbox.html"
693         echo
694         echo "start|run <config> [tag]   start $ARVBOX_CONTAINER container"
695         echo "stop               stop arvbox container"
696         echo "restart <config>   stop, then run again"
697         echo "status             print some information about current arvbox"
698         echo "ip                 print arvbox docker container ip address"
699         echo "host               print arvbox published host"
700         echo "shell              enter shell as root"
701         echo "ashell             enter shell as 'arvbox'"
702         echo "psql               enter postgres console"
703         echo "open               open arvbox workbench in a web browser"
704         echo "root-cert          get copy of root certificate"
705         echo "update  <config>   stop, pull latest image, run"
706         echo "build   <config>   build arvbox Docker image"
707         echo "reboot  <config>   stop, build arvbox Docker image, run"
708         echo "rebuild <config>   build arvbox Docker image, no layer cache"
709         echo "checkpoint         create database backup"
710         echo "restore            restore checkpoint"
711         echo "hotreset           reset database and restart API without restarting container"
712         echo "reset              delete arvbox arvados data (be careful!)"
713         echo "destroy            delete all arvbox code and data (be careful!)"
714         echo "log <service>      tail log of specified service"
715         echo "ls <options>       list directories inside arvbox"
716         echo "cat <files>        get contents of files inside arvbox"
717         echo "pipe               run a bash script piped in from stdin"
718         echo "sv <start|stop|restart> <service> "
719         echo "                   change state of service inside arvbox"
720         echo "clone <from> <to>  clone dev arvbox"
721         echo "adduser <username> <email> [password]"
722         echo "                   add a user login"
723         echo "removeuser <username>"
724         echo "                   remove user login"
725         echo "listusers          list user logins"
726         ;;
727 esac