Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apptainer.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM dsarchive/dsa_common:latest
LABEL maintainer="Kitware, Inc. <kitware@kitware.com>"

RUN add-apt-repository -y ppa:apptainer/ppa \
&& apt update \
&& apt install -y apptainer-suid
10 changes: 10 additions & 0 deletions devops/singularity-5/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
assetstore
db
# opt
# logs
# fuse

girder
mongodb
etc.hosts
resolv.conf
16 changes: 16 additions & 0 deletions devops/singularity-5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Apptainer DSA (Girder 5)

Launches DSA containers using `apptainer`.

## Getting Started

```bash
# Build dsa_common with apptainer
./build.sh

# Pull DSA service images
./pull_images.sh

# Start DSA services
./dsa_compose.sh
```
2 changes: 2 additions & 0 deletions devops/singularity-5/SIF/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
3 changes: 3 additions & 0 deletions devops/singularity-5/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

sudo apptainer build SIF/dsa_common.sif dsa_common.def
80 changes: 80 additions & 0 deletions devops/singularity-5/dsa_common.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
Bootstrap: docker
From: dsarchive/dsa_common_5

%environment
export NVM_DIR=/root_opt/nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
[ -s /root_opt/venv/bin/activate ] && . /root_opt/venv/bin/activate

%post -c /bin/bash
set -euxo pipefail

# install nvm / node properly
export NVM_DIR=/opt/nvm

git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
. "$NVM_DIR/nvm.sh"

nvm install 24
nvm alias default 24
nvm use default

# install pyaml in virtual environment
. /opt/venv/bin/activate
/opt/venv/bin/pip install pyaml setuptools

# install apptainer
apt-get update
apt-get install -y --no-install-recommends \
ca-certificates \
fuse3 \
software-properties-common \
squashfs-tools \
uidmap \
wget

# Prefer distro package if available; otherwise install a pinned .deb from
# GitHub releases (works in environments where Launchpad PPAs are blocked).
if ! apt-get install -y --no-install-recommends apptainer; then
APPTAINER_VERSION="${APPTAINER_VERSION:-1.4.3}"
wget -O /tmp/apptainer.deb \
"https://github.com/apptainer/apptainer/releases/download/v${APPTAINER_VERSION}/apptainer_${APPTAINER_VERSION}_amd64.deb"
apt-get install -y /tmp/apptainer.deb
rm -f /tmp/apptainer.deb
fi
apptainer --version

# preserve image /opt so it can be copied into bind-mounted /opt at startup
mv /opt /root_opt

