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 FF=/tmp/arvbox-fifo-$$
101 docker logs -f $ARVBOX_CONTAINER > $FF &
104 if [[ $line =~ "ok: down: ready:" ]] ; then
107 wait $LOGPID 2>/dev/null
115 if test -n "$localip" ; then
116 echo "export ARVADOS_API_HOST=$localip:8000"
118 echo "export ARVADOS_API_HOST=$(gethost):8000"
124 "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
125 "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
126 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
127 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
128 "--volume=$VAR_DATA:/var/lib/arvados:rw" \
129 "--volume=$PASSENGER:/var/lib/passenger:rw" \
130 "--volume=$GEMS:/var/lib/gems:rw" \
131 "--volume=$PIPCACHE:/var/lib/pip:rw" \
132 "--volume=$NPMCACHE:/var/lib/npm:rw" \
133 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
134 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
135 --label "org.arvados.arvbox_config=$CONFIG" \
140 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
151 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
152 if [[ $(running_config) != "$CONFIG" ]] ; then
153 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
156 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
159 echo "Container $ARVBOX_CONTAINER is already running"
164 if test $need_setup = 1 ; then
165 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
166 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
173 if test $(echo $TAG | cut -c1-1) != '-' ; then
177 if [[ $TAG = '-' ]] ; then
184 if [[ "$CONFIG" =~ ^public ]] ; then
185 if test -n "$ARVBOX_PUBLISH_IP" ; then
186 localip=$ARVBOX_PUBLISH_IP
188 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
189 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
191 echo "Public arvbox will use address $localip"
193 echo $localip > $iptemp
195 PUBLIC="--volume=$iptemp:/var/run/localip_override
202 --publish=25101:25101
205 --publish=45000-45020:45000-45020"
210 if [[ "$CONFIG" =~ demo$ ]] ; then
211 if test -d "$ARVBOX_DATA" ; then
212 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
213 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
217 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
218 docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
223 --name=$ARVBOX_CONTAINER \
225 --volumes-from $ARVBOX_CONTAINER-data \
226 --label "org.arvados.arvbox_config=$CONFIG" \
228 arvados/arvbox-demo$TAG
232 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
234 if ! test -d "$ARVADOS_ROOT" ; then
235 git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT"
237 if ! test -d "$COMPOSER_ROOT" ; then
238 git clone https://github.com/arvados/composer.git "$COMPOSER_ROOT"
239 git -C "$COMPOSER_ROOT" checkout arvados-fork
240 git -C "$COMPOSER_ROOT" pull
242 if ! test -d "$WORKBENCH2_ROOT" ; then
243 git clone https://github.com/arvados/arvados-workbench2.git "$WORKBENCH2_ROOT"
246 if [[ "$CONFIG" = test ]] ; then
248 mkdir -p $VAR_DATA/test
250 if test "$need_setup" = 1 ; then
253 --name=$ARVBOX_CONTAINER \
255 "--env=SVDIR=/etc/test-service" \
256 arvados/arvbox-dev$TAG
260 /usr/local/lib/arvbox/runsu.sh \
261 /usr/local/lib/arvbox/waitforpostgres.sh
265 /usr/local/lib/arvbox/runsu.sh \
266 /var/lib/arvbox/service/api/run-service --only-setup
270 if [[ -z "$@" ]] ; then
271 interactive=--interactive
275 -e LINES=$(tput lines) \
276 -e COLUMNS=$(tput cols) \
278 -e WORKSPACE=/usr/src/arvados \
279 -e GEM_HOME=/var/lib/gems \
280 -e CONFIGSRC=/var/lib/arvados/run_tests \
282 /usr/local/lib/arvbox/runsu.sh \
283 /usr/src/arvados/build/run-tests.sh \
284 --temp /var/lib/arvados/test \
287 elif [[ "$CONFIG" = devenv ]] ; then
288 if [[ $need_setup = 1 ]] ; then
291 --name=${ARVBOX_CONTAINER} \
292 "--env=SVDIR=/etc/devenv-service" \
293 "--volume=$HOME:$HOME:rw" \
294 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
295 arvados/arvbox-dev$TAG
297 exec docker exec --interactive --tty \
298 -e LINES=$(tput lines) \
299 -e COLUMNS=$(tput cols) \
301 -e "ARVBOX_HOME=$HOME" \
302 -e "DISPLAY=$DISPLAY" \
304 ${ARVBOX_CONTAINER} \
305 /usr/local/lib/arvbox/devenv.sh "$@"
306 elif [[ "$CONFIG" =~ dev$ ]] ; then
309 --name=$ARVBOX_CONTAINER \
312 arvados/arvbox-dev$TAG
315 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
316 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
318 echo "Unknown configuration '$CONFIG'"
329 if test $(echo $TAG | cut -c1-1) != '-' ; then
337 if echo "$CONFIG" | grep 'demo$' ; then
338 docker pull arvados/arvbox-demo$TAG
340 docker pull arvados/arvbox-dev$TAG
345 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
346 docker stop $ARVBOX_CONTAINER
349 VOLUMES=--volumes=true
350 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
351 docker rm $VOLUMES $ARVBOX_CONTAINER
353 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
354 docker rm $VOLUMES $ARVBOX_CONTAINER
359 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
360 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
363 if docker --version |grep " 1\.[0-9]\." ; then
364 # Docker version prior 1.10 require -f flag
365 # -f flag removed in Docker 1.12
368 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
369 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
370 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
371 if test "$1" = localdemo -o "$1" = publicdemo ; then
372 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
373 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
375 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
376 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
382 localdemo|publicdemo|dev|publicdev|test|devenv)
386 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
393 if test -n "$subcmd" ; then
404 NO_CACHE=--no-cache build $@
413 exec docker exec --interactive --tty \
414 -e LINES=$(tput lines) \
415 -e COLUMNS=$(tput cols) \
417 -e GEM_HOME=/var/lib/gems \
418 $ARVBOX_CONTAINER /bin/bash
422 exec docker exec --interactive --tty \
423 -e LINES=$(tput lines) \
424 -e COLUMNS=$(tput cols) \
426 -e GEM_HOME=/var/lib/gems \
428 -w /usr/src/arvados \
429 $ARVBOX_CONTAINER /bin/bash --login
433 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
469 exec xdg-open http://$(gethost)
473 echo "Container: $ARVBOX_CONTAINER"
474 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
475 echo "Cluster id: $(getclusterid)"
476 echo "Status: running"
477 echo "Container IP: $(getip)"
478 echo "Published host: $(gethost)"
480 echo "Status: not running"
482 if test -d "$ARVBOX_DATA" ; then
483 echo "Data: $ARVBOX_DATA"
484 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
485 echo "Data: $ARVBOX_CONTAINER-data"
493 if test -d "$ARVBOX_DATA" ; then
494 if test "$subcmd" = destroy ; then
495 if test "$1" != -f ; then
496 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
497 echo "Use destroy -f if you really mean it."
501 chmod -R u+w "$ARVBOX_DATA"
502 rm -rf "$ARVBOX_DATA"
504 if test "$1" != -f ; then
505 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
506 echo "Code and downloaded packages will be preserved."
507 echo "Use reset -f if you really mean it."
511 rm -rf "$ARVBOX_DATA/postgres"
512 rm -rf "$ARVBOX_DATA/var"
515 if test "$1" != -f ; then
516 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
520 docker rm "$ARVBOX_CONTAINER-data"
525 if test -n "$1" ; then
526 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"
528 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
533 if test -n "$1" ; then
534 exec docker exec $ARVBOX_CONTAINER cat "$@"
536 echo "Usage: $0 $subcmd <files>"
541 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
545 if test -n "$1" -a -n "$2" ; then
546 exec docker exec $ARVBOX_CONTAINER sv "$@"
548 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
549 echo "Available services:"
550 exec docker execa $ARVBOX_CONTAINER ls /etc/service
555 if test -n "$2" ; then
556 mkdir -p "$ARVBOX_BASE/$2"
557 cp -a "$ARVBOX_BASE/$1/passenger" \
558 "$ARVBOX_BASE/$1/gems" \
559 "$ARVBOX_BASE/$1/pip" \
560 "$ARVBOX_BASE/$1/npm" \
561 "$ARVBOX_BASE/$1/gopath" \
562 "$ARVBOX_BASE/$1/Rlibs" \
563 "$ARVBOX_BASE/$1/arvados" \
564 "$ARVBOX_BASE/$1/composer" \
565 "$ARVBOX_BASE/$1/workbench2" \
567 echo "Created new arvbox $2"
568 echo "export ARVBOX_CONTAINER=$2"
570 echo "clone <from> <to> clone an arvbox"
571 echo "available arvboxes: $(ls $ARVBOX_BASE)"
576 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
577 if test -n "$1" ; then
580 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
581 echo "Certificate copied to $CERT"
585 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'
589 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'
593 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'
597 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - <<EOF
604 cd /usr/src/arvados/services/api
605 export DISABLE_DATABASE_ENVIRONMENT_CHECK=1
606 export RAILS_ENV=development
607 bundle exec rake db:drop
608 rm /var/lib/arvados/api_database_setup
609 rm /var/lib/arvados/superuser_token
610 rm /var/lib/arvados/keep0-uuid
611 rm /var/lib/arvados/keep1-uuid
612 rm /var/lib/arvados/keepproxy-uuid
616 sv restart keepstore0
617 sv restart keepstore1
623 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
625 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
626 echo "stop stop arvbox container"
627 echo "restart <config> stop, then run again"
628 echo "status print some information about current arvbox"
629 echo "ip print arvbox docker container ip address"
630 echo "host print arvbox published host"
631 echo "shell enter shell as root"
632 echo "ashell enter shell as 'arvbox'"
633 echo "psql enter postgres console"
634 echo "open open arvbox workbench in a web browser"
635 echo "root-cert get copy of root certificate"
636 echo "update <config> stop, pull latest image, run"
637 echo "build <config> build arvbox Docker image"
638 echo "reboot <config> stop, build arvbox Docker image, run"
639 echo "rebuild <config> build arvbox Docker image, no layer cache"
640 echo "checkpoint create database backup"
641 echo "restore restore checkpoint"
642 echo "hotreset reset database and restart API without restarting container"
643 echo "reset delete arvbox arvados data (be careful!)"
644 echo "destroy delete all arvbox code and data (be careful!)"
645 echo "log <service> tail log of specified service"
646 echo "ls <options> list directories inside arvbox"
647 echo "cat <files> get contents of files inside arvbox"
648 echo "pipe run a bash script piped in from stdin"
649 echo "sv <start|stop|restart> <service> "
650 echo " change state of service inside arvbox"
651 echo "clone <from> <to> clone dev arvbox"