#!/bin/sh # Exit on error and when referencing an undefined variable. set -eu if ! command -v guix >/dev/null; then cat >&2 </dev/null; then cat >&2 <&2 <&2 <&2 } if ! command -v xdg-open >/dev/null; then cat >&2 <&2 fi done } open_files_for_guest & trap "kill $! 2>/dev/null || true; wait $!" EXIT for DIR in .container-data .container-data/var .container-data/local; do test -e "$DIR" || mkdir "$DIR" done rm -rf .container-data/.my.cnf touch .container-data/.my.cnf # Note: we pick openssl to have Guix set the SSL_CERT_FILE variable. GUIX_PACKAGES="\ coreutils grep gzip jupyter lighttpd mariadb nss-certs openssl php postgresql python python-bcrypt python-ipython-sql python-mysqlclient python-psycopg2 sed tar unzip wget" # Some distros still ship a Guix configured to use the Savannah git # URL. Cloning from that one is terriby slow nowadays and the project # now officially hosts code on Codeberg. CODEBERG_URL=https://codeberg.org/guix/guix.git # Some ordinary commit from 2025-10-16. COMMIT_KNOWN_GOOD=daea83629d7f6ccbc1c9ef6c334f5ba90d8f4bab GUIX=guix if ! guix show $GUIX_PACKAGES >/dev/null 2>&1; then # We're running an older Guix that misses one of the required # packages (probably the python-ipython-sql needed for the %%sql # magic in notebook cells). Let's have the older Guix compile its # newer friend. GUIX="guix time-machine --url=$CODEBERG_URL --commit=$COMMIT_KNOWN_GOOD --" fi $GUIX shell -C --network --emulate-fhs \ --share=.container-data/var=/var \ --share=.container-data/local="$HOME"/.local \ --share=.="$(pwd)" \ $GUIX_PACKAGES \ -- sh -c "$GUEST_SCRIPT" exit $? ################################################################################ # Container guest part of the script. # Exit on error and when referencing an undefined variable. set -eu # These programs look up their files relative to argv[0]. INITDB=$(realpath $(command -v initdb)) POSTGRES=$(realpath $(command -v postgres)) mkdir -p /var/lib/postgresql if ! [ -e /var/lib/postgresql/data ]; then $INITDB --pgdata /var/lib/postgresql/data-tmp mv /var/lib/postgresql/data-tmp /var/lib/postgresql/data fi mkdir -p /var/run/postgresql mkdir -p /var/log # What if there are some trolls in our LAN? We'd better only listen # on localhost. $POSTGRES -D /var/lib/postgresql/data -p 25432 -h 127.0.0.1 \ >/var/log/postgresql.log 2>&1 & PSQL='psql --port 25432 --quiet' # Wait for Postgres to start accepting connections. for _ in $(seq 20); do if $PSQL --command='' postgres 2>/dev/null; then break fi sleep 1 done # Let these fail if database or user already exists. for COMMAND in \ "CREATE USER demo_user PASSWORD 'demo_pwd'" \ 'CREATE DATABASE agh_it_northwind WITH OWNER demo_user'; do $PSQL --command="$COMMAND" postgres 2>/dev/null || true done cat > ~/.my.cnf </dev/null; then break fi sleep 1 done mkdir -p /var/www ALLOWED_SRC="$(printf %s "\ blob: http://localhost:127.0.0.1:28080 http://127.0.0.1:28080 'unsafe-eval' 'unsafe-inline' " | tr '\n' ' ')" cat > /tmp/lighttpd.conf < "$(command -v php-cgi)" ) accesslog.filename = "/var/log/lighttpd.log" setenv.add-response-header = ( "Content-Security-Policy" => "connect-src 'self'; default-src $ALLOWED_SRC;" ) EOF # lighttpd shall daemonize itself by default. lighttpd -f /tmp/lighttpd.conf ln -sf "$(realpath notebook-file-open-fifo)" /tmp/notebook-file-open-fifo mkdir -p /tmp/bin # This is our dummy variant of xdg-open ;) cat >/tmp/bin/xdg-open </tmp/notebook-file-open-fifo EOF chmod +x /tmp/bin/xdg-open printf 'ca_certificate = %s\n' "$SSL_CERT_FILE" >~/.wgetrc ln -s "$(realpath "$(pwd)")" /tmp/project-root export PATH=/tmp/bin:"$PATH" export BROWSER=/tmp/bin/xdg-open export PYTHONPATH=/tmp/project-root"${PYTHONPATH+:PYTHONPATH}" exec jupyter-notebook