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
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://github.com/arvados/arvados.git "$ARVADOS_ROOT"
241 if ! test -d "$SSO_ROOT" ; then
242 git clone https://github.com/arvados/sso-devise-omniauth-provider.git "$SSO_ROOT"
244 if ! test -d "$COMPOSER_ROOT" ; then
245 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
246 git -C "$COMPOSER_ROOT" checkout arvados-fork
247 git -C "$COMPOSER_ROOT" pull
249 if ! test -d "$WORKBENCH2_ROOT" ; then
250 git clone https://github.com/arvados/arvados-workbench2.git "$WORKBENCH2_ROOT"
253 if [[ "$CONFIG" = test ]] ; then
255 mkdir -p $VAR_DATA/test
257 if test "$need_setup" = 1 ; then
260 --name=$ARVBOX_CONTAINER \
262 "--env=SVDIR=/etc/test-service" \
263 arvados/arvbox-dev$TAG
267 /usr/local/lib/arvbox/runsu.sh \
268 /usr/local/lib/arvbox/waitforpostgres.sh
272 /usr/local/lib/arvbox/runsu.sh \
273 /var/lib/arvbox/service/sso/run-service --only-setup
277 /usr/local/lib/arvbox/runsu.sh \
278 /var/lib/arvbox/service/api/run-service --only-setup
282 if [[ -z "$@" ]] ; then
283 interactive=--interactive
287 -e LINES=$(tput lines) \
288 -e COLUMNS=$(tput cols) \
290 -e WORKSPACE=/usr/src/arvados \
291 -e GEM_HOME=/var/lib/gems \
292 -e CONFIGSRC=/var/lib/arvados/run_tests \
294 /usr/local/lib/arvbox/runsu.sh \
295 /usr/src/arvados/build/run-tests.sh \
296 --temp /var/lib/arvados/test \
299 elif [[ "$CONFIG" = devenv ]] ; then
300 if [[ $need_setup = 1 ]] ; then
303 --name=${ARVBOX_CONTAINER} \
304 "--env=SVDIR=/etc/devenv-service" \
305 "--volume=$HOME:$HOME:rw" \
306 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
307 arvados/arvbox-dev$TAG
309 exec docker exec --interactive --tty \
310 -e LINES=$(tput lines) \
311 -e COLUMNS=$(tput cols) \
313 -e "ARVBOX_HOME=$HOME" \
314 -e "DISPLAY=$DISPLAY" \
316 ${ARVBOX_CONTAINER} \
317 /usr/local/lib/arvbox/devenv.sh "$@"
318 elif [[ "$CONFIG" =~ dev$ ]] ; then
321 --name=$ARVBOX_CONTAINER \
324 arvados/arvbox-dev$TAG
327 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
328 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
330 echo "Unknown configuration '$CONFIG'"
341 if test $(echo $TAG | cut -c1-1) != '-' ; then
349 if echo "$CONFIG" | grep 'demo$' ; then
350 docker pull arvados/arvbox-demo$TAG
352 docker pull arvados/arvbox-dev$TAG
357 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
358 docker stop $ARVBOX_CONTAINER
361 VOLUMES=--volumes=true
362 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
363 docker rm $VOLUMES $ARVBOX_CONTAINER
365 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
366 docker rm $VOLUMES $ARVBOX_CONTAINER
371 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
372 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
375 if docker --version |grep " 1\.[0-9]\." ; then
376 # Docker version prior 1.10 require -f flag
377 # -f flag removed in Docker 1.12
380 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
381 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
382 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
383 if test "$1" = localdemo -o "$1" = publicdemo ; then
384 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
385 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
387 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
388 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
394 localdemo|publicdemo|dev|publicdev|test|devenv)
398 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
405 if test -n "$subcmd" ; then
416 NO_CACHE=--no-cache build $@
425 exec docker exec --interactive --tty \
426 -e LINES=$(tput lines) \
427 -e COLUMNS=$(tput cols) \
429 -e GEM_HOME=/var/lib/gems \
430 $ARVBOX_CONTAINER /bin/bash
434 exec docker exec --interactive --tty \
435 -e LINES=$(tput lines) \
436 -e COLUMNS=$(tput cols) \
438 -e GEM_HOME=/var/lib/gems \
440 -w /usr/src/arvados \
441 $ARVBOX_CONTAINER /bin/bash --login
445 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
481 exec xdg-open http://$(gethost)
485 echo "Container: $ARVBOX_CONTAINER"
486 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
487 echo "Cluster id: $(getclusterid)"
488 echo "Status: running"
489 echo "Container IP: $(getip)"
490 echo "Published host: $(gethost)"
492 echo "Status: not running"
494 if test -d "$ARVBOX_DATA" ; then
495 echo "Data: $ARVBOX_DATA"
496 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
497 echo "Data: $ARVBOX_CONTAINER-data"
505 if test -d "$ARVBOX_DATA" ; then
506 if test "$subcmd" = destroy ; then
507 if test "$1" != -f ; then
508 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
509 echo "Use destroy -f if you really mean it."
513 rm -rf "$ARVBOX_DATA"
515 if test "$1" != -f ; then
516 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
517 echo "Code and downloaded packages will be preserved."
518 echo "Use reset -f if you really mean it."
522 rm -rf "$ARVBOX_DATA/postgres"
523 rm -rf "$ARVBOX_DATA/var"
526 if test "$1" != -f ; then
527 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
531 docker rm "$ARVBOX_CONTAINER-data"
536 if test -n "$1" ; then
537 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"
539 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
544 if test -n "$1" ; then
545 exec docker exec $ARVBOX_CONTAINER cat "$@"
547 echo "Usage: $0 $subcmd <files>"
552 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
556 if test -n "$1" -a -n "$2" ; then
557 exec docker exec $ARVBOX_CONTAINER sv "$@"
559 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
560 echo "Available services:"
561 exec docker execa $ARVBOX_CONTAINER ls /etc/service
566 if test -n "$2" ; then
567 mkdir -p "$ARVBOX_BASE/$2"
568 cp -a "$ARVBOX_BASE/$1/passenger" \
569 "$ARVBOX_BASE/$1/gems" \
570 "$ARVBOX_BASE/$1/pip" \
571 "$ARVBOX_BASE/$1/npm" \
572 "$ARVBOX_BASE/$1/gopath" \
573 "$ARVBOX_BASE/$1/Rlibs" \
574 "$ARVBOX_BASE/$1/arvados" \
575 "$ARVBOX_BASE/$1/sso-devise-omniauth-provider" \
576 "$ARVBOX_BASE/$1/composer" \
577 "$ARVBOX_BASE/$1/workbench2" \
579 echo "Created new arvbox $2"
580 echo "export ARVBOX_CONTAINER=$2"
582 echo "clone <from> <to> clone an arvbox"
583 echo "available arvboxes: $(ls $ARVBOX_BASE)"
588 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
589 if test -n "$1" ; then
592 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
593 echo "Certificate copied to $CERT"
597 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'
601 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'
605 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'
609 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
616 cd /usr/src/arvados/services/api
617 export RAILS_ENV=development
618 bundle exec rake db:drop
619 rm /var/lib/arvados/api_database_setup
620 rm /var/lib/arvados/superuser_token
621 rm /var/lib/arvados/keep0-uuid
622 rm /var/lib/arvados/keep1-uuid
623 rm /var/lib/arvados/keepproxy-uuid
627 sv restart keepstore0
628 sv restart keepstore1
634 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
636 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
637 echo "stop stop arvbox container"
638 echo "restart <config> stop, then run again"
639 echo "status print some information about current arvbox"
640 echo "ip print arvbox docker container ip address"
641 echo "host print arvbox published host"
642 echo "shell enter shell as root"
643 echo "ashell enter shell as 'arvbox'"
644 echo "psql enter postgres console"
645 echo "open open arvbox workbench in a web browser"
646 echo "root-cert get copy of root certificate"
647 echo "update <config> stop, pull latest image, run"
648 echo "build <config> build arvbox Docker image"
649 echo "reboot <config> stop, build arvbox Docker image, run"
650 echo "rebuild <config> build arvbox Docker image, no layer cache"
651 echo "checkpoint create database backup"
652 echo "restore restore checkpoint"
653 echo "hotreset reset database and restart API without restarting container"
654 echo "reset delete arvbox arvados data (be careful!)"
655 echo "destroy delete all arvbox code and data (be careful!)"
656 echo "log <service> tail log of specified service"
657 echo "ls <options> list directories inside arvbox"
658 echo "cat <files> get contents of files inside arvbox"
659 echo "pipe run a bash script piped in from stdin"
660 echo "sv <start|stop|restart> <service> "
661 echo " change state of service inside arvbox"
662 echo "clone <from> <to> clone dev arvbox"