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
246 git -C "$COMPOSER_ROOT" pull
248 if ! test -d "$WORKBENCH2_ROOT" ; then
249 git clone https://github.com/curoverse/arvados-workbench2.git "$WORKBENCH2_ROOT"
252 if [[ "$CONFIG" = test ]] ; then
254 mkdir -p $VAR_DATA/test
256 if test "$need_setup" = 1 ; then
259 --name=$ARVBOX_CONTAINER \
261 "--env=SVDIR=/etc/test-service" \
262 arvados/arvbox-dev$TAG
266 /usr/local/lib/arvbox/runsu.sh \
267 /usr/local/lib/arvbox/waitforpostgres.sh
271 /usr/local/lib/arvbox/runsu.sh \
272 /var/lib/arvbox/service/sso/run-service --only-setup
276 /usr/local/lib/arvbox/runsu.sh \
277 /var/lib/arvbox/service/api/run-service --only-setup
281 if [[ -z "$@" ]] ; then
282 interactive=--interactive
286 -e LINES=$(tput lines) \
287 -e COLUMNS=$(tput cols) \
289 -e WORKSPACE=/usr/src/arvados \
290 -e GEM_HOME=/var/lib/gems \
291 -e CONFIGSRC=/var/lib/arvados/run_tests \
293 /usr/local/lib/arvbox/runsu.sh \
294 /usr/src/arvados/build/run-tests.sh \
295 --temp /var/lib/arvados/test \
298 elif [[ "$CONFIG" = devenv ]] ; then
299 if [[ $need_setup = 1 ]] ; then
302 --name=${ARVBOX_CONTAINER} \
303 "--env=SVDIR=/etc/devenv-service" \
304 "--volume=$HOME:$HOME:rw" \
305 --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \
306 arvados/arvbox-dev$TAG
308 exec docker exec --interactive --tty \
309 -e LINES=$(tput lines) \
310 -e COLUMNS=$(tput cols) \
312 -e "ARVBOX_HOME=$HOME" \
313 -e "DISPLAY=$DISPLAY" \
315 ${ARVBOX_CONTAINER} \
316 /usr/local/lib/arvbox/devenv.sh "$@"
317 elif [[ "$CONFIG" =~ dev$ ]] ; then
320 --name=$ARVBOX_CONTAINER \
323 arvados/arvbox-dev$TAG
326 echo "The Arvados source code is checked out at: $ARVADOS_ROOT"
327 echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem"
329 echo "Unknown configuration '$CONFIG'"
340 if test $(echo $TAG | cut -c1-1) != '-' ; then
348 if echo "$CONFIG" | grep 'demo$' ; then
349 docker pull arvados/arvbox-demo$TAG
351 docker pull arvados/arvbox-dev$TAG
356 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
357 docker stop $ARVBOX_CONTAINER
360 VOLUMES=--volumes=true
361 if docker ps -a --filter "status=created" | grep -E "$ARVBOX_CONTAINER$" -q ; then
362 docker rm $VOLUMES $ARVBOX_CONTAINER
364 if docker ps -a --filter "status=exited" | grep -E "$ARVBOX_CONTAINER$" -q ; then
365 docker rm $VOLUMES $ARVBOX_CONTAINER
370 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then
371 echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)"
374 if docker --version |grep " 1\.[0-9]\." ; then
375 # Docker version prior 1.10 require -f flag
376 # -f flag removed in Docker 1.12
379 GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD)
380 docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER"
381 docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest
382 if test "$1" = localdemo -o "$1" = publicdemo ; then
383 docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER"
384 docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest
386 docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER"
387 docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest
393 localdemo|publicdemo|dev|publicdev|test|devenv)
397 echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv"
404 if test -n "$subcmd" ; then
415 NO_CACHE=--no-cache build $@
424 exec docker exec --interactive --tty \
425 -e LINES=$(tput lines) \
426 -e COLUMNS=$(tput cols) \
428 -e GEM_HOME=/var/lib/gems \
429 $ARVBOX_CONTAINER /bin/bash
433 exec docker exec --interactive --tty \
434 -e LINES=$(tput lines) \
435 -e COLUMNS=$(tput cols) \
437 -e GEM_HOME=/var/lib/gems \
439 -w /usr/src/arvados \
440 $ARVBOX_CONTAINER /bin/bash --login
444 exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash -
480 exec xdg-open http://$(gethost)
484 echo "Container: $ARVBOX_CONTAINER"
485 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then
486 echo "Cluster id: $(getclusterid)"
487 echo "Status: running"
488 echo "Container IP: $(getip)"
489 echo "Published host: $(gethost)"
491 echo "Status: not running"
493 if test -d "$ARVBOX_DATA" ; then
494 echo "Data: $ARVBOX_DATA"
495 elif docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q ; then
496 echo "Data: $ARVBOX_CONTAINER-data"
504 if test -d "$ARVBOX_DATA" ; then
505 if test "$subcmd" = destroy ; then
506 if test "$1" != -f ; then
507 echo "WARNING! This will delete your entire arvbox ($ARVBOX_DATA)."
508 echo "Use destroy -f if you really mean it."
512 rm -rf "$ARVBOX_DATA"
514 if test "$1" != -f ; then
515 echo "WARNING! This will delete your arvbox data ($ARVBOX_DATA)."
516 echo "Code and downloaded packages will be preserved."
517 echo "Use reset -f if you really mean it."
521 rm -rf "$ARVBOX_DATA/postgres"
522 rm -rf "$ARVBOX_DATA/var"
525 if test "$1" != -f ; then
526 echo "WARNING! This will delete your data container $ARVBOX_CONTAINER-data. Use -f if you really mean it."
530 docker rm "$ARVBOX_CONTAINER-data"
535 if test -n "$1" ; then
536 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"
538 exec docker exec -ti $ARVBOX_CONTAINER tail $(docker exec -ti $ARVBOX_CONTAINER find -L /etc -path '/etc/service/*/log/main/current' -printf " %p")
543 if test -n "$1" ; then
544 exec docker exec $ARVBOX_CONTAINER cat "$@"
546 echo "Usage: $0 $subcmd <files>"
551 exec docker exec -ti $ARVBOX_CONTAINER /usr/bin/env TERM=$TERM ls "$@"
555 if test -n "$1" -a -n "$2" ; then
556 exec docker exec $ARVBOX_CONTAINER sv "$@"
558 echo "Usage: $0 $subcmd <start|stop|restart> <service>"
559 echo "Available services:"
560 exec docker execa $ARVBOX_CONTAINER ls /etc/service
565 if test -n "$2" ; then
566 mkdir -p "$ARVBOX_BASE/$2"
567 cp -a "$ARVBOX_BASE/$1/passenger" \
568 "$ARVBOX_BASE/$1/gems" \
569 "$ARVBOX_BASE/$1/pip" \
570 "$ARVBOX_BASE/$1/npm" \
571 "$ARVBOX_BASE/$1/gopath" \
572 "$ARVBOX_BASE/$1/Rlibs" \
573 "$ARVBOX_BASE/$1/arvados" \
574 "$ARVBOX_BASE/$1/sso-devise-omniauth-provider" \
575 "$ARVBOX_BASE/$1/composer" \
576 "$ARVBOX_BASE/$1/workbench2" \
578 echo "Created new arvbox $2"
579 echo "export ARVBOX_CONTAINER=$2"
581 echo "clone <from> <to> clone an arvbox"
582 echo "available arvboxes: $(ls $ARVBOX_BASE)"
587 CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt
588 if test -n "$1" ; then
591 docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT"
592 echo "Certificate copied to $CERT"
596 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'
600 echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html"
602 echo "start|run <config> [tag] start $ARVBOX_CONTAINER container"
603 echo "stop stop arvbox container"
604 echo "restart <config> stop, then run again"
605 echo "status print some information about current arvbox"
606 echo "ip print arvbox docker container ip address"
607 echo "host print arvbox published host"
608 echo "shell enter shell as root"
609 echo "ashell enter shell as 'arvbox'"
610 echo "psql enter postgres console"
611 echo "open open arvbox workbench in a web browser"
612 echo "root-cert get copy of root certificate"
613 echo "update <config> stop, pull latest image, run"
614 echo "build <config> build arvbox Docker image"
615 echo "reboot <config> stop, build arvbox Docker image, run"
616 echo "rebuild <config> build arvbox Docker image, no layer cache"
617 echo "reset delete arvbox arvados data (be careful!)"
618 echo "destroy delete all arvbox code and data (be careful!)"
619 echo "log <service> tail log of specified service"
620 echo "ls <options> list directories inside arvbox"
621 echo "cat <files> get contents of files inside arvbox"
622 echo "pipe run a bash script piped in from stdin"
623 echo "sv <start|stop|restart> <service> "
624 echo " change state of service inside arvbox"
625 echo "clone <from> <to> clone dev arvbox"