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
209 --publish=45000-45020:45000-45020"
214 if [[ "$CONFIG" =~ demo$ ]] ; then
215 if test -d "$ARVBOX_DATA" ; then
216 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
217 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
221 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
222 docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
227 --name=$ARVBOX_CONTAINER \
229 --volumes-from $ARVBOX_CONTAINER-data \
230 --label "org.arvados.arvbox_config=$CONFIG" \
232 arvados/arvbox-demo$TAG
236 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
238 if ! test -d "$ARVADOS_ROOT" ; then
239 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
241 if ! test -d "$COMPOSER_ROOT" ; then
242 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
243 git -C "$COMPOSER_ROOT" checkout arvados-fork
244 git -C "$COMPOSER_ROOT" pull
246 if ! test -d "$WORKBENCH2_ROOT" ; then
247 git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT"
250 if [[ "$CONFIG" = test ]] ; then
252 mkdir -p $VAR_DATA/test
254 if test "$need_setup" = 1 ; then
257 --name=$ARVBOX_CONTAINER \
259 "--env=SVDIR=/etc/test-service" \
260 arvados/arvbox-dev$TAG
264 /usr/local/lib/arvbox/runsu.sh \
265 /usr/local/lib/arvbox/waitforpostgres.sh
269 /usr/local/lib/arvbox/runsu.sh \
270 /var/lib/arvbox/service/api/run-service --only-setup
274 if [[ -z "$@" ]] ; then
275 interactive=--interactive
279 -e LINES=$(tput lines) \
280 -e COLUMNS=$(tput cols) \
282 -e WORKSPACE=/usr/src/arvados \
283 -e GEM_HOME=/var/lib/gems \
284 -e CONFIGSRC=/var/lib/arvados/run_tests \
286 /usr/local/lib/arvbox/runsu.sh \
287 /usr/src/arvados/build/run-tests.sh \
288 --temp /var/lib/arvados/test \
291 elif [[ "$CONFIG" = devenv ]] ; then
292 if [[ $need_setup = 1 ]] ; then
295 --name=${ARVBOX_CONTAINER} \
296 "--env=SVDIR=/etc/devenv-service" \
297 "--volume=$HOME:$HOME:rw" \
298 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
299 arvados/arvbox-dev$TAG
301 exec docker exec --interactive --tty \
302 -e LINES=$(tput lines) \
303 -e COLUMNS=$(tput cols) \
305 -e "ARVBOX_HOME=$HOME" \
306 -e "DISPLAY=$DISPLAY" \
308 ${ARVBOX_CONTAINER} \
309 /usr/local/lib/arvbox/devenv.sh "$@"
310 elif [[ "$CONFIG" =~ dev$ ]] ; then
313 --name=$ARVBOX_CONTAINER \
316 arvados/arvbox-dev$TAG
319 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
320 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
321 if [[ "$(listusers)" =~ ^\{\} ]] ; then
322 echo "No users defined, use 'arvbox adduser' to add user logins"
324 echo "Use 'arvbox listusers' to see user logins"
327 echo "Unknown configuration '$CONFIG'"
338 if test $(echo $TAG | cut -c1-1) != '-' ; then
346 if echo "$CONFIG" | grep 'demo$' ; then
347 docker pull arvados/arvbox-demo$TAG
349 docker pull arvados/arvbox-dev$TAG
354 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
355 docker stop $ARVBOX_CONTAINER
358 VOLUMES=--volumes=true
359 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
360 docker rm $VOLUMES $ARVBOX_CONTAINER
362 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
363 docker rm $VOLUMES $ARVBOX_CONTAINER
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)
378 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
379 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
380 if test "$1" = localdemo -o "$1" = publicdemo ; then
381 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
382 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
384 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
385 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
391 localdemo|publicdemo|dev|publicdev|test|devenv)
395 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
402 if test -n "$subcmd" ; then
413 NO_CACHE=--no-cache build $@
422 exec docker exec --interactive --tty \
423 -e LINES=$(tput lines) \
424 -e COLUMNS=$(tput cols) \
426 -e GEM_HOME=/var/lib/gems \
427 $ARVBOX_CONTAINER /bin/bash
431 exec docker exec --interactive --tty \
432 -e LINES=$(tput lines) \
433 -e COLUMNS=$(tput cols) \
435 -e GEM_HOME=/var/lib/gems \
437 -w /usr/src/arvados \
438 $ARVBOX_CONTAINER /bin/bash --login
442 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
478 exec xdg-open http://$(gethost)
482 echo "Container: $ARVBOX_CONTAINER"
483 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
484 echo "Cluster id: $(getclusterid)"
485 echo "Status: running"
486 echo "Container IP: $(getip)"
487 echo "Published host: $(gethost)"
489 echo "Status: not running"
491 if test -d "$ARVBOX_DATA" ; then
492 echo "Data: $ARVBOX_DATA"
493 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
494 echo "Data: $ARVBOX_CONTAINER-data"
502 if test -d "$ARVBOX_DATA" ; then
503 if test "$subcmd" = destroy ; then
504 if test "$1" != -f ; then
505 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
506 echo "Use destroy -f if you really mean it."
510 chmod -R u+w "$ARVBOX_DATA"
511 rm -rf "$ARVBOX_DATA"
513 if test "$1" != -f ; then
514 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
515 echo "Code and downloaded packages will be preserved."
516 echo "Use reset -f if you really mean it."
520 rm -rf "$ARVBOX_DATA/postgres"
521 rm -rf "$ARVBOX_DATA/var"
524 if test "$1" != -f ; then
525 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
529 docker rm "$ARVBOX_CONTAINER-data"
534 if test -n "$1" ; then
535 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"
537 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
542 if test -n "$1" ; then
543 exec docker exec $ARVBOX_CONTAINER cat "$@"
545 echo "Usage: $0 $subcmd <files>"
550 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
554 if test -n "$1" -a -n "$2" ; then
555 exec docker exec $ARVBOX_CONTAINER sv "$@"
557 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
558 echo "Available services:"
559 exec docker execa $ARVBOX_CONTAINER ls /etc/service
564 if test -n "$2" ; then
565 mkdir -p "$ARVBOX_BASE/$2"
566 cp -a "$ARVBOX_BASE/$1/passenger" \
567 "$ARVBOX_BASE/$1/gems" \
568 "$ARVBOX_BASE/$1/pip" \
569 "$ARVBOX_BASE/$1/npm" \
570 "$ARVBOX_BASE/$1/gopath" \
571 "$ARVBOX_BASE/$1/Rlibs" \
572 "$ARVBOX_BASE/$1/arvados" \
573 "$ARVBOX_BASE/$1/composer" \
574 "$ARVBOX_BASE/$1/workbench2" \
576 echo "Created new arvbox $2"
577 echo "export ARVBOX_CONTAINER=$2"
579 echo "clone <from> <to> clone an arvbox"
580 echo "available arvboxes: $(ls $ARVBOX_BASE)"
585 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
586 if test -n "$1" ; then
589 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
590 echo "Certificate copied to $CERT"
594 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'
598 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'
602 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'
606 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
613 cd /usr/src/arvados/services/api
614 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
615 export RAILS_ENV=development
616 bundle exec rake db:drop
617 rm /var/lib/arvados/api_database_setup
618 rm /var/lib/arvados/superuser_token
619 rm /var/lib/arvados/keep0-uuid
620 rm /var/lib/arvados/keep1-uuid
621 rm /var/lib/arvados/keepproxy-uuid
625 sv restart keepstore0
626 sv restart keepstore1
632 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py /var/lib/arvados/cluster_config.yml.override $(getclusterid) add $@
633 docker exec $ARVBOX_CONTAINER sv restart controller
637 docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py /var/lib/arvados/cluster_config.yml.override $(getclusterid) remove $@
638 docker exec $ARVBOX_CONTAINER sv restart controller
646 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
648 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
649 echo "stop stop arvbox container"
650 echo "restart <config> stop, then run again"
651 echo "status print some information about current arvbox"
652 echo "ip print arvbox docker container ip address"
653 echo "host print arvbox published host"
654 echo "shell enter shell as root"
655 echo "ashell enter shell as 'arvbox'"
656 echo "psql enter postgres console"
657 echo "open open arvbox workbench in a web browser"
658 echo "root-cert get copy of root certificate"
659 echo "update <config> stop, pull latest image, run"
660 echo "build <config> build arvbox Docker image"
661 echo "reboot <config> stop, build arvbox Docker image, run"
662 echo "rebuild <config> build arvbox Docker image, no layer cache"
663 echo "checkpoint create database backup"
664 echo "restore restore checkpoint"
665 echo "hotreset reset database and restart API without restarting container"
666 echo "reset delete arvbox arvados data (be careful!)"
667 echo "destroy delete all arvbox code and data (be careful!)"
668 echo "log <service> tail log of specified service"
669 echo "ls <options> list directories inside arvbox"
670 echo "cat <files> get contents of files inside arvbox"
671 echo "pipe run a bash script piped in from stdin"
672 echo "sv <start|stop|restart> <service> "
673 echo " change state of service inside arvbox"
674 echo "clone <from> <to> clone dev arvbox"
675 echo "adduser <username> <email>"
676 echo " add a user login"
677 echo "removeuser <username>"
678 echo " remove user login"
679 echo "listusers list user logins"