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"
65 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
70 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
73 if test "$CODE" = 0 ; then
81 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/api_uuid_prefix
85 if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
86 sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
87 mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
89 mkdir -p $HOME/.config/arvados
90 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
91 ARVADOS_API_HOST=$(gethost):8000
93 ARVADOS_API_HOST_INSECURE=true
99 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py /var/lib/arvados/cluster_config.yml $(getclusterid) list
103 FF=/tmp/arvbox-fifo-$$
105 docker logs -f $ARVBOX_CONTAINER > $FF &
108 if [[ $line =~ "ok: down: ready:" ]] ; then
111 wait $LOGPID 2>/dev/null
119 if test -n "$localip" ; then
120 echo "export ARVADOS_API_HOST=$localip:8000"
122 echo "export ARVADOS_API_HOST=$(gethost):8000"
128 "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
129 "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
130 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
131 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
132 "--volume=$VAR_DATA:/var/lib/arvados:rw" \
133 "--volume=$PASSENGER:/var/lib/passenger:rw" \
134 "--volume=$GEMS:/var/lib/gems:rw" \
135 "--volume=$PIPCACHE:/var/lib/pip:rw" \
136 "--volume=$NPMCACHE:/var/lib/npm:rw" \
137 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
138 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
139 --label "org.arvados.arvbox_config=$CONFIG" \
144 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
155 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
156 if [[ $(running_config) != "$CONFIG" ]] ; then
157 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
160 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
163 echo "Container $ARVBOX_CONTAINER is already running"
168 if test $need_setup = 1 ; then
169 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
170 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
177 if test $(echo $TAG | cut -c1-1) != '-' ; then
181 if [[ $TAG = '-' ]] ; then
188 if [[ "$CONFIG" =~ ^public ]] ; then
189 if test -n "$ARVBOX_PUBLISH_IP" ; then
190 localip=$ARVBOX_PUBLISH_IP
192 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
193 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
195 echo "Public arvbox will use address $localip"
197 echo $localip > $iptemp
199 PUBLIC="--volume=$iptemp:/var/run/localip_override
206 --publish=25101:25101
210 --publish=45000-45020:45000-45020"
215 if [[ "$CONFIG" =~ demo$ ]] ; then
216 if test -d "$ARVBOX_DATA" ; then
217 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
218 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
222 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
223 docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
228 --name=$ARVBOX_CONTAINER \
230 --volumes-from $ARVBOX_CONTAINER-data \
231 --label "org.arvados.arvbox_config=$CONFIG" \
233 arvados/arvbox-demo$TAG
237 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
239 if ! test -d "$ARVADOS_ROOT" ; then
240 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
242 if ! test -d "$COMPOSER_ROOT" ; then
243 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
244 git -C "$COMPOSER_ROOT" checkout arvados-fork
245 git -C "$COMPOSER_ROOT" pull
247 if ! test -d "$WORKBENCH2_ROOT" ; then
248 git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
251 if [[ "$CONFIG" = test ]] ; then
253 mkdir -p $VAR_DATA/test
255 if test "$need_setup" = 1 ; then
258 --name=$ARVBOX_CONTAINER \
260 "--env=SVDIR=/etc/test-service" \
261 arvados/arvbox-dev$TAG
265 /usr/local/lib/arvbox/runsu.sh \
266 /usr/local/lib/arvbox/waitforpostgres.sh
270 /usr/local/lib/arvbox/runsu.sh \
271 /var/lib/arvbox/service/api/run-service --only-setup
275 if [[ -z "$@" ]] ; then
276 interactive=--interactive
280 -e LINES=$(tput lines) \
281 -e COLUMNS=$(tput cols) \
283 -e WORKSPACE=/usr/src/arvados \
284 -e GEM_HOME=/var/lib/gems \
285 -e CONFIGSRC=/var/lib/arvados/run_tests \
287 /usr/local/lib/arvbox/runsu.sh \
288 /usr/src/arvados/build/run-tests.sh \
289 --temp /var/lib/arvados/test \
292 elif [[ "$CONFIG" = devenv ]] ; then
293 if [[ $need_setup = 1 ]] ; then
296 --name=${ARVBOX_CONTAINER} \
297 "--env=SVDIR=/etc/devenv-service" \
298 "--volume=$HOME:$HOME:rw" \
299 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
300 arvados/arvbox-dev$TAG
302 exec docker exec --interactive --tty \
303 -e LINES=$(tput lines) \
304 -e COLUMNS=$(tput cols) \
306 -e "ARVBOX_HOME=$HOME" \
307 -e "DISPLAY=$DISPLAY" \
309 ${ARVBOX_CONTAINER} \
310 /usr/local/lib/arvbox/devenv.sh "$@"
311 elif [[ "$CONFIG" =~ dev$ ]] ; then
314 --name=$ARVBOX_CONTAINER \
317 arvados/arvbox-dev$TAG
320 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
321 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
322 if [[ "$(listusers)" =~ ^\{\} ]] ; then
323 echo "No users defined, use 'arvbox adduser' to add user logins"
325 echo "Use 'arvbox listusers' to see user logins"
328 echo "Unknown configuration '$CONFIG'"
339 if test $(echo $TAG | cut -c1-1) != '-' ; then
347 if echo "$CONFIG" | grep 'demo$' ; then
348 docker pull arvados/arvbox-demo$TAG
350 docker pull arvados/arvbox-dev$TAG
355 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
356 docker stop $ARVBOX_CONTAINER
359 VOLUMES=--volumes=true
360 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
361 docker rm $VOLUMES $ARVBOX_CONTAINER
363 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
364 docker rm $VOLUMES $ARVBOX_CONTAINER
369 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
370 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
373 if docker --version |grep " 1\.[0-9]\." ; then
374 # Docker version prior 1.10 require -f flag
375 # -f flag removed in Docker 1.12
378 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
379 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
380 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
381 if test "$1" = localdemo -o "$1" = publicdemo ; then
382 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
383 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
385 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
386 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
392 localdemo|publicdemo|dev|publicdev|test|devenv)
396 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
403 if test -n "$subcmd" ; then
414 NO_CACHE=--no-cache build $@
423 exec docker exec --interactive --tty \
424 -e LINES=$(tput lines) \
425 -e COLUMNS=$(tput cols) \
427 -e GEM_HOME=/var/lib/gems \
428 $ARVBOX_CONTAINER /bin/bash
432 exec docker exec --interactive --tty \
433 -e LINES=$(tput lines) \
434 -e COLUMNS=$(tput cols) \
436 -e GEM_HOME=/var/lib/gems \
438 -w /usr/src/arvados \
439 $ARVBOX_CONTAINER /bin/bash --login
443 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
479 exec xdg-open http://$(gethost)
483 echo "Container: $ARVBOX_CONTAINER"
484 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
485 echo "Cluster id: $(getclusterid)"
486 echo "Status: running"
487 echo "Container IP: $(getip)"
488 echo "Published host: $(gethost)"
490 echo "Status: not running"
492 if test -d "$ARVBOX_DATA" ; then
493 echo "Data: $ARVBOX_DATA"
494 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
495 echo "Data: $ARVBOX_CONTAINER-data"
503 if test -d "$ARVBOX_DATA" ; then
504 if test "$subcmd" = destroy ; then
505 if test "$1" != -f ; then
506 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
507 echo "Use destroy -f if you really mean it."
511 chmod -R u+w "$ARVBOX_DATA"
512 rm -rf "$ARVBOX_DATA"
514 if test "$1" != -f ; then
515 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
516 echo "Code and downloaded packages will be preserved."
517 echo "Use reset -f if you really mean it."
521 rm -rf "$ARVBOX_DATA/postgres"
522 rm -rf "$ARVBOX_DATA/var"
525 if test "$1" != -f ; then
526 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
530 docker rm "$ARVBOX_CONTAINER-data"
535 if test -n "$1" ; then
536 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"
538 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
543 if test -n "$1" ; then
544 exec docker exec $ARVBOX_CONTAINER cat "$@"
546 echo "Usage: $0 $subcmd <files>"
551 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
555 if test -n "$1" -a -n "$2" ; then
556 exec docker exec $ARVBOX_CONTAINER sv "$@"
558 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
559 echo "Available services:"
560 exec docker execa $ARVBOX_CONTAINER ls /etc/service
565 if test -n "$2" ; then
566 mkdir -p "$ARVBOX_BASE/$2"
567 cp -a "$ARVBOX_BASE/$1/passenger" \
568 "$ARVBOX_BASE/$1/gems" \
569 "$ARVBOX_BASE/$1/pip" \
570 "$ARVBOX_BASE/$1/npm" \
571 "$ARVBOX_BASE/$1/gopath" \
572 "$ARVBOX_BASE/$1/Rlibs" \
573 "$ARVBOX_BASE/$1/arvados" \
574 "$ARVBOX_BASE/$1/composer" \
575 "$ARVBOX_BASE/$1/workbench2" \
577 echo "Created new arvbox $2"
578 echo "export ARVBOX_CONTAINER=$2"
580 echo "clone <from> <to> clone an arvbox"
581 echo "available arvboxes: $(ls $ARVBOX_BASE)"
586 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
587 if test -n "$1" ; then
590 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
591 echo "Certificate copied to $CERT"
595 exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat /var/lib/arvados/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados'
599 exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat /var/lib/arvados/api_database_pw) exec pg_dump --host=localhost --username=arvados --clean arvados_development > /var/lib/arvados/checkpoint.sql'
603 exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat /var/lib/arvados/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados --quiet --file=/var/lib/arvados/checkpoint.sql'
607 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
614 cd /usr/src/arvados/services/api
615 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
616 export RAILS_ENV=development
617 bundle exec rake db:drop
618 rm /var/lib/arvados/api_database_setup
619 rm /var/lib/arvados/superuser_token
620 rm /var/lib/arvados/keep0-uuid
621 rm /var/lib/arvados/keep1-uuid
622 rm /var/lib/arvados/keepproxy-uuid
626 sv restart keepstore0
627 sv restart keepstore1
633 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py /var/lib/arvados/cluster_config.yml.override $(getclusterid) add $@
634 docker exec $ARVBOX_CONTAINER sv restart controller
638 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py /var/lib/arvados/cluster_config.yml.override $(getclusterid) remove $@
639 docker exec $ARVBOX_CONTAINER sv restart controller
647 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
649 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
650 echo "stop stop arvbox container"
651 echo "restart <config> stop, then run again"
652 echo "status print some information about current arvbox"
653 echo "ip print arvbox docker container ip address"
654 echo "host print arvbox published host"
655 echo "shell enter shell as root"
656 echo "ashell enter shell as 'arvbox'"
657 echo "psql enter postgres console"
658 echo "open open arvbox workbench in a web browser"
659 echo "root-cert get copy of root certificate"
660 echo "update <config> stop, pull latest image, run"
661 echo "build <config> build arvbox Docker image"
662 echo "reboot <config> stop, build arvbox Docker image, run"
663 echo "rebuild <config> build arvbox Docker image, no layer cache"
664 echo "checkpoint create database backup"
665 echo "restore restore checkpoint"
666 echo "hotreset reset database and restart API without restarting container"
667 echo "reset delete arvbox arvados data (be careful!)"
668 echo "destroy delete all arvbox code and data (be careful!)"
669 echo "log <service> tail log of specified service"
670 echo "ls <options> list directories inside arvbox"
671 echo "cat <files> get contents of files inside arvbox"
672 echo "pipe run a bash script piped in from stdin"
673 echo "sv <start|stop|restart> <service> "
674 echo " change state of service inside arvbox"
675 echo "clone <from> <to> clone dev arvbox"
676 echo "adduser <username> <email>"
677 echo " add a user login"
678 echo "removeuser <username>"
679 echo " remove user login"
680 echo "listusers list user logins"