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 "$SSO_ROOT" ; then
48 SSO_ROOT="$ARVBOX_DATA/sso-devise-omniauth-provider"
51 if test -z "$COMPOSER_ROOT" ; then
52 COMPOSER_ROOT="$ARVBOX_DATA/composer"
55 if test -z "$WORKBENCH2_ROOT" ; then
56 WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2"
59 PG_DATA="$ARVBOX_DATA/postgres"
60 VAR_DATA="$ARVBOX_DATA/var"
61 PASSENGER="$ARVBOX_DATA/passenger"
62 GEMS="$ARVBOX_DATA/gems"
63 PIPCACHE="$ARVBOX_DATA/pip"
64 NPMCACHE="$ARVBOX_DATA/npm"
65 GOSTUFF="$ARVBOX_DATA/gopath"
66 RLIBS="$ARVBOX_DATA/Rlibs"
69 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
74 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
77 if test "$CODE" = 0 ; then
85 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/api_uuid_prefix
89 if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
90 sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
91 mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
93 mkdir -p $HOME/.config/arvados
94 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
95 ARVADOS_API_HOST=$(gethost):8000
97 ARVADOS_API_HOST_INSECURE=true
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=$SSO_ROOT:/usr/src/sso:rw" \
130 "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
131 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
132 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
133 "--volume=$VAR_DATA:/var/lib/arvados:rw" \
134 "--volume=$PASSENGER:/var/lib/passenger:rw" \
135 "--volume=$GEMS:/var/lib/gems:rw" \
136 "--volume=$PIPCACHE:/var/lib/pip:rw" \
137 "--volume=$NPMCACHE:/var/lib/npm:rw" \
138 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
139 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
140 --label "org.arvados.arvbox_config=$CONFIG" \
145 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
156 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
157 if [[ $(running_config) != "$CONFIG" ]] ; then
158 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
161 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
164 echo "Container $ARVBOX_CONTAINER is already running"
169 if test $need_setup = 1 ; then
170 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
171 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
178 if test $(echo $TAG | cut -c1-1) != '-' ; then
182 if [[ $TAG = '-' ]] ; then
189 if [[ "$CONFIG" =~ ^public ]] ; then
190 if test -n "$ARVBOX_PUBLISH_IP" ; then
191 localip=$ARVBOX_PUBLISH_IP
193 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
194 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
196 echo "Public arvbox will use address $localip"
198 echo $localip > $iptemp
200 PUBLIC="--volume=$iptemp:/var/run/localip_override
207 --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 "$SSO_ROOT" ; then
243 git clone https://github.com/arvados/sso-devise-omniauth-provider.git "$SSO_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://github.com/arvados/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 /usr/local/lib/arvbox/runsu.sh \
274 /var/lib/arvbox/service/sso/run-service --only-setup
278 /usr/local/lib/arvbox/runsu.sh \
279 /var/lib/arvbox/service/api/run-service --only-setup
283 if [[ -z "$@" ]] ; then
284 interactive=--interactive
288 -e LINES=$(tput lines) \
289 -e COLUMNS=$(tput cols) \
291 -e WORKSPACE=/usr/src/arvados \
292 -e GEM_HOME=/var/lib/gems \
293 -e CONFIGSRC=/var/lib/arvados/run_tests \
295 /usr/local/lib/arvbox/runsu.sh \
296 /usr/src/arvados/build/run-tests.sh \
297 --temp /var/lib/arvados/test \
300 elif [[ "$CONFIG" = devenv ]] ; then
301 if [[ $need_setup = 1 ]] ; then
304 --name=${ARVBOX_CONTAINER} \
305 "--env=SVDIR=/etc/devenv-service" \
306 "--volume=$HOME:$HOME:rw" \
307 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
308 arvados/arvbox-dev$TAG
310 exec docker exec --interactive --tty \
311 -e LINES=$(tput lines) \
312 -e COLUMNS=$(tput cols) \
314 -e "ARVBOX_HOME=$HOME" \
315 -e "DISPLAY=$DISPLAY" \
317 ${ARVBOX_CONTAINER} \
318 /usr/local/lib/arvbox/devenv.sh "$@"
319 elif [[ "$CONFIG" =~ dev$ ]] ; then
322 --name=$ARVBOX_CONTAINER \
325 arvados/arvbox-dev$TAG
328 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
329 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
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 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
373 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
376 if docker --version |grep " 1\.[0-9]\." ; then
377 # Docker version prior 1.10 require -f flag
378 # -f flag removed in Docker 1.12
381 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
382 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
383 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
384 if test "$1" = localdemo -o "$1" = publicdemo ; then
385 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
386 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
388 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
389 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
395 localdemo|publicdemo|dev|publicdev|test|devenv)
399 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
406 if test -n "$subcmd" ; then
417 NO_CACHE=--no-cache build $@
426 exec docker exec --interactive --tty \
427 -e LINES=$(tput lines) \
428 -e COLUMNS=$(tput cols) \
430 -e GEM_HOME=/var/lib/gems \
431 $ARVBOX_CONTAINER /bin/bash
435 exec docker exec --interactive --tty \
436 -e LINES=$(tput lines) \
437 -e COLUMNS=$(tput cols) \
439 -e GEM_HOME=/var/lib/gems \
441 -w /usr/src/arvados \
442 $ARVBOX_CONTAINER /bin/bash --login
446 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
482 exec xdg-open http://$(gethost)
486 echo "Container: $ARVBOX_CONTAINER"
487 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
488 echo "Cluster id: $(getclusterid)"
489 echo "Status: running"
490 echo "Container IP: $(getip)"
491 echo "Published host: $(gethost)"
493 echo "Status: not running"
495 if test -d "$ARVBOX_DATA" ; then
496 echo "Data: $ARVBOX_DATA"
497 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
498 echo "Data: $ARVBOX_CONTAINER-data"
506 if test -d "$ARVBOX_DATA" ; then
507 if test "$subcmd" = destroy ; then
508 if test "$1" != -f ; then
509 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
510 echo "Use destroy -f if you really mean it."
514 rm -rf "$ARVBOX_DATA"
516 if test "$1" != -f ; then
517 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
518 echo "Code and downloaded packages will be preserved."
519 echo "Use reset -f if you really mean it."
523 rm -rf "$ARVBOX_DATA/postgres"
524 rm -rf "$ARVBOX_DATA/var"
527 if test "$1" != -f ; then
528 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
532 docker rm "$ARVBOX_CONTAINER-data"
537 if test -n "$1" ; then
538 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"
540 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
545 if test -n "$1" ; then
546 exec docker exec $ARVBOX_CONTAINER cat "$@"
548 echo "Usage: $0 $subcmd <files>"
553 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
557 if test -n "$1" -a -n "$2" ; then
558 exec docker exec $ARVBOX_CONTAINER sv "$@"
560 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
561 echo "Available services:"
562 exec docker execa $ARVBOX_CONTAINER ls /etc/service
567 if test -n "$2" ; then
568 mkdir -p "$ARVBOX_BASE/$2"
569 cp -a "$ARVBOX_BASE/$1/passenger" \
570 "$ARVBOX_BASE/$1/gems" \
571 "$ARVBOX_BASE/$1/pip" \
572 "$ARVBOX_BASE/$1/npm" \
573 "$ARVBOX_BASE/$1/gopath" \
574 "$ARVBOX_BASE/$1/Rlibs" \
575 "$ARVBOX_BASE/$1/arvados" \
576 "$ARVBOX_BASE/$1/sso-devise-omniauth-provider" \
577 "$ARVBOX_BASE/$1/composer" \
578 "$ARVBOX_BASE/$1/workbench2" \
580 echo "Created new arvbox $2"
581 echo "export ARVBOX_CONTAINER=$2"
583 echo "clone <from> <to> clone an arvbox"
584 echo "available arvboxes: $(ls $ARVBOX_BASE)"
589 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
590 if test -n "$1" ; then
593 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
594 echo "Certificate copied to $CERT"
598 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'
602 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'
606 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'
610 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
617 cd /usr/src/arvados/services/api
618 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
619 export RAILS_ENV=development
620 bundle exec rake db:drop
621 rm /var/lib/arvados/api_database_setup
622 rm /var/lib/arvados/superuser_token
623 rm /var/lib/arvados/keep0-uuid
624 rm /var/lib/arvados/keep1-uuid
625 rm /var/lib/arvados/keepproxy-uuid
629 sv restart keepstore0
630 sv restart keepstore1
636 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
638 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
639 echo "stop stop arvbox container"
640 echo "restart <config> stop, then run again"
641 echo "status print some information about current arvbox"
642 echo "ip print arvbox docker container ip address"
643 echo "host print arvbox published host"
644 echo "shell enter shell as root"
645 echo "ashell enter shell as 'arvbox'"
646 echo "psql enter postgres console"
647 echo "open open arvbox workbench in a web browser"
648 echo "root-cert get copy of root certificate"
649 echo "update <config> stop, pull latest image, run"
650 echo "build <config> build arvbox Docker image"
651 echo "reboot <config> stop, build arvbox Docker image, run"
652 echo "rebuild <config> build arvbox Docker image, no layer cache"
653 echo "checkpoint create database backup"
654 echo "restore restore checkpoint"
655 echo "hotreset reset database and restart API without restarting container"
656 echo "reset delete arvbox arvados data (be careful!)"
657 echo "destroy delete all arvbox code and data (be careful!)"
658 echo "log <service> tail log of specified service"
659 echo "ls <options> list directories inside arvbox"
660 echo "cat <files> get contents of files inside arvbox"
661 echo "pipe run a bash script piped in from stdin"
662 echo "sv <start|stop|restart> <service> "
663 echo " change state of service inside arvbox"
664 echo "clone <from> <to> clone dev arvbox"