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=25100:25100
208 --publish=25107:25107
209 --publish=25108:25108
216 if [[ "$CONFIG" =~ demo$ ]] ; then
217 if test -d "$ARVBOX_DATA" ; then
218 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
219 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
223 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
224 docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
229 --name=$ARVBOX_CONTAINER \
231 --volumes-from $ARVBOX_CONTAINER-data \
232 --label "org.arvados.arvbox_config=$CONFIG" \
234 arvados/arvbox-demo$TAG
238 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
240 if ! test -d "$ARVADOS_ROOT" ; then
241 git clone https://github.com/arvados/arvados.git "$ARVADOS_ROOT"
243 if ! test -d "$SSO_ROOT" ; then
244 git clone https://github.com/arvados/sso-devise-omniauth-provider.git "$SSO_ROOT"
246 if ! test -d "$COMPOSER_ROOT" ; then
247 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
248 git -C "$COMPOSER_ROOT" checkout arvados-fork
249 git -C "$COMPOSER_ROOT" pull
251 if ! test -d "$WORKBENCH2_ROOT" ; then
252 git clone https://github.com/arvados/arvados-workbench2.git "$WORKBENCH2_ROOT"
255 if [[ "$CONFIG" = test ]] ; then
257 mkdir -p $VAR_DATA/test
259 if test "$need_setup" = 1 ; then
262 --name=$ARVBOX_CONTAINER \
264 "--env=SVDIR=/etc/test-service" \
265 arvados/arvbox-dev$TAG
269 /usr/local/lib/arvbox/runsu.sh \
270 /usr/local/lib/arvbox/waitforpostgres.sh
274 /usr/local/lib/arvbox/runsu.sh \
275 /var/lib/arvbox/service/sso/run-service --only-setup
279 /usr/local/lib/arvbox/runsu.sh \
280 /var/lib/arvbox/service/api/run-service --only-setup
284 if [[ -z "$@" ]] ; then
285 interactive=--interactive
289 -e LINES=$(tput lines) \
290 -e COLUMNS=$(tput cols) \
292 -e WORKSPACE=/usr/src/arvados \
293 -e GEM_HOME=/var/lib/gems \
294 -e CONFIGSRC=/var/lib/arvados/run_tests \
296 /usr/local/lib/arvbox/runsu.sh \
297 /usr/src/arvados/build/run-tests.sh \
298 --temp /var/lib/arvados/test \
301 elif [[ "$CONFIG" = devenv ]] ; then
302 if [[ $need_setup = 1 ]] ; then
305 --name=${ARVBOX_CONTAINER} \
306 "--env=SVDIR=/etc/devenv-service" \
307 "--volume=$HOME:$HOME:rw" \
308 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
309 arvados/arvbox-dev$TAG
311 exec docker exec --interactive --tty \
312 -e LINES=$(tput lines) \
313 -e COLUMNS=$(tput cols) \
315 -e "ARVBOX_HOME=$HOME" \
316 -e "DISPLAY=$DISPLAY" \
318 ${ARVBOX_CONTAINER} \
319 /usr/local/lib/arvbox/devenv.sh "$@"
320 elif [[ "$CONFIG" =~ dev$ ]] ; then
323 --name=$ARVBOX_CONTAINER \
326 arvados/arvbox-dev$TAG
329 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
330 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
332 echo "Unknown configuration '$CONFIG'"
343 if test $(echo $TAG | cut -c1-1) != '-' ; then
351 if echo "$CONFIG" | grep 'demo$' ; then
352 docker pull arvados/arvbox-demo$TAG
354 docker pull arvados/arvbox-dev$TAG
359 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
360 docker stop $ARVBOX_CONTAINER
363 VOLUMES=--volumes=true
364 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
365 docker rm $VOLUMES $ARVBOX_CONTAINER
367 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
368 docker rm $VOLUMES $ARVBOX_CONTAINER
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)
383 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
384 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
385 if test "$1" = localdemo -o "$1" = publicdemo ; then
386 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
387 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
389 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
390 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
396 localdemo|publicdemo|dev|publicdev|test|devenv)
400 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
407 if test -n "$subcmd" ; then
418 NO_CACHE=--no-cache build $@
427 exec docker exec --interactive --tty \
428 -e LINES=$(tput lines) \
429 -e COLUMNS=$(tput cols) \
431 -e GEM_HOME=/var/lib/gems \
432 $ARVBOX_CONTAINER /bin/bash
436 exec docker exec --interactive --tty \
437 -e LINES=$(tput lines) \
438 -e COLUMNS=$(tput cols) \
440 -e GEM_HOME=/var/lib/gems \
442 -w /usr/src/arvados \
443 $ARVBOX_CONTAINER /bin/bash --login
447 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
483 exec xdg-open http://$(gethost)
487 echo "Container: $ARVBOX_CONTAINER"
488 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
489 echo "Cluster id: $(getclusterid)"
490 echo "Status: running"
491 echo "Container IP: $(getip)"
492 echo "Published host: $(gethost)"
494 echo "Status: not running"
496 if test -d "$ARVBOX_DATA" ; then
497 echo "Data: $ARVBOX_DATA"
498 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
499 echo "Data: $ARVBOX_CONTAINER-data"
507 if test -d "$ARVBOX_DATA" ; then
508 if test "$subcmd" = destroy ; then
509 if test "$1" != -f ; then
510 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
511 echo "Use destroy -f if you really mean it."
515 rm -rf "$ARVBOX_DATA"
517 if test "$1" != -f ; then
518 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
519 echo "Code and downloaded packages will be preserved."
520 echo "Use reset -f if you really mean it."
524 rm -rf "$ARVBOX_DATA/postgres"
525 rm -rf "$ARVBOX_DATA/var"
528 if test "$1" != -f ; then
529 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
533 docker rm "$ARVBOX_CONTAINER-data"
538 if test -n "$1" ; then
539 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"
541 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
546 if test -n "$1" ; then
547 exec docker exec $ARVBOX_CONTAINER cat "$@"
549 echo "Usage: $0 $subcmd <files>"
554 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
558 if test -n "$1" -a -n "$2" ; then
559 exec docker exec $ARVBOX_CONTAINER sv "$@"
561 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
562 echo "Available services:"
563 exec docker execa $ARVBOX_CONTAINER ls /etc/service
568 if test -n "$2" ; then
569 mkdir -p "$ARVBOX_BASE/$2"
570 cp -a "$ARVBOX_BASE/$1/passenger" \
571 "$ARVBOX_BASE/$1/gems" \
572 "$ARVBOX_BASE/$1/pip" \
573 "$ARVBOX_BASE/$1/npm" \
574 "$ARVBOX_BASE/$1/gopath" \
575 "$ARVBOX_BASE/$1/Rlibs" \
576 "$ARVBOX_BASE/$1/arvados" \
577 "$ARVBOX_BASE/$1/sso-devise-omniauth-provider" \
578 "$ARVBOX_BASE/$1/composer" \
579 "$ARVBOX_BASE/$1/workbench2" \
581 echo "Created new arvbox $2"
582 echo "export ARVBOX_CONTAINER=$2"
584 echo "clone <from> <to> clone an arvbox"
585 echo "available arvboxes: $(ls $ARVBOX_BASE)"
590 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
591 if test -n "$1" ; then
594 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
595 echo "Certificate copied to $CERT"
599 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'
603 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'
607 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'
611 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
618 cd /usr/src/arvados/services/api
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"