X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/08d0b1ab43499b7f13462d5e3555d239b4634d22..dc08f17cc3c90714efafb11e38e27ca8ea1b5f5b:/tools/arvbox/bin/arvbox diff --git a/tools/arvbox/bin/arvbox b/tools/arvbox/bin/arvbox index 74933718c7..b3b9a5fcb4 100755 --- a/tools/arvbox/bin/arvbox +++ b/tools/arvbox/bin/arvbox @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright (C) The Arvados Authors. All rights reserved. # # SPDX-License-Identifier: AGPL-3.0 @@ -19,11 +19,13 @@ if ! which docker >/dev/null 2>/dev/null ; then fi if test -z "$ARVBOX_DOCKER" ; then + set +e if which greadlink >/dev/null 2>/dev/null ; then ARVBOX_DOCKER=$(greadlink -f $(dirname $0)/../lib/arvbox/docker) else ARVBOX_DOCKER=$(readlink -f $(dirname $0)/../lib/arvbox/docker) fi + set -e fi if test -z "$ARVBOX_CONTAINER" ; then @@ -42,18 +44,21 @@ if test -z "$ARVADOS_ROOT" ; then ARVADOS_ROOT="$ARVBOX_DATA/arvados" fi -if test -z "$SSO_ROOT" ; then - SSO_ROOT="$ARVBOX_DATA/sso-devise-omniauth-provider" +if test -z "$WORKBENCH2_ROOT" ; then + WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2" fi -if test -z "$COMPOSER_ROOT" ; then - COMPOSER_ROOT="$ARVBOX_DATA/composer" +if test -z "$ARVADOS_BRANCH" ; then + ARVADOS_BRANCH=main fi -if test -z "$WORKBENCH2_ROOT" ; then - WORKBENCH2_ROOT="$ARVBOX_DATA/workbench2" +if test -z "$WORKBENCH2_BRANCH" ; then + WORKBENCH2_BRANCH=main fi +# Update this to the docker tag for the version on releases. +DEFAULT_TAG= + PG_DATA="$ARVBOX_DATA/postgres" VAR_DATA="$ARVBOX_DATA/var" PASSENGER="$ARVBOX_DATA/passenger" @@ -62,9 +67,10 @@ PIPCACHE="$ARVBOX_DATA/pip" NPMCACHE="$ARVBOX_DATA/npm" GOSTUFF="$ARVBOX_DATA/gopath" RLIBS="$ARVBOX_DATA/Rlibs" +ARVADOS_CONTAINER_PATH="/var/lib/arvados-arvbox" getip() { - docker inspect $ARVBOX_CONTAINER | grep \"IPAddress\" | head -n1 | tr -d ' ":,\n' | cut -c10- + docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $ARVBOX_CONTAINER } gethost() { @@ -80,7 +86,7 @@ gethost() { } getclusterid() { - docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/api_uuid_prefix + docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/api_uuid_prefix } updateconf() { @@ -97,16 +103,23 @@ EOF fi } +listusers() { + docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml $(getclusterid) list +} + wait_for_arvbox() { FF=/tmp/arvbox-fifo-$$ mkfifo $FF docker logs -f $ARVBOX_CONTAINER > $FF & LOGPID=$! while read line ; do - if echo $line | grep "ok: down: ready:" >/dev/null ; then + if [[ $line =~ "ok: down: ready:" ]] ; then kill $LOGPID - else - echo $line + set +e + wait $LOGPID 2>/dev/null + set -e + else + echo $line fi done < $FF rm $FF @@ -120,19 +133,22 @@ wait_for_arvbox() { docker_run_dev() { docker run \ - "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \ - "--volume=$SSO_ROOT:/usr/src/sso:rw" \ - "--volume=$COMPOSER_ROOT:/usr/src/composer:rw" \ + "--volume=$ARVADOS_ROOT:/usr/src/arvados:rw" \ "--volume=$WORKBENCH2_ROOT:/usr/src/workbench2:rw" \ "--volume=$PG_DATA:/var/lib/postgresql:rw" \ - "--volume=$VAR_DATA:/var/lib/arvados:rw" \ + "--volume=$VAR_DATA:$ARVADOS_CONTAINER_PATH:rw" \ "--volume=$PASSENGER:/var/lib/passenger:rw" \ - "--volume=$GEMS:/var/lib/gems:rw" \ + "--volume=$GEMS:/var/lib/arvados-arvbox/.gem:rw" \ "--volume=$PIPCACHE:/var/lib/pip:rw" \ "--volume=$NPMCACHE:/var/lib/npm:rw" \ "--volume=$GOSTUFF:/var/lib/gopath:rw" \ "--volume=$RLIBS:/var/lib/Rlibs:rw" \ - "$@" + --label "org.arvados.arvbox_config=$CONFIG" \ + "$@" +} + +running_config() { + docker inspect $ARVBOX_CONTAINER -f '{{index .Config.Labels "org.arvados.arvbox_config"}}' } run() { @@ -144,39 +160,51 @@ run() { need_setup=1 if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then - if test "$CONFIG" = test ; then + if [[ $(running_config) != "$CONFIG" ]] ; then + echo "Container $ARVBOX_CONTAINER is '$(running_config)' config but requested '$CONFIG'; use restart or reboot" + return 1 + fi + if test "$CONFIG" = test -o "$CONFIG" = devenv ; then need_setup=0 else echo "Container $ARVBOX_CONTAINER is already running" - exit 0 + return 0 fi fi if test $need_setup = 1 ; then if docker ps -a | grep -E "$ARVBOX_CONTAINER$" -q ; then echo "Container $ARVBOX_CONTAINER already exists but is not running; use restart or reboot" - exit 1 + return 1 fi fi if test -n "$TAG" then if test $(echo $TAG | cut -c1-1) != '-' ; then - TAG=":$TAG" + TAG=":$TAG" shift else + if [[ $TAG = '-' ]] ; then + shift + fi unset TAG fi fi - if echo "$CONFIG" | grep '^public' ; then + if test -z "$TAG" -a -n "$DEFAULT_TAG"; then + TAG=":$DEFAULT_TAG" + fi + + if [[ "$CONFIG" =~ ^public ]] ; then if test -n "$ARVBOX_PUBLISH_IP" ; then localip=$ARVBOX_PUBLISH_IP else defaultdev=$(/sbin/ip route|awk '/default/ { print $5 }') localip=$(ip addr show $defaultdev | grep 'inet ' | sed 's/ *inet \(.*\)\/.*/\1/') fi - iptemp=$(tempfile) + echo "Public arvbox will use address $localip" + iptemp=$(mktemp) echo $localip > $iptemp chmod og+r $iptemp PUBLIC="--volume=$iptemp:/var/run/localip_override @@ -184,26 +212,27 @@ run() { --publish=3001:3001 --publish=8000:8000 --publish=8900:8900 - --publish=9001:9001 + --publish=9000:9000 --publish=9002:9002 - --publish=25100:25100 - --publish=25107:25107 - --publish=25108:25108 + --publish=9004:9004 + --publish=25101:25101 --publish=8001:8001 - --publish=8002:8002" + --publish=8002:8002 + --publish=4202:4202 + --publish=45000-45020:45000-45020" else PUBLIC="" fi - if echo "$CONFIG" | grep 'demo$' ; then + if [[ "$CONFIG" =~ demo$ ]] ; then if test -d "$ARVBOX_DATA" ; then echo "It looks like you already have a development container named $ARVBOX_CONTAINER." - echo "Set ARVBOX_CONTAINER to set a different name for your demo container" + echo "Set environment variable ARVBOX_CONTAINER to set a different name for your demo container" exit 1 fi if ! (docker ps -a | grep -E "$ARVBOX_CONTAINER-data$" -q) ; then - docker create -v /var/lib/postgresql -v /var/lib/arvados --name $ARVBOX_CONTAINER-data arvados/arvbox-demo /bin/true + docker create -v /var/lib/postgresql -v $ARVADOS_CONTAINER_PATH --name $ARVBOX_CONTAINER-data arvados/arvbox-demo$TAG /bin/true fi docker run \ @@ -211,6 +240,7 @@ run() { --name=$ARVBOX_CONTAINER \ --privileged \ --volumes-from $ARVBOX_CONTAINER-data \ + --label "org.arvados.arvbox_config=$CONFIG" \ $PUBLIC \ arvados/arvbox-demo$TAG updateconf @@ -218,21 +248,16 @@ run() { else mkdir -p "$PG_DATA" "$VAR_DATA" "$PASSENGER" "$GEMS" "$PIPCACHE" "$NPMCACHE" "$GOSTUFF" "$RLIBS" - if ! test -d "$ARVADOS_ROOT" ; then - git clone https://github.com/curoverse/arvados.git "$ARVADOS_ROOT" - fi - if ! test -d "$SSO_ROOT" ; then - git clone https://github.com/curoverse/sso-devise-omniauth-provider.git "$SSO_ROOT" - fi - if ! test -d "$COMPOSER_ROOT" ; then - git clone https://github.com/curoverse/composer.git "$COMPOSER_ROOT" + git clone https://git.arvados.org/arvados.git "$ARVADOS_ROOT" + git -C "$ARVADOS_ROOT" checkout $ARVADOS_BRANCH fi if ! test -d "$WORKBENCH2_ROOT" ; then - git clone https://github.com/curoverse/arvados-workbench2.git "$WORKBENCH2_ROOT" + git clone https://git.arvados.org/arvados-workbench2.git "$WORKBENCH2_ROOT" + git -C "$ARVADOS_ROOT" checkout $WORKBENCH2_BRANCH fi - if test "$CONFIG" = test ; then + if [[ "$CONFIG" = test ]] ; then mkdir -p $VAR_DATA/test @@ -241,34 +266,52 @@ run() { --detach \ --name=$ARVBOX_CONTAINER \ --privileged \ - "--env=SVDIR=/etc/test-service" \ + "--env=SVDIR=/etc/test-service" \ arvados/arvbox-dev$TAG docker exec -ti \ $ARVBOX_CONTAINER \ /usr/local/lib/arvbox/runsu.sh \ /usr/local/lib/arvbox/waitforpostgres.sh + fi - docker exec -ti \ - $ARVBOX_CONTAINER \ - /usr/local/lib/arvbox/runsu.sh \ - /var/lib/arvbox/service/sso/run-service --only-setup - - docker exec -ti \ - $ARVBOX_CONTAINER \ - /usr/local/lib/arvbox/runsu.sh \ - /var/lib/arvbox/service/api/run-service --only-setup + interactive="" + if [[ -z "$@" ]] ; then + interactive=--interactive fi docker exec -ti \ + -e LINES=$(tput lines) \ + -e COLUMNS=$(tput cols) \ + -e TERM=$TERM \ + -e WORKSPACE=/usr/src/arvados \ + -e CONFIGSRC=$ARVADOS_CONTAINER_PATH/run_tests \ $ARVBOX_CONTAINER \ /usr/local/lib/arvbox/runsu.sh \ /usr/src/arvados/build/run-tests.sh \ - --temp /var/lib/arvados/test \ - WORKSPACE=/usr/src/arvados \ - GEM_HOME=/var/lib/gems \ + --temp $ARVADOS_CONTAINER_PATH/test \ + $interactive \ "$@" - elif echo "$CONFIG" | grep 'dev$' ; then + elif [[ "$CONFIG" = devenv ]] ; then + if [[ $need_setup = 1 ]] ; then + docker_run_dev \ + --detach \ + --name=${ARVBOX_CONTAINER} \ + "--env=SVDIR=/etc/devenv-service" \ + "--volume=$HOME:$HOME:rw" \ + --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \ + arvados/arvbox-dev$TAG + fi + exec docker exec --interactive --tty \ + -e LINES=$(tput lines) \ + -e COLUMNS=$(tput cols) \ + -e TERM=$TERM \ + -e "ARVBOX_HOME=$HOME" \ + -e "DISPLAY=$DISPLAY" \ + --workdir=$PWD \ + ${ARVBOX_CONTAINER} \ + /usr/local/lib/arvbox/devenv.sh "$@" + elif [[ "$CONFIG" =~ dev$ ]] ; then docker_run_dev \ --detach \ --name=$ARVBOX_CONTAINER \ @@ -278,7 +321,12 @@ run() { updateconf wait_for_arvbox echo "The Arvados source code is checked out at: $ARVADOS_ROOT" - echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem" + echo "The Arvados testing root certificate is $VAR_DATA/root-cert.pem" + if [[ "$(listusers)" =~ ^\{\} ]] ; then + echo "No users defined, use 'arvbox adduser' to add user logins" + else + echo "Use 'arvbox listusers' to see user logins" + fi else echo "Unknown configuration '$CONFIG'" fi @@ -292,7 +340,7 @@ update() { if test -n "$TAG" then if test $(echo $TAG | cut -c1-1) != '-' ; then - TAG=":$TAG" + TAG=":$TAG" shift else unset TAG @@ -300,9 +348,9 @@ update() { fi if echo "$CONFIG" | grep 'demo$' ; then - docker pull arvados/arvbox-demo$TAG + docker pull arvados/arvbox-demo$TAG else - docker pull arvados/arvbox-dev$TAG + docker pull arvados/arvbox-dev$TAG fi } @@ -321,6 +369,7 @@ stop() { } build() { + export DOCKER_BUILDKIT=1 if ! test -f "$ARVBOX_DOCKER/Dockerfile.base" ; then echo "Could not find Dockerfile (expected it at $ARVBOX_DOCKER/Dockerfile.base)" exit 1 @@ -331,24 +380,54 @@ build() { FORCE=-f fi GITHEAD=$(cd $ARVBOX_DOCKER && git log --format=%H -n1 HEAD) - docker build --build-arg=arvados_version=$GITHEAD $NO_CACHE -t arvados/arvbox-base:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.base" "$ARVBOX_DOCKER" - docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest + + set +e + if which greadlink >/dev/null 2>/dev/null ; then + LOCAL_ARVADOS_ROOT=$(greadlink -f $(dirname $0)/../../../) + else + LOCAL_ARVADOS_ROOT=$(readlink -f $(dirname $0)/../../../) + fi + set -e + + # Get the go version we should use for bootstrapping + GO_VERSION=`grep 'const goversion =' $LOCAL_ARVADOS_ROOT/lib/install/deps.go |awk -F'"' '{print $2}'` + if test "$1" = localdemo -o "$1" = publicdemo ; then - docker build $NO_CACHE -t arvados/arvbox-demo:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.demo" "$ARVBOX_DOCKER" - docker tag $FORCE arvados/arvbox-demo:$GITHEAD arvados/arvbox-demo:latest + BUILDTYPE=demo else - docker build $NO_CACHE -t arvados/arvbox-dev:$GITHEAD -f "$ARVBOX_DOCKER/Dockerfile.dev" "$ARVBOX_DOCKER" - docker tag $FORCE arvados/arvbox-dev:$GITHEAD arvados/arvbox-dev:latest + BUILDTYPE=dev fi + + if test "$ARVADOS_BRANCH" = "main" ; then + ARVADOS_BRANCH=$GITHEAD + fi + + docker build --build-arg=BUILDTYPE=$BUILDTYPE $NO_CACHE \ + --build-arg=go_version=$GO_VERSION \ + --build-arg=arvados_version=$ARVADOS_BRANCH \ + --build-arg=workbench2_version=$WORKBENCH2_BRANCH \ + --build-arg=workdir=/tools/arvbox/lib/arvbox/docker \ + -t arvados/arvbox-base:$GITHEAD \ + -f "$ARVBOX_DOCKER/Dockerfile.base" \ + "$LOCAL_ARVADOS_ROOT" + docker tag $FORCE arvados/arvbox-base:$GITHEAD arvados/arvbox-base:latest + docker build $NO_CACHE \ + --build-arg=go_version=$GO_VERSION \ + --build-arg=arvados_version=$ARVADOS_BRANCH \ + --build-arg=workbench2_version=$WORKBENCH2_BRANCH \ + -t arvados/arvbox-$BUILDTYPE:$GITHEAD \ + -f "$ARVBOX_DOCKER/Dockerfile.$BUILDTYPE" \ + "$ARVBOX_DOCKER" + docker tag $FORCE arvados/arvbox-$BUILDTYPE:$GITHEAD arvados/arvbox-$BUILDTYPE:latest } check() { case "$1" in - localdemo|publicdemo|dev|publicdev|test) + localdemo|publicdemo|dev|publicdev|test|devenv) true ;; *) - echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test" + echo "Argument to $subcmd must be one of localdemo, publicdemo, dev, publicdev, test, devenv" exit 1 ;; esac @@ -375,16 +454,25 @@ case "$subcmd" in ;; sh*) - exec docker exec -ti \ - -e LINES=$(tput lines) \ - -e COLUMNS=$(tput cols) \ - -e TERM=$TERM \ - -e GEM_HOME=/var/lib/gems \ - $ARVBOX_CONTAINER /bin/bash + exec docker exec --interactive --tty \ + -e LINES=$(tput lines) \ + -e COLUMNS=$(tput cols) \ + -e TERM=$TERM \ + $ARVBOX_CONTAINER /bin/bash + ;; + + ash*) + exec docker exec --interactive --tty \ + -e LINES=$(tput lines) \ + -e COLUMNS=$(tput cols) \ + -e TERM=$TERM \ + -u arvbox \ + -w /usr/src/arvados \ + $ARVBOX_CONTAINER /bin/bash --login ;; pipe) - exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env GEM_HOME=/var/lib/gems /bin/bash - + exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash - ;; stop) @@ -407,7 +495,7 @@ case "$subcmd" in update) check $@ stop - update $@ + update $@ run $@ ;; @@ -426,10 +514,11 @@ case "$subcmd" in status) echo "Container: $ARVBOX_CONTAINER" if docker ps -a --filter "status=running" | grep -E "$ARVBOX_CONTAINER$" -q ; then - echo "Cluster id: $(getclusterid)" + echo "Cluster id: $(getclusterid)" echo "Status: running" echo "Container IP: $(getip)" echo "Published host: $(gethost)" + echo "Workbench: https://$(gethost)" else echo "Status: not running" fi @@ -452,6 +541,7 @@ case "$subcmd" in exit 1 fi set -x + chmod -R u+w "$ARVBOX_DATA" rm -rf "$ARVBOX_DATA" else if test "$1" != -f ; then @@ -500,13 +590,22 @@ case "$subcmd" in else echo "Usage: $0 $subcmd " echo "Available services:" - exec docker execa $ARVBOX_CONTAINER ls /etc/service + exec docker exec $ARVBOX_CONTAINER ls /etc/service fi ;; clone) if test -n "$2" ; then - cp -r "$ARVBOX_BASE/$1" "$ARVBOX_BASE/$2" + mkdir -p "$ARVBOX_BASE/$2" + cp -a "$ARVBOX_BASE/$1/passenger" \ + "$ARVBOX_BASE/$1/gems" \ + "$ARVBOX_BASE/$1/pip" \ + "$ARVBOX_BASE/$1/npm" \ + "$ARVBOX_BASE/$1/gopath" \ + "$ARVBOX_BASE/$1/Rlibs" \ + "$ARVBOX_BASE/$1/arvados" \ + "$ARVBOX_BASE/$1/workbench2" \ + "$ARVBOX_BASE/$2" echo "Created new arvbox $2" echo "export ARVBOX_CONTAINER=$2" else @@ -516,71 +615,105 @@ case "$subcmd" in ;; root-cert) - CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.pem - if test -n "$1" ; then - CERT="$1" + CERT=$PWD/${ARVBOX_CONTAINER}-root-cert.crt + if test -n "$1" ; then + CERT="$1" + fi + docker exec $ARVBOX_CONTAINER cat $ARVADOS_CONTAINER_PATH/root-cert.pem > "$CERT" + echo "Certificate copied to $CERT" + ;; + + psql) + exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados' + ;; + + checkpoint) + exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec pg_dump --host=localhost --username=arvados --clean arvados_development > $ARVADOS_CONTAINER_PATH/checkpoint.sql' + ;; + + restore) + exec docker exec -ti $ARVBOX_CONTAINER bash -c 'PGPASSWORD=$(cat $ARVADOS_CONTAINER_PATH/api_database_pw) exec psql --dbname=arvados_development --host=localhost --username=arvados --quiet --file=$ARVADOS_CONTAINER_PATH/checkpoint.sql' + ;; + + hotreset) + exec docker exec -i $ARVBOX_CONTAINER /usr/bin/env /bin/bash - < [password]" fi - docker exec $ARVBOX_CONTAINER cat /var/lib/arvados/root-cert.pem > "$CERT" - echo "Certificate copied to $CERT" - ;; - - devenv) - set -x - if docker ps -a --filter "status=exited" | grep -E "${ARVBOX_CONTAINER}-devenv$" -q ; then - docker start ${ARVBOX_CONTAINER}-devenv - elif ! (docker ps -a --filter "status=running" | grep -E "${ARVBOX_CONTAINER}-devenv$" -q) ; then - docker_run_dev \ - --detach \ - --name=${ARVBOX_CONTAINER}-devenv \ - "--env=SVDIR=/etc/devenv-service" \ - "--volume=$HOME:$HOME:rw" \ - --volume=/tmp/.X11-unix:/tmp/.X11-unix:rw \ - arvados/arvbox-dev$TAG + ;; + + removeuser) + if [[ -n "$1" ]] ; then + docker exec -ti $ARVBOX_CONTAINER /usr/local/lib/arvbox/edit_users.py $ARVADOS_CONTAINER_PATH/cluster_config.yml.override $(getclusterid) remove $@ + docker exec $ARVBOX_CONTAINER sv restart controller + else + echo "Usage: removeuser " fi + ;; - exec docker exec --interactive --tty \ - -e LINES=$(tput lines) \ - -e COLUMNS=$(tput cols) \ - -e TERM=$TERM \ - -e "ARVBOX_HOME=$HOME" \ - -e "DISPLAY=$DISPLAY" \ - --workdir=$PWD \ - ${ARVBOX_CONTAINER}-devenv \ - /usr/local/lib/arvbox/devenv.sh "$@" - ;; - - devenv-stop) - docker stop ${ARVBOX_CONTAINER}-devenv - ;; - - devenv-reset) - docker stop ${ARVBOX_CONTAINER}-devenv - docker rm ${ARVBOX_CONTAINER}-devenv - ;; + listusers) + listusers + ;; *) - echo "Arvados-in-a-box http://arvados.org" + echo "Arvados-in-a-box https://doc.arvados.org/install/arvbox.html" echo - echo "start|run [tag] start $ARVBOX_CONTAINER container" - echo "stop stop arvbox container" - echo "restart stop, then run again" - echo "status print some information about current arvbox" - echo "ip print arvbox docker container ip address" - echo "host print arvbox published host" - echo "shell enter arvbox shell" - echo "open open arvbox workbench in a web browser" - echo "root-cert get copy of root certificate" - echo "update stop, pull latest image, run" - echo "build build arvbox Docker image" - echo "reboot stop, build arvbox Docker image, run" - echo "rebuild build arvbox Docker image, no layer cache" - echo "reset delete arvbox arvados data (be careful!)" - echo "destroy delete all arvbox code and data (be careful!)" - echo "log tail log of specified service" - echo "ls list directories inside arvbox" - echo "cat get contents of files inside arvbox" - echo "pipe run a bash script piped in from stdin" - echo "sv change state of service inside arvbox" - echo "clone clone an arvbox" + echo "start|run [tag] start $ARVBOX_CONTAINER container" + echo "stop stop arvbox container" + echo "restart stop, then run again" + echo "status print some information about current arvbox" + echo "ip print arvbox docker container ip address" + echo "host print arvbox published host" + echo "shell enter shell as root" + echo "ashell enter shell as 'arvbox'" + echo "psql enter postgres console" + echo "open open arvbox workbench in a web browser" + echo "root-cert get copy of root certificate" + echo "update stop, pull latest image, run" + echo "build build arvbox Docker image" + echo "reboot stop, build arvbox Docker image, run" + echo "rebuild build arvbox Docker image, no layer cache" + echo "checkpoint create database backup" + echo "restore restore checkpoint" + echo "hotreset reset database and restart API without restarting container" + echo "reset delete arvbox arvados data (be careful!)" + echo "destroy delete all arvbox code and data (be careful!)" + echo "log tail log of specified service" + echo "ls list directories inside arvbox" + echo "cat get contents of files inside arvbox" + echo "pipe run a bash script piped in from stdin" + echo "sv " + echo " change state of service inside arvbox" + echo "clone clone dev arvbox" + echo "adduser [password]" + echo " add a user login" + echo "removeuser " + echo " remove user login" + echo "listusers list user logins" ;; esac