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
22 if which greadlink >/dev/null 2>/dev/null ; then
23 ARVBOX_DOCKER=$(greadlink -f $(dirname $0)/../lib/arvbox/docker)
25 ARVBOX_DOCKER=$(readlink -f $(dirname $0)/../lib/arvbox/docker)
29 if test -z "$ARVBOX_CONTAINER" ; then
30 ARVBOX_CONTAINER=arvbox
33 if test -z "$ARVBOX_BASE" ; then
34 ARVBOX_BASE="$HOME/.arvbox"
37 if test -z "$ARVBOX_DATA" ; then
38 ARVBOX_DATA="$ARVBOX_BASE/$ARVBOX_CONTAINER"
41 if test -z "$ARVADOS_ROOT" ; then
42 ARVADOS_ROOT="$ARVBOX_DATA/arvados"
45 if test -z "$SSO_ROOT" ; then
46 SSO_ROOT="$ARVBOX_DATA/sso-devise-omniauth-provider"
49 if test -z "$COMPOSER_ROOT" ; then
50 COMPOSER_ROOT="$ARVBOX_DATA/composer"
53 if test -z "$WORKBENCH2_ROOT" ; then
54 WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2"
57 PG_DATA="$ARVBOX_DATA/postgres"
58 VAR_DATA="$ARVBOX_DATA/var"
59 PASSENGER="$ARVBOX_DATA/passenger"
60 GEMS="$ARVBOX_DATA/gems"
61 PIPCACHE="$ARVBOX_DATA/pip"
62 NPMCACHE="$ARVBOX_DATA/npm"
63 GOSTUFF="$ARVBOX_DATA/gopath"
64 RLIBS="$ARVBOX_DATA/Rlibs"
67 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER
72 OVERRIDE=$(docker exec -i $ARVBOX_CONTAINER cat /var/run/localip_override 2>/dev/null)
75 if test "$CODE" = 0 ; then
83 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/api_uuid_prefix
87 if test -f ~/.config/arvados/$ARVBOX_CONTAINER.conf ; then
88 sed "s/ARVADOS_API_HOST=.*/ARVADOS_API_HOST=$(gethost):8000/" <$HOME/.config/arvados/$ARVBOX_CONTAINER.conf >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf.tmp
89 mv ~/.config/arvados/$ARVBOX_CONTAINER.conf.tmp ~/.config/arvados/$ARVBOX_CONTAINER.conf
91 mkdir -p $HOME/.config/arvados
92 cat >$HOME/.config/arvados/$ARVBOX_CONTAINER.conf <<EOF
93 ARVADOS_API_HOST=$(gethost):8000
95 ARVADOS_API_HOST_INSECURE=true
101 FF=/tmp/arvbox-fifo-$$
103 docker logs -f $ARVBOX_CONTAINER > $FF &
106 if [[ $line =~ "ok: down: ready:" ]] ; then
109 wait $LOGPID 2>/dev/null
117 if test -n "$localip" ; then
118 echo "export ARVADOS_API_HOST=$localip:8000"
120 echo "export ARVADOS_API_HOST=$(gethost):8000"
126 "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \
127 "--volume=$SSO_ROOT:/usr/src/sso:rw" \
128 "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \
129 "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \
130 "--volume=$PG_DATA:/var/lib/postgresql:rw" \
131 "--volume=$VAR_DATA:/var/lib/arvados:rw" \
132 "--volume=$PASSENGER:/var/lib/passenger:rw" \
133 "--volume=$GEMS:/var/lib/gems:rw" \
134 "--volume=$PIPCACHE:/var/lib/pip:rw" \
135 "--volume=$NPMCACHE:/var/lib/npm:rw" \
136 "--volume=$GOSTUFF:/var/lib/gopath:rw" \
137 "--volume=$RLIBS:/var/lib/Rlibs:rw" \
138 --label "org.arvados.arvbox_config=$CONFIG" \
143 docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}'
154 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
155 if [[ $(running_config) != "$CONFIG" ]] ; then
156 echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot"
159 if test "$CONFIG" = test -o "$CONFIG" = devenv ; then
162 echo "Container $ARVBOX_CONTAINER is already running"
167 if test $need_setup = 1 ; then
168 if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then
169 echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot"
176 if test $(echo $TAG | cut -c1-1) != '-' ; then
180 if [[ $TAG = '-' ]] ; then
187 if [[ "$CONFIG" =~ ^public ]] ; then
188 if test -n "$ARVBOX_PUBLISH_IP" ; then
189 localip=$ARVBOX_PUBLISH_IP
191 defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }')
192 localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/')
195 echo $localip > $iptemp
197 PUBLIC="--volume=$iptemp:/var/run/localip_override
204 --publish=25100:25100
205 --publish=25107:25107
206 --publish=25108:25108
213 if [[ "$CONFIG" =~ demo$ ]] ; then
214 if test -d "$ARVBOX_DATA" ; then
215 echo "It looks like you already have a development container named $ARVBOX_CONTAINER."
216 echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container"
220 if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then
221 docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true
226 --name=$ARVBOX_CONTAINER \
228 --volumes-from $ARVBOX_CONTAINER-data \
229 --label "org.arvados.arvbox_config=$CONFIG" \
231 arvados/arvbox-demo$TAG
235 mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS"
237 if ! test -d "$ARVADOS_ROOT" ; then
238 git clone https://github.com/curoverse/arvados.git "$ARVADOS_ROOT"
240 if ! test -d "$SSO_ROOT" ; then
241 git clone https://github.com/curoverse/sso-devise-omniauth-provider.git "$SSO_ROOT"
243 if ! test -d "$COMPOSER_ROOT" ; then
244 git clone https://github.com/curoverse/composer.git "$COMPOSER_ROOT"
245 git -C "$COMPOSER_ROOT" checkout arvados-fork
247 if ! test -d "$WORKBENCH2_ROOT" ; then
248 git clone https://github.com/curoverse/arvados-workbench2.git "$WORKBENCH2_ROOT"
251 if [[ "$CONFIG" = test ]] ; then
253 mkdir -p $VAR_DATA/test
255 if test "$need_setup" = 1 ; then
258 --name=$ARVBOX_CONTAINER \
260 "--env=SVDIR=/etc/test-service" \
261 arvados/arvbox-dev$TAG
265 /usr/local/lib/arvbox/runsu.sh \
266 /usr/local/lib/arvbox/waitforpostgres.sh
270 /usr/local/lib/arvbox/runsu.sh \
271 /var/lib/arvbox/service/sso/run-service --only-setup
275 /usr/local/lib/arvbox/runsu.sh \
276 /var/lib/arvbox/service/api/run-service --only-setup
280 if [[ -z "$@" ]] ; then
281 interactive=--interactive
285 -e LINES=$(tput lines) \
286 -e COLUMNS=$(tput cols) \
288 -e WORKSPACE=/usr/src/arvados \
289 -e GEM_HOME=/var/lib/gems \
290 -e CONFIGSRC=/var/lib/arvados/run_tests \
292 /usr/local/lib/arvbox/runsu.sh \
293 /usr/src/arvados/build/run-tests.sh \
294 --temp /var/lib/arvados/test \
297 elif [[ "$CONFIG" = devenv ]] ; then
298 if [[ $need_setup = 1 ]] ; then
301 --name=${ARVBOX_CONTAINER} \
302 "--env=SVDIR=/etc/devenv-service" \
303 "--volume=$HOME:$HOME:rw" \
304 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
305 arvados/arvbox-dev$TAG
307 exec docker exec --interactive --tty \
308 -e LINES=$(tput lines) \
309 -e COLUMNS=$(tput cols) \
311 -e "ARVBOX_HOME=$HOME" \
312 -e "DISPLAY=$DISPLAY" \
314 ${ARVBOX_CONTAINER} \
315 /usr/local/lib/arvbox/devenv.sh "$@"
316 elif [[ "$CONFIG" =~ dev$ ]] ; then
319 --name=$ARVBOX_CONTAINER \
322 arvados/arvbox-dev$TAG
325 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
326 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
328 echo "Unknown configuration '$CONFIG'"
339 if test $(echo $TAG | cut -c1-1) != '-' ; then
347 if echo "$CONFIG" | grep 'demo$' ; then
348 docker pull arvados/arvbox-demo$TAG
350 docker pull arvados/arvbox-dev$TAG
355 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
356 docker stop $ARVBOX_CONTAINER
359 VOLUMES=--volumes=true
360 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
361 docker rm $VOLUMES $ARVBOX_CONTAINER
363 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
364 docker rm $VOLUMES $ARVBOX_CONTAINER
369 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
370 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
373 if docker --version |grep " 1\.[0-9]\." ; then
374 # Docker version prior 1.10 require -f flag
375 # -f flag removed in Docker 1.12
378 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
379 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
380 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
381 if test "$1" = localdemo -o "$1" = publicdemo ; then
382 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
383 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
385 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
386 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
392 localdemo|publicdemo|dev|publicdev|test|devenv)
396 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
403 if test -n "$subcmd" ; then
414 NO_CACHE=--no-cache build $@
423 exec docker exec --interactive --tty \
424 -e LINES=$(tput lines) \
425 -e COLUMNS=$(tput cols) \
427 -e GEM_HOME=/var/lib/gems \
428 $ARVBOX_CONTAINER /bin/bash
432 exec docker exec --interactive --tty \
433 -e LINES=$(tput lines) \
434 -e COLUMNS=$(tput cols) \
436 -e GEM_HOME=/var/lib/gems \
438 -w /usr/src/arvados \
439 $ARVBOX_CONTAINER /bin/bash --login
443 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
479 exec xdg-open http://$(gethost)
483 echo "Container: $ARVBOX_CONTAINER"
484 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
485 echo "Cluster id: $(getclusterid)"
486 echo "Status: running"
487 echo "Container IP: $(getip)"
488 echo "Published host: $(gethost)"
490 echo "Status: not running"
492 if test -d "$ARVBOX_DATA" ; then
493 echo "Data: $ARVBOX_DATA"
494 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
495 echo "Data: $ARVBOX_CONTAINER-data"
503 if test -d "$ARVBOX_DATA" ; then
504 if test "$subcmd" = destroy ; then
505 if test "$1" != -f ; then
506 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
507 echo "Use destroy -f if you really mean it."
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/sso-devise-omniauth-provider" \
574 "$ARVBOX_BASE/$1/composer" \
575 "$ARVBOX_BASE/$1/workbench2" \
577 echo "Created new arvbox $2"
578 echo "export ARVBOX_CONTAINER=$2"
580 echo "clone <from> <to> clone an arvbox"
581 echo "available arvboxes: $(ls $ARVBOX_BASE)"
586 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
587 if test -n "$1" ; then
590 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
591 echo "Certificate copied to $CERT"
595 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'
599 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
601 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
602 echo "stop stop arvbox container"
603 echo "restart <config> stop, then run again"
604 echo "status print some information about current arvbox"
605 echo "ip print arvbox docker container ip address"
606 echo "host print arvbox published host"
607 echo "shell enter shell as root"
608 echo "ashell enter shell as 'arvbox'"
609 echo "psql enter postgres console"
610 echo "open open arvbox workbench in a web browser"
611 echo "root-cert get copy of root certificate"
612 echo "update <config> stop, pull latest image, run"
613 echo "build <config> build arvbox Docker image"
614 echo "reboot <config> stop, build arvbox Docker image, run"
615 echo "rebuild <config> build arvbox Docker image, no layer cache"
616 echo "reset delete arvbox arvados data (be careful!)"
617 echo "destroy delete all arvbox code and data (be careful!)"
618 echo "log <service> tail log of specified service"
619 echo "ls <options> list directories inside arvbox"
620 echo "cat <files> get contents of files inside arvbox"
621 echo "pipe run a bash script piped in from stdin"
622 echo "sv <start|stop|restart> <service> "
623 echo " change state of service inside arvbox"
624 echo "clone <from> <to> clone dev arvbox"