2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
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."
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"
21 if test -z "$ARVBOX_DOCKER" ; then
23 if which greadlink >/dev/null 2>/dev/null ; then
24 ARVBOX_DOCKER=$(greadlink -f $(dirname $0)/../lib/arvbox/docker)
26 ARVBOX_DOCKER=$(readlink -f $(dirname $0)/../lib/arvbox/docker)
31 if test -z "$ARVBOX_CONTAINER" ; then
32 ARVBOX_CONTAINER=arvbox
35 if test -z "$ARVBOX_BASE" ; then
36 ARVBOX_BASE="$HOME/.arvbox"
39 if test -z "$ARVBOX_DATA" ; then
40 ARVBOX_DATA="$ARVBOX_BASE/$ARVBOX_CONTAINER"
43 if test -z "$ARVADOS_ROOT" ; then
44 ARVADOS_ROOT="$ARVBOX_DATA/arvados"
47 if test -z "$COMPOSER_ROOT" ; then
48 COMPOSER_ROOT="$ARVBOX_DATA/composer"
51 if test -z "$WORKBENCH2_ROOT" ; then
52 WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2"
55 PG_DATA="$ARVBOX_DATA/postgres"
56 VAR_DATA="$ARVBOX_DATA/var"
57 PASSENGER="$ARVBOX_DATA/passenger"
58 GEMS="$ARVBOX_DATA/gems"
59 PIPCACHE="$ARVBOX_DATA/pip"
60 NPMCACHE="$ARVBOX_DATA/npm"
61 GOSTUFF="$ARVBOX_DATA/gopath"
62 RLIBS="$ARVBOX_DATA/Rlibs"
63 ARVADOS_CONTAINER_PATH="/var/lib/arvados-arvbox"
64 GEM_HOME="/var/lib/arvados/lib/ruby/gems/2.5.0"
67 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
72 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
75 if test "$CODE" = 0 ; then
83 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix
87 if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
88 sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
89 mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
91 mkdir -p $HOME/.config/arvados
92 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
93 ARVADOS_API_HOST=$(gethost):8000
95 ARVADOS_API_HOST_INSECURE=true
101 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list
105 FF=/tmp/arvbox-fifo-$$
107 docker logs -f $ARVBOX_CONTAINER > $FF &
110 if [[ $line =~ "ok: down: ready:" ]] ; then
113 wait $LOGPID 2>/dev/null
121 if test -n "$localip" ; then
122 echo "export ARVADOS_API_HOST=$localip:8000"
124 echo "export ARVADOS_API_HOST=$(gethost):8000"
130 "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
131 "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
132 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
133 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
134 "--volume=$VAR_DATA:$ARVADOS_CONTAINER_PATH:rw" \
135 "--volume=$PASSENGER:/var/lib/passenger:rw" \
136 "--volume=$GEMS:$GEM_HOME:rw" \
137 "--volume=$PIPCACHE:/var/lib/pip:rw" \
138 "--volume=$NPMCACHE:/var/lib/npm:rw" \
139 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
140 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
141 --label "org.arvados.arvbox_config=$CONFIG" \
146 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
157 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
158 if [[ $(running_config) != "$CONFIG" ]] ; then
159 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
162 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
165 echo "Container $ARVBOX_CONTAINER is already running"
170 if test $need_setup = 1 ; then
171 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
172 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
179 if test $(echo $TAG | cut -c1-1) != '-' ; then
183 if [[ $TAG = '-' ]] ; then
190 if [[ "$CONFIG" =~ ^public ]] ; then
191 if test -n "$ARVBOX_PUBLISH_IP" ; then
192 localip=$ARVBOX_PUBLISH_IP
194 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
195 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
197 echo "Public arvbox will use address $localip"
199 echo $localip > $iptemp
201 PUBLIC="--volume=$iptemp:/var/run/localip_override
209 --publish=25101:25101
213 --publish=45000-45020:45000-45020"
218 if [[ "$CONFIG" =~ demo$ ]] ; then
219 if test -d "$ARVBOX_DATA" ; then
220 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
221 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
225 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
226 docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
231 --name=$ARVBOX_CONTAINER \
233 --volumes-from $ARVBOX_CONTAINER-data \
234 --label "org.arvados.arvbox_config=$CONFIG" \
236 arvados/arvbox-demo$TAG
240 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
242 if ! test -d "$ARVADOS_ROOT" ; then
243 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
245 if ! test -d "$COMPOSER_ROOT" ; then
246 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
247 git -C "$COMPOSER_ROOT" checkout arvados-fork
248 git -C "$COMPOSER_ROOT" pull
250 if ! test -d "$WORKBENCH2_ROOT" ; then
251 git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
254 if [[ "$CONFIG" = test ]] ; then
256 mkdir -p $VAR_DATA/test
258 if test "$need_setup" = 1 ; then
261 --name=$ARVBOX_CONTAINER \
263 "--env=SVDIR=/etc/test-service" \
264 arvados/arvbox-dev$TAG
268 /usr/local/lib/arvbox/runsu.sh \
269 /usr/local/lib/arvbox/waitforpostgres.sh
273 if [[ -z "$@" ]] ; then
274 interactive=--interactive
278 -e LINES=$(tput lines) \
279 -e COLUMNS=$(tput cols) \
281 -e WORKSPACE=/usr/src/arvados \
282 -e GEM_HOME=$GEM_HOME \
283 -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
285 /usr/local/lib/arvbox/runsu.sh \
286 /usr/src/arvados/build/run-tests.sh \
287 --temp $ARVADOS_CONTAINER_PATH/test \
290 elif [[ "$CONFIG" = devenv ]] ; then
291 if [[ $need_setup = 1 ]] ; then
294 --name=${ARVBOX_CONTAINER} \
295 "--env=SVDIR=/etc/devenv-service" \
296 "--volume=$HOME:$HOME:rw" \
297 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
298 arvados/arvbox-dev$TAG
300 exec docker exec --interactive --tty \
301 -e LINES=$(tput lines) \
302 -e COLUMNS=$(tput cols) \
304 -e "ARVBOX_HOME=$HOME" \
305 -e "DISPLAY=$DISPLAY" \
307 ${ARVBOX_CONTAINER} \
308 /usr/local/lib/arvbox/devenv.sh "$@"
309 elif [[ "$CONFIG" =~ dev$ ]] ; then
312 --name=$ARVBOX_CONTAINER \
315 arvados/arvbox-dev$TAG
318 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
319 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
320 if [[ "$(listusers)" =~ ^\{\} ]] ; then
321 echo "No users defined, use 'arvbox adduser' to add user logins"
323 echo "Use 'arvbox listusers' to see user logins"
326 echo "Unknown configuration '$CONFIG'"
337 if test $(echo $TAG | cut -c1-1) != '-' ; then
345 if echo "$CONFIG" | grep 'demo$' ; then
346 docker pull arvados/arvbox-demo$TAG
348 docker pull arvados/arvbox-dev$TAG
353 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
354 docker stop $ARVBOX_CONTAINER
357 VOLUMES=--volumes=true
358 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
359 docker rm $VOLUMES $ARVBOX_CONTAINER
361 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
362 docker rm $VOLUMES $ARVBOX_CONTAINER
367 export DOCKER_BUILDKIT=1
368 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
369 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
372 if docker --version |grep " 1\.[0-9]\." ; then
373 # Docker version prior 1.10 require -f flag
374 # -f flag removed in Docker 1.12
377 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
380 if which greadlink >/dev/null 2>/dev/null ; then
381 LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
383 LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
387 if test "$1" = localdemo -o "$1" = publicdemo ; then
393 docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE --build-arg=arvados_version=$GITHEAD --build-arg=workdir=/tools/arvbox/lib/arvbox/docker -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$LOCAL_ARVADOS_ROOT"
394 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
395 docker build $NO_CACHE -t arvados/arvbox-$BUILDTYPE:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" "$ARVBOX_DOCKER"
396 docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
401 localdemo|publicdemo|dev|publicdev|test|devenv)
405 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
412 if test -n "$subcmd" ; then
423 NO_CACHE=--no-cache build $@
432 exec docker exec --interactive --tty \
433 -e LINES=$(tput lines) \
434 -e COLUMNS=$(tput cols) \
436 -e GEM_HOME=$GEM_HOME \
437 $ARVBOX_CONTAINER /bin/bash
441 exec docker exec --interactive --tty \
442 -e LINES=$(tput lines) \
443 -e COLUMNS=$(tput cols) \
445 -e GEM_HOME=$GEM_HOME \
447 -w /usr/src/arvados \
448 $ARVBOX_CONTAINER /bin/bash --login
452 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash -
488 exec xdg-open http://$(gethost)
492 echo "Container: $ARVBOX_CONTAINER"
493 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
494 echo "Cluster id: $(getclusterid)"
495 echo "Status: running"
496 echo "Container IP: $(getip)"
497 echo "Published host: $(gethost)"
499 echo "Status: not running"
501 if test -d "$ARVBOX_DATA" ; then
502 echo "Data: $ARVBOX_DATA"
503 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
504 echo "Data: $ARVBOX_CONTAINER-data"
512 if test -d "$ARVBOX_DATA" ; then
513 if test "$subcmd" = destroy ; then
514 if test "$1" != -f ; then
515 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
516 echo "Use destroy -f if you really mean it."
520 chmod -R u+w "$ARVBOX_DATA"
521 rm -rf "$ARVBOX_DATA"
523 if test "$1" != -f ; then
524 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
525 echo "Code and downloaded packages will be preserved."
526 echo "Use reset -f if you really mean it."
530 rm -rf "$ARVBOX_DATA/postgres"
531 rm -rf "$ARVBOX_DATA/var"
534 if test "$1" != -f ; then
535 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
539 docker rm "$ARVBOX_CONTAINER-data"
544 if test -n "$1" ; then
545 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"
547 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
552 if test -n "$1" ; then
553 exec docker exec $ARVBOX_CONTAINER cat "$@"
555 echo "Usage: $0 $subcmd <files>"
560 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
564 if test -n "$1" -a -n "$2" ; then
565 exec docker exec $ARVBOX_CONTAINER sv "$@"
567 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
568 echo "Available services:"
569 exec docker exec $ARVBOX_CONTAINER ls /etc/service
574 if test -n "$2" ; then
575 mkdir -p "$ARVBOX_BASE/$2"
576 cp -a "$ARVBOX_BASE/$1/passenger" \
577 "$ARVBOX_BASE/$1/gems" \
578 "$ARVBOX_BASE/$1/pip" \
579 "$ARVBOX_BASE/$1/npm" \
580 "$ARVBOX_BASE/$1/gopath" \
581 "$ARVBOX_BASE/$1/Rlibs" \
582 "$ARVBOX_BASE/$1/arvados" \
583 "$ARVBOX_BASE/$1/composer" \
584 "$ARVBOX_BASE/$1/workbench2" \
586 echo "Created new arvbox $2"
587 echo "export ARVBOX_CONTAINER=$2"
589 echo "clone <from> <to> clone an arvbox"
590 echo "available arvboxes: $(ls $ARVBOX_BASE)"
595 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
596 if test -n "$1" ; then
599 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
600 echo "Certificate copied to $CERT"
604 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'
608 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'
612 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'
616 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=$GEM_HOME /bin/bash - <<EOF
623 cd /usr/src/arvados/services/api
624 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
625 export RAILS_ENV=development
626 flock $GEM_HOME/gems.lock bundle exec rake db:drop
627 rm $ARVADOS_CONTAINER_PATH/api_database_setup
628 rm $ARVADOS_CONTAINER_PATH/superuser_token
632 sv restart keepstore0
633 sv restart keepstore1
639 if [[ -n "$2" ]] ; then
640 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
641 docker exec $ARVBOX_CONTAINER sv restart controller
643 echo "Usage: adduser <username> <email> [password]"
648 if [[ -n "$1" ]] ; then
649 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
650 docker exec $ARVBOX_CONTAINER sv restart controller
652 echo "Usage: removeuser <username>"
661 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
663 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
664 echo "stop stop arvbox container"
665 echo "restart <config> stop, then run again"
666 echo "status print some information about current arvbox"
667 echo "ip print arvbox docker container ip address"
668 echo "host print arvbox published host"
669 echo "shell enter shell as root"
670 echo "ashell enter shell as 'arvbox'"
671 echo "psql enter postgres console"
672 echo "open open arvbox workbench in a web browser"
673 echo "root-cert get copy of root certificate"
674 echo "update <config> stop, pull latest image, run"
675 echo "build <config> build arvbox Docker image"
676 echo "reboot <config> stop, build arvbox Docker image, run"
677 echo "rebuild <config> build arvbox Docker image, no layer cache"
678 echo "checkpoint create database backup"
679 echo "restore restore checkpoint"
680 echo "hotreset reset database and restart API without restarting container"
681 echo "reset delete arvbox arvados data (be careful!)"
682 echo "destroy delete all arvbox code and data (be careful!)"
683 echo "log <service> tail log of specified service"
684 echo "ls <options> list directories inside arvbox"
685 echo "cat <files> get contents of files inside arvbox"
686 echo "pipe run a bash script piped in from stdin"
687 echo "sv <start|stop|restart> <service> "
688 echo " change state of service inside arvbox"
689 echo "clone <from> <to> clone dev arvbox"
690 echo "adduser <username> <email> [password]"
691 echo " add a user login"
692 echo "removeuser <username>"
693 echo " remove user login"
694 echo "listusers list user logins"