apt-get clean
rm -rf /var/lib/apt/lists/*

%runscript
set -x

if [ -d /opt/nvm ]; then
export NVM_DIR=/opt/nvm
. "$NVM_DIR/nvm.sh"
else
export NVM_DIR=/root_opt/nvm
. "$NVM_DIR/nvm.sh"
fi

if [ -f /opt/venv/bin/activate ]; then
. /opt/venv/bin/activate
else
. /root_opt/venv/bin/activate
fi

exec bash -c "$@"

%startscript
set -x

# assuming that the user mounts a local directory to /opt/
# this is necessary for getting the correct singularity permissions
echo " - Copying docker image's opt (/root_opt) to user mounted /opt"
echo " - Make sure you're mounting a local directory to /opt"
cp -r /root_opt/* /opt/
/opt/venv/bin/pip install pyaml setuptools
111 changes: 111 additions & 0 deletions devops/singularity-5/dsa_compose.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env bash
set -euxo pipefail

cd "$(dirname "$0")"
GIRDER_SRC="${GIRDER_SRC:-$(realpath ../../../girder)}"
if [ ! -d "$GIRDER_SRC" ]; then
echo "Missing GIRDER_SRC directory: $GIRDER_SRC"
exit 1
fi

apptainer instance stop -a || echo "No instances stopped"

# Load Modules
# module load slurm-drmaa

# Start instances
# MongoDB, RabbitMQ, Redis
apptainer instance start \
--bind ./db:/data/db \
SIF/mongodb.sif dsa-mongodb-1

apptainer instance start \
--env RABBITMQ_DEFAULT_USER=guest \
--env RABBITMQ_DEFAULT_PASS=guest \
--bind ./rabbitmqdata:/var/lib/rabbitmq/ \
SIF/rabbitMQ.sif dsa-rabbitMQ-1

apptainer instance start SIF/redis.sif dsa-redis-1

# # clean girder opt
# find ./opt/* -not -path "*opt/local_*" -not -path "*opt/.gitignore" -delete

# # set up worker opt
# # rm -rf ./worker_opt/*
# # cp -r ./opt/* ./worker_opt/
rm -rf ./tmp/*
mkdir -p ./tmp/sifs
TMP_OPT_GIRDER=$(mktemp -d --tmpdir=./tmp)
TMP_OPT_WORKER=$(mktemp -d --tmpdir=./tmp)

## Start Girder and Worker
apptainer instance start \
--bind ./assetstore:/assetstore \
--bind ./logs:/logs \
--bind ./tmp:/tmp \
--bind ./fuse:/fuse \
--bind ./girder.cfg:/etc/girder.cfg \
--bind ./start_girder.sh:/opt/start_girder.sh \
--bind ./provision.yaml:/opt/provision.yaml \
--bind ../ver5/provision.py:/opt/provision.py \
--bind "$GIRDER_SRC":/src/girder \
--bind $TMP_OPT_GIRDER:/opt \
SIF/dsa_common.sif test-dsarchive

apptainer instance start \
--bind ./logs:/logs \
--bind ./start_worker.sh:/opt/start_worker.sh \
--bind ./provision.yaml:/opt/provision.yaml \
--bind ../ver5/provision.py:/opt/provision.py \
--bind "$GIRDER_SRC":/src/girder \
--bind $TMP_OPT_WORKER:/opt \
SIF/dsa_common.sif dsa-worker-1
# --bind ./worker_opt:/opt \

# --bind ./blue:/blue/pinaki.sarder/rc-svc-pinaki.sarder-web \
# --no-mount /cmsuf \
# --bind /blue/pinaki.sarder/rc-svc-pinaki.sarder-web/logs:/logs \
# --bind /apps \
# --bind /var/run/munge:/run/munge \
# --bind /opt/slurm \

## Execute shells
apptainer exec instance://dsa-mongodb-1 mongod > /dev/null &

sleep 5 # TODO: WHY THE HELL IS THERE A RACE CONDITIONNNNNN
# the files seem to be not mounted properly before this stuff runs

apptainer run \
--env SIF_IMAGE_PATH="$(pwd)/tmp/sifs/" \
--env TMPDIR="$(pwd)/tmp" \
--env LOGS="$(pwd)/logs" \
--env DSA_PROVISION_YAML=/opt/provision.yaml \
--env GIRDER_WORKER_BROKER=amqp://guest:guest@localhost:5672/ \
--env GIRDER_WORKER_BACKEND=rpc://guest:guest@localhost:5672/ \
--env CELERY_BROKER_URL=amqp://guest:guest@localhost:5672/ \
--env CELERY_RESULT_BACKEND=rpc://guest:guest@localhost:5672/ \
instance://dsa-worker-1 /opt/start_worker.sh &

# --env PATH=/opt/slurm/bin:$PATH \
# --env SLURM_QOS=pinaki.sarder-dsa \
# --env SLURM_ACCOUNT=pinaki.sarder-dsa \


sleep 30

apptainer run \
--env SIF_IMAGE_PATH="$(pwd)/tmp/sifs/" \
--env TMPDIR="$(pwd)/tmp" \
--env LOGS="$(pwd)/logs" \
--env DSA_PROVISION_YAML=/opt/provision.yaml \
--env CELERY_BROKER_URL=amqp://guest:guest@localhost:5672/ \
--env CELERY_RESULT_BACKEND=rpc://guest:guest@localhost:5672/ \
--env GIRDER_NOTIFICATION_REDIS_URL=redis://localhost:6379 \
--env LARGE_IMAGE_CACHE_BACKEND=redis \
--env LARGE_IMAGE_CACHE_REDIS_URL=localhost:6379 \
--env DSA_WORKER_API_URL=http://localhost:8080/api/v1 \
instance://test-dsarchive /opt/start_girder.sh

# --env PATH=/opt/slurm/bin:$PATH \
# --env SLURM_QOS=pinaki.sarder-dsa \
# --env SLURM_ACCOUNT=pinaki.sarder-dsa \
2 changes: 2 additions & 0 deletions devops/singularity-5/fuse/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
6 changes: 6 additions & 0 deletions devops/singularity-5/girder.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[global]
server.socket_host = "0.0.0.0"
server.max_request_body_size = 1073741824

[database]
uri = "mongodb://localhost:27017/girder?socketTimeoutMS=3600000"
2 changes: 2 additions & 0 deletions devops/singularity-5/logs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
139 changes: 139 additions & 0 deletions devops/singularity-5/provision.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
# The provision script can take a yaml file with provision options
# This is a dictionary of command-line arguments for the provisioning script
force: False
samples: False
clean-delete-locks: True
sample-collection: Samples
sample-folder: Images
# Set use-defaults to False to skip default settings
use-defaults: True
# Set mongo_compat to False to not automatically set the mongo feature
# compatibility version to the current server version.
mongo-compat: True
# A list of additional pip modules to install; if any are girder plugins with
# client-side code, that code must be built in the shell step.
# pip:
# - girder-oauth
# - girder-ldap
# Run additional shell commands before start
# shell:
# - ls
# Default admin user if there are no admin users
admin:
login: admin
password: password
firstName: Admin
lastName: Admin
email: admin@nowhere.nil
public: True
# Default assetstore if there are no assetstores
assetstore:
method: createFilesystemAssetstore
name: Assetstore
root: /assetstore
# Any resources to ensure exist. A model must be specified. This creates the
# resource if there is no match for all specified values. A value of
# "resource:<path>" is converted to the resource document with that resource
# path. "resource:admin" uses the default admin, "resourceid:<path>" is the
# string id for the resource path, and "resourceid:admin" is the string if for
# default admin.
# You can add metadata to a resource. The default key is meta. If
# metadata_update is False, metadata will not be set if any metadata
# already exists.
resources:
- model: collection
name: Tasks
creator: resource:admin
public: True
- model: folder
parent: resource:collection/Tasks
parentType: collection
name: "Slicer CLI Web Tasks"
creator: resource:admin
public: True
# metadata:
# sample_key: sample_value
# metadata_key: meta
# metadata_update: True
settings:
worker.api_url: "http://localhost:8080/api/v1"
worker.direct_path: True

core.brand_name: "Digital Slide Archive"
# core.http_only_cookies: True
histomicsui.webroot_path: "histomics"
histomicsui.alternate_webroot_path: "histomicstk"
histomicsui.delete_annotations_after_ingest: True
homepage.markdown: |-
# Digital Slide Archive
---
## Bioinformatics Platform

Welcome to the **Digital Slide Archive**.

Developers who want to use the Girder REST API should check out the
[interactive web API docs](api/v1).

The [HistomicsUI](histomics) application is enabled.
slicer_cli_web.task_folder: "resourceid:collection/Tasks/Slicer CLI Web Tasks"
# List slicer-cli-images to pull, if not present, and load
# slicer-cli-image:
# - dsarchive/histomicstk:latest
# List slicer-cli-images to always pull, and load
slicer-cli-image-pull:
# - dsarchive/histomicstk:latest
# The worker can specify parameters for provisioning
# worker-rabbitmq-host: localhost:5672
worker-rabbitmq-user: guest
worker-rabbitmq-pass: guest
worker-rabbitmq-host: localhost
worker-config: /src/girder/worker/girder_worker/worker.local.cfg
# These have precedence over the top level values
worker:
# rabbitmq-host: girder:8080
# rabbitmq-user: guest
# rabbitmq-pass: guest
# config: /opt/girder_worker/girder_worker/worker.local.cfg
# Install additional pip packages in the worker
# shell:
# - pip -V
# - python -V
# pip:
# - -e /opt/local_girder_worker
# - --force-reinstall -e /opt/local_girder_worker
# - -e /opt/local_girder_worker/girder_worker/singularity
# - -e /opt/local_girder_worker/girder_worker/slurm
# - -e /opt/local_slicer_cli_web
# - -e /opt/local_slicer_cli_web/slicer_cli_web/singularity
shell:
- pip install --force-reinstall -e /src/girder
- pip install --force-reinstall -e /src/girder/worker
- pip install --force-reinstall -e /src/girder/plugins/slicer_cli_web
- pip install --force-reinstall --no-deps -e /src/girder/worker/girder_worker/singularity
# - pip install --force-reinstall --no-deps -e /src/girder/worker/girder_worker/slurm
- pip install --force-reinstall --no-deps -e /src/girder/plugins/slicer_cli_web/slicer_cli_web/singularity
- pip install --upgrade "girder-client>=5.0.0a5"

# Run additional shell commands in the worker before start
# shell:
# - pip -V
# - pip freeze | grep worker
# - pip install -e /opt/local_girder_worker
# - pip freeze | grep worker
# - ls
pip:
# - -e /opt/local_girder_worker
# - -e /opt/local_girder_worker/girder_worker/singularity
# - -e /opt/local_girder_worker/girder_worker/slurm
# - -e /opt/local_slicer_cli_web
# - -e /opt/local_slicer_cli_web/slicer_cli_web/singularity
shell:
- /bin/bash -lc 'cd /src/girder/plugins/slicer_cli_web/slicer_cli_web/web_client && if [ ! -f dist/style.css ]; then npm ci && npm run build; fi'
- pip install --force-reinstall -e /src/girder
- pip install --force-reinstall -e /src/girder/worker
- pip install --force-reinstall -e /src/girder/plugins/slicer_cli_web
- pip install --force-reinstall --no-deps -e /src/girder/worker/girder_worker/singularity
# - pip install --force-reinstall --no-deps -e /src/girder/worker/girder_worker/slurm
- pip install --force-reinstall --no-deps -e /src/girder/plugins/slicer_cli_web/slicer_cli_web/singularity
- pip install --upgrade "girder-client>=5.0.0a5"
5 changes: 5 additions & 0 deletions devops/singularity-5/pull_images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

apptainer pull SIF/rabbitMQ.sif library://sylabs/examples/rabbitmq
apptainer pull SIF/mongodb.sif docker://mongo:latest
apptainer pull SIF/redis.sif docker://redis:latest
2 changes: 2 additions & 0 deletions devops/singularity-5/rabbitmqdata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
Loading