Merge branch '18313-arvbox-bootstrap-go-version'
[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     # Get the go version we should use for bootstrapping
404     GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'`
405
406     if test "$1" = localdemo -o "$1" = publicdemo ; then
407         BUILDTYPE=demo
408     else
409         BUILDTYPE=dev
410     fi
411
412     if test "$ARVADOS_BRANCH" = "main" ; then
413         ARVADOS_BRANCH=$GITHEAD
414     fi
415
416     docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \
417            --build-arg=go_version=$GO_VERSION \
418            --build-arg=arvados_version=$ARVADOS_BRANCH \
419            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
420            --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
421            -t arvados/arvbox-base:$GITHEAD \
422            -f "$ARVBOX_DOCKER/Dockerfile.base" \
423            "$LOCAL_ARVADOS_ROOT"
424     docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
425     docker build $NO_CACHE \
426            --build-arg=go_version=$GO_VERSION \
427            --build-arg=arvados_version=$ARVADOS_BRANCH \
428            --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
429            -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
430            -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
431            "$ARVBOX_DOCKER"
432     docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
433 }
434
435 check() {
436     case "$1" in
437         localdemo|publicdemo|dev|publicdev|test|devenv)
438             true
439             ;;
440         *)
441             echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
442             exit 1
443         ;;
444     esac
445 }
446
447 subcmd="$1"
448 if test -n "$subcmd" ; then
449     shift
450 fi
451 case "$subcmd" in
452     build)
453         check $@
454         build $@
455         ;;
456
457     rebuild)
458         check $@
459         NO_CACHE=--no-cache build $@
460         ;;
461
462     start|run)
463         check $@
464         run $@
465         ;;
466
467     sh*)
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                $ARVBOX_CONTAINER /bin/bash
474         ;;
475
476     ash*)
477         exec docker exec --interactive --tty \
478                -e LINES=$(tput lines) \
479                -e COLUMNS=$(tput cols) \
480                -e TERM=$TERM \
481                -e GEM_HOME=$GEM_HOME \
482                -u arvbox \
483                -w /usr/src/arvados \
484                $ARVBOX_CONTAINER /bin/bash --login
485         ;;
486
487     pipe)
488         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash -
489         ;;
490
491     stop)
492         stop
493         ;;
494
495     restart)
496         check $@
497         stop
498         run $@
499         ;;
500
501     reboot)
502         check $@
503         stop
504         build $@
505         run $@
506         ;;
507
508     update)
509         check $@
510         stop
511         update $@
512         run $@
513         ;;
514
515     ip)
516         getip
517         ;;
518
519     host)
520         gethost
521         ;;
522
523     open)
524         exec xdg-open http://$(gethost)
525         ;;
526
527     status)
528         echo "Container: $ARVBOX_CONTAINER"
529         if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
530             echo "Cluster id: $(getclusterid)"
531             echo "Status: running"
532             echo "Container IP: $(getip)"
533             echo "Published host: $(gethost)"
534             echo "Workbench: https://$(gethost)"
535         else
536             echo "Status: not running"
537         fi
538         if test -d "$ARVBOX_DATA" ; then
539             echo "Data: $ARVBOX_DATA"
540         elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
541             echo "Data: $ARVBOX_CONTAINER-data"
542         else
543             echo "Data: none"
544         fi
545         ;;
546
547     reset|destroy)
548         stop
549         if test -d "$ARVBOX_DATA" ; then
550             if test "$subcmd" = destroy ; then
551                 if test "$1" != -f ; then
552                     echo "WARNING!  This will delete your entire arvbox ($ARVBOX_DATA)."
553                     echo "Use destroy -f if you really mean it."
554                     exit 1
555                 fi
556                 set -x
557                 chmod -R u+w "$ARVBOX_DATA"
558                 rm -rf "$ARVBOX_DATA"
559             else
560                 if test "$1" != -f ; then
561                     echo "WARNING!  This will delete your arvbox data ($ARVBOX_DATA)."
562                     echo "Code and downloaded packages will be preserved."
563                     echo "Use reset -f if you really mean it."
564                     exit 1
565                 fi
566                 set -x
567                 rm -rf "$ARVBOX_DATA/postgres"
568                 rm -rf "$ARVBOX_DATA/var"
569             fi
570         else
571             if test "$1" != -f ; then
572                 echo "WARNING!  This will delete your data container $ARVBOX_CONTAINER-data.  Use -f if you really mean it."
573                 exit 1
574             fi
575             set -x
576             docker rm "$ARVBOX_CONTAINER-data"
577         fi
578         ;;
579
580     log)
581         if test -n "$1" ; then
582             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"
583         else
584             exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
585         fi
586         ;;
587
588     cat)
589         if test -n "$1" ; then
590             exec docker exec $ARVBOX_CONTAINER cat "$@"
591         else
592             echo "Usage: $0 $subcmd <files>"
593         fi
594         ;;
595
596     ls)
597         exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
598         ;;
599
600     sv)
601         if test -n "$1" -a -n "$2" ; then
602             exec docker exec $ARVBOX_CONTAINER sv "$@"
603         else
604             echo "Usage: $0 $subcmd <start|stop|restart> <service>"
605             echo "Available services:"
606             exec docker exec $ARVBOX_CONTAINER ls /etc/service
607         fi
608         ;;
609
610     clone)
611         if test -n "$2" ; then
612             mkdir -p "$ARVBOX_BASE/$2"
613             cp -a "$ARVBOX_BASE/$1/passenger" \
614                "$ARVBOX_BASE/$1/gems" \
615                "$ARVBOX_BASE/$1/pip" \
616                "$ARVBOX_BASE/$1/npm" \
617                "$ARVBOX_BASE/$1/gopath" \
618                "$ARVBOX_BASE/$1/Rlibs" \
619                "$ARVBOX_BASE/$1/arvados" \
620                "$ARVBOX_BASE/$1/composer" \
621                "$ARVBOX_BASE/$1/workbench2" \
622                "$ARVBOX_BASE/$2"
623             echo "Created new arvbox $2"
624             echo "export ARVBOX_CONTAINER=$2"
625         else
626             echo "clone <from> <to>   clone an arvbox"
627             echo "available arvboxes: $(ls $ARVBOX_BASE)"
628         fi
629         ;;
630
631     root-cert)
632         CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
633         if test -n "$1" ; then
634             CERT="$1"
635         fi
636         docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
637         echo "Certificate copied to $CERT"
638         ;;
639
640     psql)
641         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'
642         ;;
643
644     checkpoint)
645         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'
646         ;;
647
648     restore)
649         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'
650         ;;
651
652     hotreset)
653         exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash - <<EOF
654 sv stop api
655 sv stop controller
656 sv stop websockets
657 sv stop keepstore0
658 sv stop keepstore1
659 sv stop keepproxy
660 cd /usr/src/arvados/services/api
661 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
662 export RAILS_ENV=development
663 flock $GEM_HOME/gems.lock bin/bundle exec rake db:drop
664 rm $ARVADOS_CONTAINER_PATH/api_database_setup
665 rm $ARVADOS_CONTAINER_PATH/superuser_token
666 sv start api
667 sv start controller
668 sv start websockets
669 sv restart keepstore0
670 sv restart keepstore1
671 sv restart keepproxy
672 EOF
673         ;;
674
675     adduser)
676 if [[ -n "$2" ]] ; then
677           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
678           docker exec $ARVBOX_CONTAINER sv restart controller
679         else
680             echo "Usage: adduser <username> <email> [password]"
681         fi
682         ;;
683
684     removeuser)
685         if [[ -n "$1" ]] ; then
686           docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
687           docker exec $ARVBOX_CONTAINER sv restart controller
688         else
689             echo "Usage: removeuser <username>"
690         fi
691         ;;
692
693     listusers)
694         listusers
695         ;;
696
697     *)
698         echo "Arvados-in-a-box             https://doc.arvados.org/install/arvbox.html"
699         echo
700         echo "start|run <config> [tag]   start $ARVBOX_CONTAINER container"
701         echo "stop               stop arvbox container"
702         echo "restart <config>   stop, then run again"
703         echo "status             print some information about current arvbox"
704         echo "ip                 print arvbox docker container ip address"
705         echo "host               print arvbox published host"
706         echo "shell              enter shell as root"
707         echo "ashell             enter shell as 'arvbox'"
708         echo "psql               enter postgres console"
709         echo "open               open arvbox workbench in a web browser"
710         echo "root-cert          get copy of root certificate"
711         echo "update  <config>   stop, pull latest image, run"
712         echo "build   <config>   build arvbox Docker image"
713         echo "reboot  <config>   stop, build arvbox Docker image, run"
714         echo "rebuild <config>   build arvbox Docker image, no layer cache"
715         echo "checkpoint         create database backup"
716         echo "restore            restore checkpoint"
717         echo "hotreset           reset database and restart API without restarting container"
718         echo "reset              delete arvbox arvados data (be careful!)"
719         echo "destroy            delete all arvbox code and data (be careful!)"
720         echo "log <service>      tail log of specified service"
721         echo "ls <options>       list directories inside arvbox"
722         echo "cat <files>        get contents of files inside arvbox"
723         echo "pipe               run a bash script piped in from stdin"
724         echo "sv <start|stop|restart> <service> "
725         echo "                   change state of service inside arvbox"
726         echo "clone <from> <to>  clone dev arvbox"
727         echo "adduser <username> <email> [password]"
728         echo "                   add a user login"
729         echo "removeuser <username>"
730         echo "                   remove user login"
731         echo "listusers          list user logins"
732         ;;
733 esac