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 if test -z "$ARVADOS_BRANCH" ; then
59 if test -z "$WORKBENCH2_BRANCH" ; then
60 WORKBENCH2_BRANCH=main
63 # Update this to the docker tag for the version on releases.
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"
77 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
82 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
85 if test "$CODE" = 0 ; then
93 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix
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
101 mkdir -p $HOME/.config/arvados
102 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
103 ARVADOS_API_HOST=$(gethost):8000
105 ARVADOS_API_HOST_INSECURE=true
111 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list
115 FF=/tmp/arvbox-fifo-$$
117 docker logs -f $ARVBOX_CONTAINER > $FF &
120 if [[ $line =~ "ok: down: ready:" ]] ; then
123 wait $LOGPID 2>/dev/null
131 if test -n "$localip" ; then
132 echo "export ARVADOS_API_HOST=$localip:8000"
134 echo "export ARVADOS_API_HOST=$(gethost):8000"
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=$GEMS:/var/lib/arvados/lib/ruby/gems:rw" \
147 "--volume=$PIPCACHE:/var/lib/pip:rw" \
148 "--volume=$NPMCACHE:/var/lib/npm:rw" \
149 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
150 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
151 --label "org.arvados.arvbox_config=$CONFIG" \
156 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
167 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
168 if [[ $(running_config) != "$CONFIG" ]] ; then
169 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
172 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
175 echo "Container $ARVBOX_CONTAINER is already running"
180 if test $need_setup = 1 ; then
181 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
182 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
189 if test $(echo $TAG | cut -c1-1) != '-' ; then
193 if [[ $TAG = '-' ]] ; then
200 if test -z "$TAG" -a -n "$DEFAULT_TAG"; then
204 if [[ "$CONFIG" =~ ^public ]] ; then
205 if test -n "$ARVBOX_PUBLISH_IP" ; then
206 localip=$ARVBOX_PUBLISH_IP
208 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
209 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
211 echo "Public arvbox will use address $localip"
213 echo $localip > $iptemp
215 PUBLIC="--volume=$iptemp:/var/run/localip_override
223 --publish=25101:25101
227 --publish=45000-45020:45000-45020"
232 if [[ "$CONFIG" =~ demo$ ]] ; then
233 if test -d "$ARVBOX_DATA" ; then
234 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
235 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
239 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
240 docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
245 --name=$ARVBOX_CONTAINER \
247 --volumes-from $ARVBOX_CONTAINER-data \
248 --label "org.arvados.arvbox_config=$CONFIG" \
250 arvados/arvbox-demo$TAG
254 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
256 if ! test -d "$ARVADOS_ROOT" ; then
257 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
258 git -C "$ARVADOS_ROOT" checkout $ARVADOS_BRANCH
260 if ! test -d "$COMPOSER_ROOT" ; then
261 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
262 git -C "$COMPOSER_ROOT" checkout arvados-fork
264 if ! test -d "$WORKBENCH2_ROOT" ; then
265 git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
266 git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH
269 if [[ "$CONFIG" = test ]] ; then
271 mkdir -p $VAR_DATA/test
273 if test "$need_setup" = 1 ; then
276 --name=$ARVBOX_CONTAINER \
278 "--env=SVDIR=/etc/test-service" \
279 arvados/arvbox-dev$TAG
283 /usr/local/lib/arvbox/runsu.sh \
284 /usr/local/lib/arvbox/waitforpostgres.sh
288 if [[ -z "$@" ]] ; then
289 interactive=--interactive
293 -e LINES=$(tput lines) \
294 -e COLUMNS=$(tput cols) \
296 -e WORKSPACE=/usr/src/arvados \
297 -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
299 /usr/local/lib/arvbox/runsu.sh \
300 /usr/src/arvados/build/run-tests.sh \
301 --temp $ARVADOS_CONTAINER_PATH/test \
304 elif [[ "$CONFIG" = devenv ]] ; then
305 if [[ $need_setup = 1 ]] ; then
308 --name=${ARVBOX_CONTAINER} \
309 "--env=SVDIR=/etc/devenv-service" \
310 "--volume=$HOME:$HOME:rw" \
311 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
312 arvados/arvbox-dev$TAG
314 exec docker exec --interactive --tty \
315 -e LINES=$(tput lines) \
316 -e COLUMNS=$(tput cols) \
318 -e "ARVBOX_HOME=$HOME" \
319 -e "DISPLAY=$DISPLAY" \
321 ${ARVBOX_CONTAINER} \
322 /usr/local/lib/arvbox/devenv.sh "$@"
323 elif [[ "$CONFIG" =~ dev$ ]] ; then
326 --name=$ARVBOX_CONTAINER \
329 arvados/arvbox-dev$TAG
332 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
333 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
334 if [[ "$(listusers)" =~ ^\{\} ]] ; then
335 echo "No users defined, use 'arvbox adduser' to add user logins"
337 echo "Use 'arvbox listusers' to see user logins"
340 echo "Unknown configuration '$CONFIG'"
351 if test $(echo $TAG | cut -c1-1) != '-' ; then
359 if echo "$CONFIG" | grep 'demo$' ; then
360 docker pull arvados/arvbox-demo$TAG
362 docker pull arvados/arvbox-dev$TAG
367 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
368 docker stop $ARVBOX_CONTAINER
371 VOLUMES=--volumes=true
372 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
373 docker rm $VOLUMES $ARVBOX_CONTAINER
375 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
376 docker rm $VOLUMES $ARVBOX_CONTAINER
381 export DOCKER_BUILDKIT=1
382 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
383 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
386 if docker --version |grep " 1\.[0-9]\." ; then
387 # Docker version prior 1.10 require -f flag
388 # -f flag removed in Docker 1.12
391 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
394 if which greadlink >/dev/null 2>/dev/null ; then
395 LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
397 LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
401 # Get the go version we should use for bootstrapping
402 GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'`
404 if test "$1" = localdemo -o "$1" = publicdemo ; then
410 if test "$ARVADOS_BRANCH" = "main" ; then
411 ARVADOS_BRANCH=$GITHEAD
414 docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \
415 --build-arg=go_version=$GO_VERSION \
416 --build-arg=arvados_version=$ARVADOS_BRANCH \
417 --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
418 --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
419 -t arvados/arvbox-base:$GITHEAD \
420 -f "$ARVBOX_DOCKER/Dockerfile.base" \
421 "$LOCAL_ARVADOS_ROOT"
422 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
423 docker build $NO_CACHE \
424 --build-arg=go_version=$GO_VERSION \
425 --build-arg=arvados_version=$ARVADOS_BRANCH \
426 --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
427 -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
428 -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
430 docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
435 localdemo|publicdemo|dev|publicdev|test|devenv)
439 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
446 if test -n "$subcmd" ; then
457 NO_CACHE=--no-cache build $@
466 exec docker exec --interactive --tty \
467 -e LINES=$(tput lines) \
468 -e COLUMNS=$(tput cols) \
470 $ARVBOX_CONTAINER /bin/bash
474 exec docker exec --interactive --tty \
475 -e LINES=$(tput lines) \
476 -e COLUMNS=$(tput cols) \
479 -w /usr/src/arvados \
480 $ARVBOX_CONTAINER /bin/bash --login
484 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash -
520 exec xdg-open http://$(gethost)
524 echo "Container: $ARVBOX_CONTAINER"
525 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
526 echo "Cluster id: $(getclusterid)"
527 echo "Status: running"
528 echo "Container IP: $(getip)"
529 echo "Published host: $(gethost)"
530 echo "Workbench: https://$(gethost)"
532 echo "Status: not running"
534 if test -d "$ARVBOX_DATA" ; then
535 echo "Data: $ARVBOX_DATA"
536 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
537 echo "Data: $ARVBOX_CONTAINER-data"
545 if test -d "$ARVBOX_DATA" ; then
546 if test "$subcmd" = destroy ; then
547 if test "$1" != -f ; then
548 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
549 echo "Use destroy -f if you really mean it."
553 chmod -R u+w "$ARVBOX_DATA"
554 rm -rf "$ARVBOX_DATA"
556 if test "$1" != -f ; then
557 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
558 echo "Code and downloaded packages will be preserved."
559 echo "Use reset -f if you really mean it."
563 rm -rf "$ARVBOX_DATA/postgres"
564 rm -rf "$ARVBOX_DATA/var"
567 if test "$1" != -f ; then
568 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
572 docker rm "$ARVBOX_CONTAINER-data"
577 if test -n "$1" ; then
578 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"
580 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
585 if test -n "$1" ; then
586 exec docker exec $ARVBOX_CONTAINER cat "$@"
588 echo "Usage: $0 $subcmd <files>"
593 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
597 if test -n "$1" -a -n "$2" ; then
598 exec docker exec $ARVBOX_CONTAINER sv "$@"
600 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
601 echo "Available services:"
602 exec docker exec $ARVBOX_CONTAINER ls /etc/service
607 if test -n "$2" ; then
608 mkdir -p "$ARVBOX_BASE/$2"
609 cp -a "$ARVBOX_BASE/$1/passenger" \
610 "$ARVBOX_BASE/$1/gems" \
611 "$ARVBOX_BASE/$1/pip" \
612 "$ARVBOX_BASE/$1/npm" \
613 "$ARVBOX_BASE/$1/gopath" \
614 "$ARVBOX_BASE/$1/Rlibs" \
615 "$ARVBOX_BASE/$1/arvados" \
616 "$ARVBOX_BASE/$1/composer" \
617 "$ARVBOX_BASE/$1/workbench2" \
619 echo "Created new arvbox $2"
620 echo "export ARVBOX_CONTAINER=$2"
622 echo "clone <from> <to> clone an arvbox"
623 echo "available arvboxes: $(ls $ARVBOX_BASE)"
628 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
629 if test -n "$1" ; then
632 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
633 echo "Certificate copied to $CERT"
637 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'
641 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'
645 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'
649 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash - <<EOF
656 cd /usr/src/arvados/services/api
657 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
658 export RAILS_ENV=development
659 bin/bundle exec rake db:drop
660 rm $ARVADOS_CONTAINER_PATH/api_database_setup
661 rm $ARVADOS_CONTAINER_PATH/superuser_token
665 sv restart keepstore0
666 sv restart keepstore1
672 if [[ -n "$2" ]] ; then
673 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
674 docker exec $ARVBOX_CONTAINER sv restart controller
676 echo "Usage: adduser <username> <email> [password]"
681 if [[ -n "$1" ]] ; then
682 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
683 docker exec $ARVBOX_CONTAINER sv restart controller
685 echo "Usage: removeuser <username>"
694 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
696 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
697 echo "stop stop arvbox container"
698 echo "restart <config> stop, then run again"
699 echo "status print some information about current arvbox"
700 echo "ip print arvbox docker container ip address"
701 echo "host print arvbox published host"
702 echo "shell enter shell as root"
703 echo "ashell enter shell as 'arvbox'"
704 echo "psql enter postgres console"
705 echo "open open arvbox workbench in a web browser"
706 echo "root-cert get copy of root certificate"
707 echo "update <config> stop, pull latest image, run"
708 echo "build <config> build arvbox Docker image"
709 echo "reboot <config> stop, build arvbox Docker image, run"
710 echo "rebuild <config> build arvbox Docker image, no layer cache"
711 echo "checkpoint create database backup"
712 echo "restore restore checkpoint"
713 echo "hotreset reset database and restart API without restarting container"
714 echo "reset delete arvbox arvados data (be careful!)"
715 echo "destroy delete all arvbox code and data (be careful!)"
716 echo "log <service> tail log of specified service"
717 echo "ls <options> list directories inside arvbox"
718 echo "cat <files> get contents of files inside arvbox"
719 echo "pipe run a bash script piped in from stdin"
720 echo "sv <start|stop|restart> <service> "
721 echo " change state of service inside arvbox"
722 echo "clone <from> <to> clone dev arvbox"
723 echo "adduser <username> <email> [password]"
724 echo " add a user login"
725 echo "removeuser <username>"
726 echo " remove user login"
727 echo "listusers list user logins"