From 304b11d8b6f4eb5c296d57125126f29b9274a257 Mon Sep 17 00:00:00 2001 From: manzuoni-astera Date: Thu, 6 Aug 2026 12:49:10 -0400 Subject: [PATCH] feat(astera): put SBGrid on $PATH when /programs is mounted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Astera installs the SBGrid collection once on a shared `sbgrid-programs` PVC, which the actl catalog auto-mounts read-only at /programs for every diffuse profile. The mount arrives regardless of image, but scientists on this image still had to run three manual steps before phenix worked. Two of those steps were the image's fault. `tcsh` is a hard requirement, not a convenience: /programs/sbgrid.shrc aborts with "requires the C shell" when /bin/csh is missing and sets up nothing at all, so the entire collection stays invisible. `bsdextrautils` provides column(1), which SBGrid's sbgrid-obsolete helper shells out to on every title lookup. Both are added to the verification loop. The third was the missing shell init, added here following the existing ext-shell pattern. It is guarded so it cannot break shells that have no collection: /programs is created empty in the image, so a non-diffuse workspace or a --no-mount run simply no-ops. The `|| true` is load-bearing. sbgrid.shrc runs commands that return non-zero benignly, so sourcing it under `set -e` kills the shell — verified on a live pod, and the reason my first attempt at this failed. Verified against the real collection on the current image with the PVC mounted read-only: an interactive shell resolves phenix.molprobity with no setup and scores 1CRN correctly, `bash -lc` works for non-interactive callers, pixi is unaffected, an absent mount is a clean no-op under both plain and `set -e` shells, and SBGRID_NO_AUTOINIT=1 opts out. Note this brings phenix and the rest of SBGrid; tortoize is not an SBGrid title and still comes from `pixi run -e analysis`. --- Dockerfile.astera | 13 ++++++++++++- docker/astera/install-sbgrid-shell-hooks.sh | 21 +++++++++++++++++++++ docker/astera/sbgrid-shell.sh | 20 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100755 docker/astera/install-sbgrid-shell-hooks.sh create mode 100644 docker/astera/sbgrid-shell.sh diff --git a/Dockerfile.astera b/Dockerfile.astera index c159a837..97999810 100644 --- a/Dockerfile.astera +++ b/Dockerfile.astera @@ -34,6 +34,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ RUN apt-get update && apt-get install -y --no-install-recommends \ bash \ + bsdextrautils \ ca-certificates \ curl \ dnsutils \ @@ -44,6 +45,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ nano \ ncdu \ rsync \ + tcsh \ tini \ tmux \ vim \ @@ -56,7 +58,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && install -m 0755 /app/run_experiments.sh /usr/local/bin/run_experiments.sh \ && install -m 0755 /app/run_all_models.sh /usr/local/bin/run_all_models.sh \ && for cmd in \ - bash curl dig emacs git htop nano ncdu ping rsync tini tmux vim wget zsh; do \ + bash column csh curl dig emacs git htop nano ncdu ping rsync tini tmux vim wget zsh; do \ command -v "${cmd}" >/dev/null 2>&1 || exit 1; \ done @@ -68,6 +70,15 @@ RUN install -m 0644 \ && EXT_VERSION="${EXT_VERSION}" bash /usr/local/share/sampleworks/astera/install-ext.sh \ && bash /usr/local/share/sampleworks/astera/install-ext-shell-hooks.sh +# SBGrid lives on the shared sbgrid-programs PVC, auto-mounted read-only at +# /programs by the actl catalog. /programs is created empty so the guarded init +# is a clean no-op when the PVC is not mounted. +RUN mkdir -p /programs \ + && install -m 0644 \ + /usr/local/share/sampleworks/astera/sbgrid-shell.sh \ + /etc/profile.d/sbgrid-shell.sh \ + && bash /usr/local/share/sampleworks/astera/install-sbgrid-shell-hooks.sh + WORKDIR /home/dev # ACTL workspace pods intentionally keep the inherited root runtime user: the diff --git a/docker/astera/install-sbgrid-shell-hooks.sh b/docker/astera/install-sbgrid-shell-hooks.sh new file mode 100755 index 00000000..8942d317 --- /dev/null +++ b/docker/astera/install-sbgrid-shell-hooks.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Wire the guarded SBGrid init into every shell actl might open, mirroring +# install-ext-shell-hooks.sh. Idempotent: re-running never double-appends. + +profile_script="/etc/profile.d/sbgrid-shell.sh" +profile_comment="# Sampleworks: put SBGrid on \$PATH when /programs is mounted." +profile_line="[ -r ${profile_script} ] && . ${profile_script}" + +touch /root/.bashrc /home/dev/.bashrc + +for profile_file in /etc/bash.bashrc /root/.bashrc /home/dev/.bashrc /etc/zsh/zshrc /etc/zsh/zprofile; do + if [ ! -e "${profile_file}" ]; then + continue + fi + if grep -Fqs "${profile_line}" "${profile_file}"; then + continue + fi + printf '\n%s\n%s\n' "${profile_comment}" "${profile_line}" >> "${profile_file}" +done diff --git a/docker/astera/sbgrid-shell.sh b/docker/astera/sbgrid-shell.sh new file mode 100644 index 00000000..33bdc94a --- /dev/null +++ b/docker/astera/sbgrid-shell.sh @@ -0,0 +1,20 @@ +# Put the SBGrid collection on $PATH when it is mounted. +# +# SBGrid is a site installation on the shared `sbgrid-programs` PVC, which the +# actl catalog auto-mounts read-only at /programs for every diffuse profile. It +# is not part of this image — the collection is well over a terabyte — so this +# script must be a no-op whenever the mount is absent (any non-diffuse +# workspace, or a run with --no-mount). Every step is guarded accordingly: +# /programs is an ordinary empty directory without the PVC. +# +# Set SBGRID_NO_AUTOINIT=1 before shell start to opt out. + +if [ -z "${SBGRID_NO_AUTOINIT:-}" ] && [ -z "${SBGRID_INITIALISED:-}" ] && [ -r /programs/sbgrid.shrc ]; then + SBGRID_INITIALISED=1 + export SBGRID_INITIALISED + # sbgrid.shrc runs commands that return non-zero benignly, so it aborts + # under `set -e` and would take the whole shell with it. It is also chatty + # on first run and writes into $HOME. Neither should be able to break shell + # startup, hence the redirect and the `|| true`. + . /programs/sbgrid.shrc >/dev/null 2>&1 || true +fi