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 "$WORKBENCH2_ROOT" ; then
48 WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2"
51 if test -z "$ARVADOS_BRANCH" ; then
55 if test -z "$WORKBENCH2_BRANCH" ; then
56 WORKBENCH2_BRANCH=main
59 # Update this to the docker tag for the version on releases.
62 PG_DATA="$ARVBOX_DATA/postgres"
63 VAR_DATA="$ARVBOX_DATA/var"
64 PASSENGER="$ARVBOX_DATA/passenger"
65 GEMS="$ARVBOX_DATA/gems"
66 PIPCACHE="$ARVBOX_DATA/pip"
67 NPMCACHE="$ARVBOX_DATA/npm"
68 GOSTUFF="$ARVBOX_DATA/gopath"
69 RLIBS="$ARVBOX_DATA/Rlibs"
70 ARVADOS_CONTAINER_PATH="/var/lib/arvados-arvbox"
73 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
78 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
81 if test "$CODE" = 0 ; then
89 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix
93 if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
94 sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
95 mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
97 mkdir -p $HOME/.config/arvados
98 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
99 ARVADOS_API_HOST=$(gethost):8000
101 ARVADOS_API_HOST_INSECURE=true
107 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list
111 FF=/tmp/arvbox-fifo-$$
113 docker logs -f $ARVBOX_CONTAINER > $FF &
116 if [[ $line =~ "ok: down: ready:" ]] ; then
119 wait $LOGPID 2>/dev/null
127 if test -n "$localip" ; then
128 echo "export ARVADOS_API_HOST=$localip:8000"
130 echo "export ARVADOS_API_HOST=$(gethost):8000"
136 "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
137 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
138 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
139 "--volume=$VAR_DATA:$ARVADOS_CONTAINER_PATH:rw" \
140 "--volume=$PASSENGER:/var/lib/passenger:rw" \
141 "--volume=$GEMS:/var/lib/arvados-arvbox/.gem:rw" \
142 "--volume=$PIPCACHE:/var/lib/pip:rw" \
143 "--volume=$NPMCACHE:/var/lib/npm:rw" \
144 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
145 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
146 --label "org.arvados.arvbox_config=$CONFIG" \
151 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
162 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
163 if [[ $(running_config) != "$CONFIG" ]] ; then
164 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
167 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
170 echo "Container $ARVBOX_CONTAINER is already running"
175 if test $need_setup = 1 ; then
176 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
177 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
184 if test $(echo $TAG | cut -c1-1) != '-' ; then
188 if [[ $TAG = '-' ]] ; then
195 if test -z "$TAG" -a -n "$DEFAULT_TAG"; then
199 if [[ "$CONFIG" =~ ^public ]] ; then
200 if test -n "$ARVBOX_PUBLISH_IP" ; then
201 localip=$ARVBOX_PUBLISH_IP
203 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
204 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
206 echo "Public arvbox will use address $localip"
208 echo $localip > $iptemp
210 PUBLIC="--volume=$iptemp:/var/run/localip_override
218 --publish=25101:25101
222 --publish=45000-45020:45000-45020"
227 if [[ "$CONFIG" =~ demo$ ]] ; then
228 if test -d "$ARVBOX_DATA" ; then
229 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
230 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
234 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
235 docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo$TAG /bin/true
240 --name=$ARVBOX_CONTAINER \
242 --volumes-from $ARVBOX_CONTAINER-data \
243 --label "org.arvados.arvbox_config=$CONFIG" \
245 arvados/arvbox-demo$TAG
249 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
251 if ! test -d "$ARVADOS_ROOT" ; then
252 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
253 git -C "$ARVADOS_ROOT" checkout $ARVADOS_BRANCH
255 if ! test -d "$WORKBENCH2_ROOT" ; then
256 git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
257 git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH
260 if [[ "$CONFIG" = test ]] ; then
262 mkdir -p $VAR_DATA/test
264 if test "$need_setup" = 1 ; then
267 --name=$ARVBOX_CONTAINER \
269 "--env=SVDIR=/etc/test-service" \
270 arvados/arvbox-dev$TAG
274 /usr/local/lib/arvbox/runsu.sh \
275 /usr/local/lib/arvbox/waitforpostgres.sh
279 if [[ -z "$@" ]] ; then
280 interactive=--interactive
284 -e LINES=$(tput lines) \
285 -e COLUMNS=$(tput cols) \
287 -e WORKSPACE=/usr/src/arvados \
288 -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \
290 /usr/local/lib/arvbox/runsu.sh \
291 /usr/src/arvados/build/run-tests.sh \
292 --temp $ARVADOS_CONTAINER_PATH/test \
295 elif [[ "$CONFIG" = devenv ]] ; then
296 if [[ $need_setup = 1 ]] ; then
299 --name=${ARVBOX_CONTAINER} \
300 "--env=SVDIR=/etc/devenv-service" \
301 "--volume=$HOME:$HOME:rw" \
302 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
303 arvados/arvbox-dev$TAG
305 exec docker exec --interactive --tty \
306 -e LINES=$(tput lines) \
307 -e COLUMNS=$(tput cols) \
309 -e "ARVBOX_HOME=$HOME" \
310 -e "DISPLAY=$DISPLAY" \
312 ${ARVBOX_CONTAINER} \
313 /usr/local/lib/arvbox/devenv.sh "$@"
314 elif [[ "$CONFIG" =~ dev$ ]] ; then
317 --name=$ARVBOX_CONTAINER \
320 arvados/arvbox-dev$TAG
323 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
324 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
325 if [[ "$(listusers)" =~ ^\{\} ]] ; then
326 echo "No users defined, use 'arvbox adduser' to add user logins"
328 echo "Use 'arvbox listusers' to see user logins"
331 echo "Unknown configuration '$CONFIG'"
342 if test $(echo $TAG | cut -c1-1) != '-' ; then
350 if echo "$CONFIG" | grep 'demo$' ; then
351 docker pull arvados/arvbox-demo$TAG
353 docker pull arvados/arvbox-dev$TAG
358 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
359 docker stop $ARVBOX_CONTAINER
362 VOLUMES=--volumes=true
363 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
364 docker rm $VOLUMES $ARVBOX_CONTAINER
366 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
367 docker rm $VOLUMES $ARVBOX_CONTAINER
372 export DOCKER_BUILDKIT=1
373 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
374 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
377 if docker --version |grep " 1\.[0-9]\." ; then
378 # Docker version prior 1.10 require -f flag
379 # -f flag removed in Docker 1.12
382 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
385 if which greadlink >/dev/null 2>/dev/null ; then
386 LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../)
388 LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../)
392 # Get the go version we should use for bootstrapping
393 GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'`
395 if test "$1" = localdemo -o "$1" = publicdemo ; then
401 if test "$ARVADOS_BRANCH" = "main" ; then
402 ARVADOS_BRANCH=$GITHEAD
405 docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \
406 --build-arg=go_version=$GO_VERSION \
407 --build-arg=arvados_version=$ARVADOS_BRANCH \
408 --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
409 --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \
410 -t arvados/arvbox-base:$GITHEAD \
411 -f "$ARVBOX_DOCKER/Dockerfile.base" \
412 "$LOCAL_ARVADOS_ROOT"
413 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
414 docker build $NO_CACHE \
415 --build-arg=go_version=$GO_VERSION \
416 --build-arg=arvados_version=$ARVADOS_BRANCH \
417 --build-arg=workbench2_version=$WORKBENCH2_BRANCH \
418 -t arvados/arvbox-$BUILDTYPE:$GITHEAD \
419 -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \
421 docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest
426 localdemo|publicdemo|dev|publicdev|test|devenv)
430 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
437 if test -n "$subcmd" ; then
448 NO_CACHE=--no-cache build $@
457 exec docker exec --interactive --tty \
458 -e LINES=$(tput lines) \
459 -e COLUMNS=$(tput cols) \
461 $ARVBOX_CONTAINER /bin/bash
465 exec docker exec --interactive --tty \
466 -e LINES=$(tput lines) \
467 -e COLUMNS=$(tput cols) \
470 -w /usr/src/arvados \
471 $ARVBOX_CONTAINER /bin/bash --login
475 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash -
511 exec xdg-open http://$(gethost)
515 echo "Container: $ARVBOX_CONTAINER"
516 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
517 echo "Cluster id: $(getclusterid)"
518 echo "Status: running"
519 echo "Container IP: $(getip)"
520 echo "Published host: $(gethost)"
521 echo "Workbench: https://$(gethost)"
523 echo "Status: not running"
525 if test -d "$ARVBOX_DATA" ; then
526 echo "Data: $ARVBOX_DATA"
527 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
528 echo "Data: $ARVBOX_CONTAINER-data"
536 if test -d "$ARVBOX_DATA" ; then
537 if test "$subcmd" = destroy ; then
538 if test "$1" != -f ; then
539 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
540 echo "Use destroy -f if you really mean it."
544 chmod -R u+w "$ARVBOX_DATA"
545 rm -rf "$ARVBOX_DATA"
547 if test "$1" != -f ; then
548 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
549 echo "Code and downloaded packages will be preserved."
550 echo "Use reset -f if you really mean it."
554 rm -rf "$ARVBOX_DATA/postgres"
555 rm -rf "$ARVBOX_DATA/var"
558 if test "$1" != -f ; then
559 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
563 docker rm "$ARVBOX_CONTAINER-data"
568 if test -n "$1" ; then
569 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"
571 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
576 if test -n "$1" ; then
577 exec docker exec $ARVBOX_CONTAINER cat "$@"
579 echo "Usage: $0 $subcmd <files>"
584 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
588 if test -n "$1" -a -n "$2" ; then
589 exec docker exec $ARVBOX_CONTAINER sv "$@"
591 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
592 echo "Available services:"
593 exec docker exec $ARVBOX_CONTAINER ls /etc/service
598 if test -n "$2" ; then
599 mkdir -p "$ARVBOX_BASE/$2"
600 cp -a "$ARVBOX_BASE/$1/passenger" \
601 "$ARVBOX_BASE/$1/gems" \
602 "$ARVBOX_BASE/$1/pip" \
603 "$ARVBOX_BASE/$1/npm" \
604 "$ARVBOX_BASE/$1/gopath" \
605 "$ARVBOX_BASE/$1/Rlibs" \
606 "$ARVBOX_BASE/$1/arvados" \
607 "$ARVBOX_BASE/$1/workbench2" \
609 echo "Created new arvbox $2"
610 echo "export ARVBOX_CONTAINER=$2"
612 echo "clone <from> <to> clone an arvbox"
613 echo "available arvboxes: $(ls $ARVBOX_BASE)"
618 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
619 if test -n "$1" ; then
622 docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT"
623 echo "Certificate copied to $CERT"
627 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'
631 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'
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 --quiet --file=$ARVADOS_CONTAINER_PATH/checkpoint.sql'
639 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash - <<EOF
646 cd /usr/src/arvados/services/api
647 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
648 export RAILS_ENV=development
649 bin/bundle exec rake db:drop
650 rm $ARVADOS_CONTAINER_PATH/api_database_setup
651 rm $ARVADOS_CONTAINER_PATH/superuser_token
655 sv restart keepstore0
656 sv restart keepstore1
662 if [[ -n "$2" ]] ; then
663 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) add $@
664 docker exec $ARVBOX_CONTAINER sv restart controller
666 echo "Usage: adduser <username> <email> [password]"
671 if [[ -n "$1" ]] ; then
672 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@
673 docker exec $ARVBOX_CONTAINER sv restart controller
675 echo "Usage: removeuser <username>"
684 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
686 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
687 echo "stop stop arvbox container"
688 echo "restart <config> stop, then run again"
689 echo "status print some information about current arvbox"
690 echo "ip print arvbox docker container ip address"
691 echo "host print arvbox published host"
692 echo "shell enter shell as root"
693 echo "ashell enter shell as 'arvbox'"
694 echo "psql enter postgres console"
695 echo "open open arvbox workbench in a web browser"
696 echo "root-cert get copy of root certificate"
697 echo "update <config> stop, pull latest image, run"
698 echo "build <config> build arvbox Docker image"
699 echo "reboot <config> stop, build arvbox Docker image, run"
700 echo "rebuild <config> build arvbox Docker image, no layer cache"
701 echo "checkpoint create database backup"
702 echo "restore restore checkpoint"
703 echo "hotreset reset database and restart API without restarting container"
704 echo "reset delete arvbox arvados data (be careful!)"
705 echo "destroy delete all arvbox code and data (be careful!)"
706 echo "log <service> tail log of specified service"
707 echo "ls <options> list directories inside arvbox"
708 echo "cat <files> get contents of files inside arvbox"
709 echo "pipe run a bash script piped in from stdin"
710 echo "sv <start|stop|restart> <service> "
711 echo " change state of service inside arvbox"
712 echo "clone <from> <to> clone dev arvbox"
713 echo "adduser <username> <email> [password]"
714 echo " add a user login"
715 echo "removeuser <username>"
716 echo " remove user login"
717 echo "listusers list user logins"