# =====================================================================
# owuitools-octave - the code execution sandbox.
#
# This is the only container in the suite that runs code supplied by
# whoever is talking to the model. It therefore gets the strictest
# treatment in docker-compose.yml: network_mode "none", read-only root,
# non-root user, all capabilities dropped.
#
# It has NO network stack at all, so it cannot be given work over HTTP.
# Jobs arrive as files on a small tmpfs volume shared with the API
# container, and results go back the same way. See run.sh.
# =====================================================================
FROM debian:12-slim

# octave-* forge packages cover the four toolboxes people actually reach
# for in general engineering work. They are NOT auto-loaded: run.sh does
# the `pkg load` calls, because a script that says `pkg load signal`
# itself is valid Octave but is not valid MATLAB, and we do not want the
# model learning to write it.
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
      octave \
      octave-signal \
      octave-control \
      octave-statistics \
      octave-optim \
      gnuplot-nox \
      ghostscript \
      fonts-freefont-otf \
      fonts-dejavu-core \
 && rm -rf /var/lib/apt/lists/*

# Path shim, deliberately outside any working directory so it cannot show
# up as a user artefact or be shadowed by a user file. See shim/print.m.
# Octave never tells gnuplot to fill the legend background, so plot lines
# show through it. See the script for why this is a build-time edit.
COPY patch-legend-opaque.sh /tmp/patch-legend-opaque.sh
RUN sh /tmp/patch-legend-opaque.sh && rm /tmp/patch-legend-opaque.sh

COPY shim/ /opt/owuitools-shim/
# The shims implement MATLAB functions this Octave does not have, on a
# path that sits ahead of everything. Two things have to be true at build
# time and cannot be checked later: that Octave has not since acquired the
# function itself (in which case ours is deleted rather than allowed to
# shadow it), and that each one does what MATLAB documents. The script
# fails the build if a shim is wrong.
COPY check-shims.sh /tmp/check-shims.sh
RUN sh /tmp/check-shims.sh && rm /tmp/check-shims.sh

COPY run.sh /usr/local/bin/run.sh
RUN chmod 0555 /usr/local/bin/run.sh

# Unprivileged, and with a home it can actually write to (a read-only
# root filesystem means HOME must live on the tmpfs).
# Same uid as owuitools-api on purpose. The two containers share one small
# tmpfs for job files, and matching uids let that volume be mode 0700 -
# unreadable to anything else - instead of world-writable. It grants no
# privilege: they are separate containers with separate namespaces, and
# the uid only decides who can touch /jobs.
RUN useradd --uid 10001 --create-home --home-dir /home/runner --shell /usr/sbin/nologin runner
USER 10001:10001
ENV HOME=/tmp/octhome

ENTRYPOINT ["/usr/local/bin/run.sh"]
