diff --git a/50-config.py b/50-config.py new file mode 100755 index 00000000..6a526777 --- /dev/null +++ b/50-config.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# 1. Run .omero files from /opt/omero/server/config/ +# 2. Set omero config properties from CONFIG_ envvars +# Variable names should replace "." with "_" and "_" with "__" +# E.g. CONFIG_omero_web_public_enabled=false + +import os +from subprocess import call +from re import sub + + +CONFIG_OMERO = '/opt/omero/server/config/omero-server-config-update.sh' +OMERO = '/opt/omero/server/OMERO.server/bin/omero' + +if os.access(CONFIG_OMERO, os.X_OK): + rc = call([CONFIG_OMERO]) + assert rc == 0 + +for (k, v) in os.environ.iteritems(): + if k.startswith('CONFIG_'): + prop = k[7:] + prop = sub('([^_])_([^_])', r'\1.\2', prop) + prop = sub('__', '_', prop) + value = v + rc = call([OMERO, 'config', 'set', '--', prop, value]) + assert rc == 0 diff --git a/60-database.sh b/60-database.sh new file mode 100755 index 00000000..076c153a --- /dev/null +++ b/60-database.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# 50-config.py or equivalent must be run first to set all omero.db.* +# omero.db.host may require special handling since the default is +# to use `--link postgres:db` + +set -eu + +omero=/opt/omero/server/OMERO.server/bin/omero +omego=/opt/omero/omego/bin/omego +cd /opt/omero/server + +CONFIG_omero_db_host=${CONFIG_omero_db_host:-} +if [ -n "$CONFIG_omero_db_host" ]; then + DBHOST="$CONFIG_omero_db_host" +else + DBHOST=db + $omero config set omero.db.host "$DBHOST" +fi +DBUSER="${CONFIG_omero_db_user:-omero}" +DBNAME="${CONFIG_omero_db_name:-omero}" +DBPASS="${CONFIG_omero_db_pass:-omero}" +ROOTPASS="${ROOTPASS:-omero}" + +export PGPASSWORD="$DBPASS" + +i=0 +while ! psql -h "$DBHOST" -U "$DBUSER" "$DBNAME" >/dev/null 2>&1 < /dev/null; do + i=$(($i+1)) + if [ $i -ge 50 ]; then + echo "$(date) - postgres:5432 still not reachable, giving up" + exit 1 + fi + echo "$(date) - waiting for postgres:5432..." + sleep 1 +done +echo "postgres connection established" + +psql -w -h "$DBHOST" -U "$DBUSER" "$DBNAME" -c \ + "select * from dbpatch" 2> /dev/null && { + echo "Upgrading database" + $omego db upgrade --serverdir=OMERO.server +} || { + echo "Initialising database" + $omego db init --rootpass "$ROOTPASS" --serverdir=OMERO.server +} diff --git a/99-run.sh b/99-run.sh new file mode 100755 index 00000000..ec83b891 --- /dev/null +++ b/99-run.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eu + +omero=/opt/omero/server/OMERO.server/bin/omero +cd /opt/omero/server +echo "Starting OMERO.server" +exec $omero admin start --foreground diff --git a/Dockerfile b/Dockerfile index cf6a5310..bdbad5b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,13 +12,15 @@ RUN yum -y install epel-release \ ARG OMERO_VERSION=latest RUN ansible-playbook playbook.yml -e omero_server_release=$OMERO_VERSION -USER omero-server +RUN curl -L -o /usr/local/bin/dumb-init \ + https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 && \ + chmod +x /usr/local/bin/dumb-init +ADD entrypoint.sh /usr/local/bin/ +ADD 50-config.py 60-database.sh 99-run.sh /startup/ -# default.xml may be modified at runtime for a multinode configuration -RUN cp /opt/omero/server/OMERO.server/etc/templates/grid/default.xml /opt/omero/server/OMERO.server/etc/templates/grid/default.xml.orig +USER omero-server -EXPOSE 4061 4063 4064 +EXPOSE 4063 4064 VOLUME ["/OMERO", "/opt/omero/server/OMERO.server/var"] -ADD slave.cfg run.sh process_defaultxml.py /opt/omero/server/ -ENTRYPOINT ["/opt/omero/server/run.sh"] +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 00000000..9c44f0b5 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +OMERO.server Docker +=================== + +A CentOS 7 based Docker image for OMERO.server. + + +Running the images +------------------ + +To run the Docker images start a postgres DB: + + docker run -d --name postgres -e POSTGRES_PASSWORD=postgres postgres + +Then run OMERO.server passing the database configuration parameters if they differ from the defaults. +This example uses the default `postgres` system database for convenience, in practice you may want to create your own database. + + docker run -d --name omero-server --link postgres:db + -e CONFIG_omero_db_user=postgres \ + -e CONFIG_omero_db_pass=postgres \ + -e CONFIG_omero_db_name=postgres \ + -e ROOTPASS=omero-root-password \ + -p 4063:4063 -p 4064:4064 \ + openmicroscopy/omero-server + + +Configuration variables +----------------------- + +All [OMERO configuration properties](www.openmicroscopy.org/site/support/omero/sysadmins/config.html) can be set be defining environment variables `CONFIG_omero_property_name=`. +Since `.` is not allowed in a variable name `.` must be replaced by `_`, and `_` by `__`, for example + + -e CONFIG_omero_web_public_enabled=false + + +Configuration files +------------------- + +Additional configuration files for OMERO can be provided by mounting files into `/opt/omero/server/config/`. +Files will be loaded with `omero load`. +For example: + + docker run -d -v + /config/extra.omero:/opt/omero/server/config/extra.omero:ro + openmicroscopy/omero-server + +Parameters required for initializing the server such as database configuration *must* be set using environment variables. + + +Default volumes +--------------- + +- `/opt/omero/server/OMERO.server/var`: The OMERO.server `var` directory, including logs +- `/OMERO`: The OMERO data directory + + +Exposed ports +------------- + +- 4063 +- 4064 + + +Example with named volumes +-------------------------- + + docker volume create --name omero-db + docker volume create --name omero-data + + docker run -d --name postgres -e POSTGRES_PASSWORD=postgres + -v omero-db:/var/lib/postgresql/data postgres + docker run -d --name omero-server --link postgres:db + <-e CONFIG_omero_db_ ...> + -v omero-data:/OMERO + -p 4063:4063 -p 4064:4064 openmicroscopy/omero-server + + +Running without links +--------------------- + +As an alternative to running with `--link` the address of the database can be specified using the variable `CONFIG_omero_db_host` diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..a1b37df2 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,10 @@ +#!/usr/local/bin/dumb-init /bin/bash + +set -e + +for f in /startup/*; do + if [ -f "$f" -a -x "$f" ]; then + echo "Running $f $@" + "$f" "$@" + fi +done diff --git a/playbook.yml b/playbook.yml index 03188f0b..f4823e29 100644 --- a/playbook.yml +++ b/playbook.yml @@ -3,5 +3,10 @@ - role: openmicroscopy.omero-server vars: ice_version: "3.6" + ice_install_devel: False omero_server_database_manage: False omero_server_systemd_setup: False + omero_server_system_uid: 1000 + # You can reduce the size of the image by providing the URL to a + # precompiled Ice Python wheel + #ice_python_wheel: diff --git a/process_defaultxml.py b/process_defaultxml.py deleted file mode 100755 index 580370c9..00000000 --- a/process_defaultxml.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -""" -Convert the nodes and server-instances in default.xml to a multi-node -configuration - -The configuration string should be in the form node1:s1,s2,... node2:s3 ... - -Examples - -Everything on a single node (default, the same as passing no config): -master:Blitz-0,Indexer-0,DropBox,MonitorServer,FileServer,Storm,PixelData-0,Processor-0,Tables-0,TestDropBox - -Processor on a separate node: -master:Blitz-0,Indexer-0,DropBox,MonitorServer,FileServer,Storm,PixelData-0,Tables-0,TestDropBox slave:Processor-0 - -Two Processor and two PixelData on two separate nodes: -master:Blitz-0,Indexer-0,DropBox,MonitorServer,FileServer,Storm,Tables-0,TestDropBox slave-1:Processor-0,PixelData-0 slave-2:Processor-1,PixelData-1 -""" - - -import re -import sys - - -def getnodes(nodedescs): - nodes = {} - for nd in nodedescs: - s = '' - node, descs = nd.split(':') - descs = descs.split(',') - for d in descs: - try: - t, i = d.split('-') - except ValueError: - t = d - i = None - s += ' \s*\]*\>(.*?\)' -m = re.search(pattern, xml, re.DOTALL) -assert m - -nodedescs = sys.argv[2:] - -master = '\n \n' -slaves = '' -nodes = getnodes(nodedescs) -for nodename in sorted(nodes.keys()): - servers = nodes[nodename] - if nodename == 'master': - master = '%s%s' % (servers, master) - else: - slaves += ' \n%s \n' % (nodename, servers) - -if nodes: - xmlout = xml[:m.start(1)] + master + slaves + xml[m.end(1):] -else: - xmlout = xml -print xmlout diff --git a/requirements.yml b/requirements.yml index 44390aa6..f3129664 100644 --- a/requirements.yml +++ b/requirements.yml @@ -4,10 +4,10 @@ version: 1.0.0 - src: openmicroscopy.ice - version: 2.0.0 + version: 2.1.0 - src: openmicroscopy.java - version: 2.0.0 + version: 2.0.1 - src: openmicroscopy.omego version: 0.1.0 @@ -18,9 +18,8 @@ - src: openmicroscopy.omero-python-deps version: 1.1.0 -- name: openmicroscopy.omero-server -# version: 2.0.0-m1 - src: https://github.com/manics/ansible-role-omero-server/archive/devel.tar.gz +- src: openmicroscopy.omero-server + version: 2.0.0-m2 - src: openmicroscopy.postgresql version: 2.0.0 diff --git a/run.sh b/run.sh deleted file mode 100755 index 365439d9..00000000 --- a/run.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash - -set -eu - -TARGET=${1:-master} - -OMERO_SERVER=/opt/omero/server/OMERO.server -omero=$OMERO_SERVER/bin/omero -cd /opt/omero/server - -if [ "$TARGET" = bash ]; then - echo "Entering a shell" - exec bash -l -elif [ "$TARGET" = master ]; then - # Remaining args are the servers to run, default (no args) is to run all - # on master - if [ $# -gt 1 ]; then - shift - ARGS="$@" - else - ARGS= - fi - ./process_defaultxml.py OMERO.server/etc/templates/grid/default.xml.orig \ - $ARGS > OMERO.server/etc/templates/grid/default.xml - - DBHOST=${DBHOST:-} - if [ -z "$DBHOST" ]; then - DBHOST=db - fi - DBUSER=${DBUSER:-omero} - DBNAME=${DBNAME:-omero} - DBPASS=${DBPASS:-omero} - ROOTPASS=${ROOTPASS:-omero} - MASTER_IP=$(hostname -i) - - export PGPASSWORD="$DBPASS" - - i=0 - while ! psql -h $DBHOST -U$DBUSER $DBNAME >/dev/null 2>&1 < /dev/null; do - i=$(($i+1)) - if [ $i -ge 50 ]; then - echo "$(date) - postgres:5432 still not reachable, giving up" - exit 1 - fi - echo "$(date) - waiting for postgres:5432..." - sleep 1 - done - echo "postgres connection established" - - psql -w -h $DBHOST -U$DBUSER $DBNAME -c \ - "select * from dbpatch" 2> /dev/null && { - echo "Upgrading database" - DBCMD=upgrade - } || { - echo "Initialising database" - DBCMD=init - } - /opt/omero/omego/bin/omego db $DBCMD \ - --dbhost "$DBHOST" --dbuser "$DBUSER" --dbname "$DBNAME" \ - --dbpass "$DBPASS" --rootpass "$ROOTPASS" --serverdir=OMERO.server - - $omero config set omero.db.host "$DBHOST" - $omero config set omero.db.user "$DBUSER" - $omero config set omero.db.name "$DBNAME" - $omero config set omero.db.pass "$DBPASS" - - $omero config set omero.master.host "$MASTER_IP" - - if stat -t /config/* > /dev/null 2>&1; then - for f in /config/*; do - echo "Loading $f" - $omero load "$f" - done - fi - - echo "Starting $TARGET" - exec $omero admin start --foreground -else - MASTER_ADDR=${MASTER_ADDR:-} - if [ -z "$MASTER_ADDR" ]; then - MASTER_ADDR=master - fi - - SLAVE_ADDR=$(hostname -i) - - $omero config set omero.master.host "$MASTER_ADDR" - - if stat -t /config/* > /dev/null 2>&1; then - for f in /config/*; do - echo "Loading $f" - $omero load "$f" - done - fi - - echo "Master addr: $MASTER_ADDR Slave addr: $SLAVE_ADDR" - sed -e "s/@omero.slave.host@/$SLAVE_ADDR/" -e "s/@slave.name@/$TARGET/" \ - slave.cfg > OMERO.server/etc/$TARGET.cfg - grep '^Ice.Default.Router=' OMERO.server/etc/ice.config || \ - echo Ice.Default.Router= >> OMERO.server/etc/ice.config - sed -i -r "s|^(Ice.Default.Router=).*|\1OMERO.Glacier2/router:tcp -p 4063 -h $MASTER_ADDR|" \ - OMERO.server/etc/ice.config - - echo "Starting node $TARGET" - exec $omero node $TARGET start --foreground -fi diff --git a/slave.cfg b/slave.cfg deleted file mode 100644 index 3377eac0..00000000 --- a/slave.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# OMERO slave configuration -IceGrid.Node.Endpoints=tcp -h @omero.slave.host@ -IceGrid.Node.Name=@slave.name@ -IceGrid.Node.Data=var/@slave.name@ -IceGrid.Node.Output=var/log - -Ice.StdOut=var/log/@slave.name@.out -Ice.StdErr=var/log/@slave.name@.err diff --git a/test.sh b/test.sh index 1bc462b4..052fe215 100755 --- a/test.sh +++ b/test.sh @@ -9,7 +9,7 @@ IMAGE=omero-server:$PREFIX CLEAN=${CLEAN:-y} cleanup() { - docker rm -f -v $PREFIX-db $PREFIX-master $PREFIX-slave-1 + docker rm -f -v $PREFIX-db $PREFIX-server } if [ "$CLEAN" = y ]; then @@ -21,15 +21,13 @@ cleanup || true docker build -t $IMAGE . docker run -d --name $PREFIX-db -e POSTGRES_PASSWORD=postgres postgres -docker run -d --name $PREFIX-master --link $PREFIX-db:db \ +docker run -d --name $PREFIX-server --link $PREFIX-db:db \ -p 4063:4063 -p 4064:4064 \ - -e DBUSER=postgres -e DBPASS=postgres -e DBNAME=postgres \ + -e CONFIG_omero_db_user=postgres \ + -e CONFIG_omero_db_pass=postgres \ + -e CONFIG_omero_db_name=postgres \ -e ROOTPASS=omero-root-password \ - $IMAGE master \ - master:Blitz-0,Indexer-0,DropBox,MonitorServer,FileServer,Storm,PixelData-0,Tables-0 \ - slave-1:Processor-0 - -docker run -d --name $PREFIX-slave-1 --link $PREFIX-master:master $IMAGE slave-1 + $IMAGE # Smoke tests diff --git a/test_dropbox.sh b/test_dropbox.sh index 60a36f47..41429044 100755 --- a/test_dropbox.sh +++ b/test_dropbox.sh @@ -9,7 +9,7 @@ set -x OMERO=/opt/omero/server/OMERO.server/bin/omero FILENAME=$(date +%Y%m%d-%H%M%S-%N).fake -docker exec $PREFIX-master sh -c \ +docker exec $PREFIX-server sh -c \ "mkdir -p /OMERO/DropBox/root && touch /OMERO/DropBox/root/$FILENAME" echo -n "Checking for imported DropBox image $FILENAME " @@ -18,7 +18,7 @@ i=0 result= while [ $i -lt 60 ]; do sleep 4 - result=$(docker exec $PREFIX-master $OMERO hql -q -s localhost -u $OMERO_USER -w $OMERO_PASS "SELECT COUNT (*) FROM Image WHERE name='$FILENAME'" --style plain) + result=$(docker exec $PREFIX-server $OMERO hql -q -s localhost -u $OMERO_USER -w $OMERO_PASS "SELECT COUNT (*) FROM Image WHERE name='$FILENAME'" --style plain) if [ "$result" = "0,1" ]; then echo echo "Found image: $result" diff --git a/test_login.sh b/test_login.sh index d3af1b46..4f086404 100755 --- a/test_login.sh +++ b/test_login.sh @@ -11,7 +11,7 @@ OMERO=/opt/omero/server/OMERO.server/bin/omero # Wait up to 2 mins i=0 -while ! docker exec test-master $OMERO login -C -s localhost -u "$OMERO_USER" -q -w "$OMERO_PASS"; do +while ! docker exec test-server $OMERO login -C -s localhost -u "$OMERO_USER" -q -w "$OMERO_PASS"; do i=$(($i+1)) if [ $i -ge 24 ]; then echo "$(date) - OMERO.server still not reachable, giving up" diff --git a/test_processor.sh b/test_processor.sh index 78e650e4..193af4f2 100755 --- a/test_processor.sh +++ b/test_processor.sh @@ -12,15 +12,15 @@ DSNAME=$(date +%Y%m%d-%H%M%S-%N) FILENAME=$(date +%Y%m%d-%H%M%S-%N).fake SCRIPT=/omero/util_scripts/Dataset_To_Plate.py -dataset_id=$(docker exec $PREFIX-master $OMERO obj -q -s localhost -u $OMERO_USER -w $OMERO_PASS new Dataset name=$DSNAME | cut -d: -f2) +dataset_id=$(docker exec $PREFIX-server $OMERO obj -q -s localhost -u $OMERO_USER -w $OMERO_PASS new Dataset name=$DSNAME | cut -d: -f2) -docker exec $PREFIX-master sh -c \ +docker exec $PREFIX-server sh -c \ "touch /tmp/$FILENAME && $OMERO import -d $dataset_id /tmp/$FILENAME" -docker exec $PREFIX-master $OMERO script launch $SCRIPT IDs=$dataset_id +docker exec $PREFIX-server $OMERO script launch $SCRIPT IDs=$dataset_id echo "Completed with code $?" -result=$(docker exec $PREFIX-master $OMERO hql -q -s localhost -u $OMERO_USER -w $OMERO_PASS "SELECT COUNT(w) FROM WellSample w WHERE w.well.plate.name='$DSNAME' AND w.image.name='$FILENAME'" --style plain) +result=$(docker exec $PREFIX-server $OMERO hql -q -s localhost -u $OMERO_USER -w $OMERO_PASS "SELECT COUNT(w) FROM WellSample w WHERE w.well.plate.name='$DSNAME' AND w.image.name='$FILENAME'" --style plain) if [ "$result" != "0,1" ]; then echo "Script failed: $result" exit 2