commit 105bb36b2981fe5d824bcb79278495c8496ee8ab Author: Simon Lambin Date: Wed Sep 9 08:31:28 2026 +0200 feat: setup houdini image build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1577a16 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Downloaded proprietary installers/tarballs — never commit these. +*.tar.gz +*.tar.bz2 +*.iso diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e9a6cb --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# distrobox-images + +Dockerfiles pour les softs lourds (Houdini, ...) lancés via [distrobox](https://github.com/89luca89/distrobox), +buildés une fois et poussés sur un registry privé plutôt que rebuild à chaque +`distrobox create`. + +## Convention + +Un dossier par soft, autonome : + +``` +/ + Dockerfile # souvent multi-stage: base commune + variante amd / nvidia + build-and-push.sh # build + push vers le registry + -run # launcher installé dans l'image (entrypoint applicatif) + README.md # specifics: prérequis, licence, distrobox create, gotchas +``` + +Pas de base image partagée entre softs différents — chacun a ses propres +dépendances système, ça n'apporte rien de mutualiser au-delà du dossier. + +Deux variantes GPU par soft quand le rendu OpenGL/Vulkan compte (viewport, +préview) : +- `-amd` — Mesa embarqué dans l'image (radeonsi / RADV), marche aussi + pour Intel. +- `-nvidia` — rien embarqué; le driver NVIDIA de l'hôte est monté au + runtime par `distrobox --nvidia`. + +Si le rendu GPU n'a pas d'importance pour un soft donné, une seule image +suffit — ne pas dupliquer par principe. + +## Registry privé + +```bash +podman run -d --name registry --restart=always \ + -p 5000:5000 -v registry-data:/var/lib/registry \ + registry:2 +``` + +HTTP en clair, donc à déclarer en "insecure" côté moteur de conteneurs. + +**podman** — `/etc/containers/registries.conf.d/local.conf` : + +```toml +[[registry]] +location = "registry.lan:5000" +insecure = true +``` + +**docker** — `/etc/docker/daemon.json`, puis restart docker : + +```json +{ "insecure-registries": ["registry.lan:5000"] } +``` + +Au-delà d'un LAN de confiance, mettre TLS + auth devant plutôt que +`insecure`. + +## Licences / EULA + +Plusieurs de ces softs (Houdini compris) sont installés depuis un binaire +propriétaire téléchargé avec un compte perso, et l'EULA interdit en général +la redistribution. Le registry doit rester **privé** — jamais de push d'une +image contenant un de ces binaires vers un registry public. + +## Softs + +- [`houdini/`](houdini/README.md) — Houdini Apprentice diff --git a/houdini/Dockerfile b/houdini/Dockerfile new file mode 100644 index 0000000..d282a35 --- /dev/null +++ b/houdini/Dockerfile @@ -0,0 +1,52 @@ +# syntax=docker/dockerfile:1.7 +# +# Base + install command follow SideFX's own docker/Ubuntu/Dockerfile +# (shipped inside the Houdini tarball). Ubuntu 22.04 matters here, not just +# as a default: gccXX.X-tagged tarballs need a libstdc++ new enough to match, +# and Ubuntu's base image keeps libstdc++6 updated while RHEL/Rocky pin their +# system toolchain for the OS lifetime. +FROM docker.io/library/ubuntu:22.04 AS base + +ARG HOUDINI_TARBALL=houdini-linux.tar.gz +# Plain YYYY-MM-DD, no "SideFX-" prefix (that prefix is for the newer, +# unrelated houdini_installer launcher tool). Current EULA date: 2021-10-13, +# see https://www.sidefx.com/legal/license-agreement/ +ARG HOUDINI_EULA_DATE=2021-10-13 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + sudo procps \ + bc fontconfig wget libasound2 libgl1 libglu1 libglu1-mesa libglx0 \ + libegl1 libatomic1 libxkbfile1 libxcb-cursor0 \ + libice6 libnss3 libopengl0 libpci3 libsm6 libx11-6 libx11-xcb1 \ + libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 \ + libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 \ + libxcb-sync1 libxcb-util1 libxcb-xfixes0 libxcb-xinerama0 \ + libxcb-xkb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \ + libxext6 libxi6 libxkbcommon-x11-0 libxkbcommon0 libxrandr2 \ + libxrender1 libxss1 libxt6 libxtst6 && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /tmp/houdini +COPY ${HOUDINI_TARBALL} ./houdini.tar.gz + +# Flags match SideFX's own Dockerfile verbatim (space before the date, no +# '='). The installer creates /opt/hfs (e.g. /opt/hfs22.0), not +# a generic /opt/hfs — add our own stable symlink so houdini-run and the +# profile.d snippet don't need to know the version. +RUN tar xzf houdini.tar.gz --strip-components=1 && \ + ./houdini.install --auto-install --accept-EULA ${HOUDINI_EULA_DATE} && \ + ln -s "$(find /opt -maxdepth 1 -type d -name 'hfs[0-9]*' | sort -V | tail -1)" /opt/hfs && \ + rm -rf /tmp/houdini + +COPY houdini-run /usr/local/bin/houdini-run +RUN chmod +x /usr/local/bin/houdini-run && \ + printf 'if [ -d /opt/hfs ]; then _p="$PWD"; cd /opt/hfs && . ./houdini_setup >/dev/null 2>&1; cd "$_p"; fi\n' \ + > /etc/profile.d/houdini.sh + +FROM base AS amd +RUN apt-get update && apt-get install -y --no-install-recommends \ + libgl1-mesa-dri libglx-mesa0 mesa-vulkan-drivers && \ + rm -rf /var/lib/apt/lists/* + +FROM base AS nvidia +# GL/Vulkan/CUDA come from the host driver via `distrobox --nvidia`. diff --git a/houdini/README.md b/houdini/README.md new file mode 100644 index 0000000..1c674f0 --- /dev/null +++ b/houdini/README.md @@ -0,0 +1,203 @@ +# Houdini Apprentice in distrobox, from a private registry + +Two images built from one shared base: + +- `houdini-amd` — Houdini + Mesa (radeonsi / RADV) for AMD/Intel GPUs +- `houdini-nvidia` — Houdini; the NVIDIA driver is injected at runtime by `distrobox --nvidia` + +Files: `Dockerfile` (multi-stage), `houdini-run` (in-image launcher), `build-and-push.sh`. + +> **Single-image alternative (honest note):** because `distrobox --nvidia` +> mounts the host driver at runtime, a *single* image (base + Mesa) usually +> works for both vendors, with the GPU chosen at `distrobox create` time. Two +> images are cleaner and leaner per vendor, which is what this setup does — but +> if you'd rather maintain one, build only the `amd` target and use it with or +> without `--nvidia`. + +--- + +## 0. Prerequisites + +- `podman` (or `docker`) and `distrobox` on the host. +- A private registry — see the [repo-level README](../README.md) for setup. +- Your Houdini Linux tarball from your SideFX account, e.g. + `houdini-22.0.429-linux_x86_64_gcc14.2.tar.gz`, placed next to the `Dockerfile`. + The `gccXX.X` suffix means the runtime needs a `libstdc++` new enough for + that build; that's why the base image is Ubuntu 22.04, not Rocky/RHEL — + Ubuntu's base image keeps `libstdc++6` updated, while RHEL-family distros + pin their system toolchain for the OS's lifetime. +- A SideFX account (Apprentice is free) to activate the license on first launch. + +> This Dockerfile mirrors the one SideFX ships inside the tarball itself +> (`docker/Ubuntu/Dockerfile`) for the base image, package list, and install +> command — verified against the vendor's own recipe rather than guessed. Their +> package list is for headless `hython`/`sesinetd` use, though; running the +> actual `houdinifx` GUI needed 3 more runtime libs (`libegl1`, `libatomic1`, +> `libxkbfile1`), found by test-building and `ldd`-checking the binaries — +> already folded into the `Dockerfile`. + +> **EULA / redistribution:** Houdini binaries are baked into these images. Keep +> the registry **private**. Do not push Houdini images to a public registry. + +--- + +## 1. Build & push + +Edit the variables at the top of `build-and-push.sh` (registry, version, +tarball name, EULA date), then run it. It builds the shared base once, then the +two variants, and pushes all tags. The base layers are stored only once in the +registry. + +```bash +./build-and-push.sh +``` + +> **EULA date format:** plain `YYYY-MM-DD`, no `SideFX-` prefix (that prefix +> belongs to a different, unrelated tool — the newer credential-based +> `houdini_installer` launcher, not the `houdini.install` script used here). +> Current EULA date is `2021-10-13`; double check against +> https://www.sidefx.com/legal/license-agreement/ since SideFX can update it. + +--- + +## 2. Use it via distrobox + +Pick the image matching your GPU. The two `--additional-flags` bits below are +what make Apprentice licensing survive (see section 3): + +- `--hostname houdini-apprentice` — stable machine name for the node-lock +- a bind mount of the `licenses` file so the activation persists + +```bash +# One-time: create the persisted license file on the host. +mkdir -p ~/.houdini-apprentice +touch ~/.houdini-apprentice/licenses +``` + +**NVIDIA:** + +```bash +distrobox create \ + --name houdini \ + --image registry.lan:5000/houdini-nvidia:latest \ + --nvidia \ + --additional-flags "--hostname houdini-apprentice -v $HOME/.houdini-apprentice/licenses:/usr/lib/sesi/licenses" +``` + +**AMD / Intel** (drop `--nvidia`; distrobox exposes `/dev/dri` automatically): + +```bash +distrobox create \ + --name houdini \ + --image registry.lan:5000/houdini-amd:latest \ + --additional-flags "--hostname houdini-apprentice -v $HOME/.houdini-apprentice/licenses:/usr/lib/sesi/licenses" +``` + +Then: + +```bash +distrobox enter houdini +houdini-run # starts sesinetd, then launches Houdini FX +``` + +On **first launch** Houdini prompts to install the free Apprentice license: log +in with your SideFX account. + +To add a real app-menu entry (icon, no terminal window) instead of a plain +binary shortcut, export a `.desktop` file from inside the box — the icon path +must point at Houdini's own bundled icon (there's no separate `.desktop` file +shipped, so this one is written by hand): + +```bash +distrobox enter houdini +cat > /tmp/houdini.desktop << 'EOF' +[Desktop Entry] +Type=Application +Name=Houdini FX +Comment=Houdini Apprentice (distrobox) +Exec=houdini-run +Icon=/opt/hfs/houdini/cloudsubmit/houdini_icon.png +Terminal=false +Categories=Graphics;3DGraphics;Education; +StartupWMClass=houdinifx-bin +EOF +distrobox-export --app /tmp/houdini.desktop +``` + +`distrobox-export` copies the icon out to `~/.local/share/icons/` on the host +and writes `~/.local/share/applications/houdini-houdini.desktop`. Distrobox +also auto-creates a generic `houdini.desktop` ("Terminal entering Houdini") +for every box at creation time — set `NoDisplay=true` in that file (or delete +it) if you don't want both showing up in the app menu. + +--- + +## 3. Apprentice licensing — read this + +Apprentice is the fragile part, by design. Confirmed SideFX behaviour: + +- **No Login Licensing** for Apprentice — only node-locked (workstation) + licenses served by a **local** `sesinetd`, which must be running for Houdini + to start at all. +- The license is **node-locked to the machine hardware _and_ the machine name**. + Change the hostname and the license is invalidated — hence the fixed + `--hostname houdini-apprentice`. Always create the box with the same hostname. +- Apprentice licenses are **valid 30 days**, then you reinstall a fresh free set + (a quick re-login in the same dialog). +- On Linux the keys live in `/usr/lib/sesi/licenses`. The bind mount in section + 2 persists just that file into `~/.houdini-apprentice/`, so recreating or + re-pulling the container keeps the activation (within the 30 days, same host). + Confirmed by an actual Apprentice activation. Two gotchas that took a while + to track down, both now handled automatically by `houdini-run`: + - **File permissions.** `sesinetd` runs as `www-data`, not as your + distrobox user. A bind-mounted file created on the host with `touch` + belongs to your host user and isn't writable by `www-data`, so activation + fails with `Failed to open license file` in + `/var/log/sidefx/sesinetd.log` — surfaced in the GUI as an unrelated- + looking **"Success (curl error 0)"** error that just loops back to the + install-license prompt. `houdini-run` now `chmod 666`s the file before + starting `sesinetd` every time, so this self-heals. + - **Stuck self-signed cert.** If `sesinetd`'s self-signed TLS cert + generation is interrupted (it was, once, across our own container + restarts), it leaves 0-byte `auth.cert`/`auth.priv` files behind, and the + daemon then spins at ~100% CPU retrying against them forever instead of + regenerating — silently breaking activation with no obvious error. + `houdini-run` now deletes those files first if they're empty. + +Practical consequences: + +- **Same physical machine, stable hostname:** activate once; survives container + recreation and image updates until the 30-day expiry. +- **A different physical machine:** the hardware differs, so you re-activate + there (still free). The image is portable; the *license state* is per-machine. + +Inspect or manage licenses from inside the box with `houdini-run hkey` +(graphical) or `sesictrl` (CLI). + +> **"Container-enabled licenses" — why this doesn't apply here:** SideFX's own +> docker README warns that regular (non-floating) licenses need special +> "container enabled" entitlements to run `sesinetd` in Docker, and their own +> `docker-compose.yml` works around it with `network_mode: host`. That warning +> is about Docker's default *isolated* network namespace confusing the +> node-lock check. Distrobox shares the host's network namespace by default +> (no `--unshare-netns`), so the container sees the real host network identity +> — same situation as SideFX's own host-network workaround. Regular Apprentice +> licensing is expected to work unmodified. + +--- + +## 4. Known-fragile / to verify (honest status) + +| Area | Confidence | Note | +|---|---|---| +| Overall Dockerfile + distrobox shape | High | Standard distrobox GUI/GPU pattern. | +| Base image + install command (`--auto-install --accept-EULA `) | High | Copied from SideFX's own `docker/Ubuntu/Dockerfile`; test-built end to end against the real 22.0.429 tarball. | +| `/opt/hfs` symlink | High | The installer only creates a major.minor symlink (`/opt/hfs22.0`); the Dockerfile adds the generic `/opt/hfs` one itself — confirmed by test build. | +| EULA date value | Medium | `2021-10-13` as of writing; SideFX can update the EULA without notice, check the legal page. | +| Licensing works under distrobox's shared netns | High | Confirmed with a real Apprentice activation via the GUI, over the host's shared network namespace. | +| Runtime library list | High | Vendor's list plus 4 libs it was missing for the GUI (`libegl1`, `libatomic1`, `libxkbfile1`, `libxcb-cursor0`), all confirmed by `ldd`-checking `houdinifx-bin`/Qt plugins and by an actual successful launch. | +| `houdini-run` strict-mode compatibility | High | `houdini_setup` isn't written for `set -euo pipefail` (unset vars, `which java` expected to fail silently) — fixed by relaxing those flags just around the `source`; confirmed end to end. | +| `sesinetd` auto-start via the launcher | High | Confirmed under distrobox's real non-root user + sudo setup, including the license-file-permission and stuck-cert fixes described in section 3. | +| distrobox default hostname | Medium | We pin it explicitly rather than trust the default. | +| Actual GUI rendering (X11/Wayland via XWayland) | High | Confirmed: real AMD hardware acceleration (`glxinfo` reports direct rendering, AMD Radeon Vega renderer, not a software fallback), Houdini FX runs and renders normally through XWayland on a Hyprland session. First launch was noticeably slow; subsequent launches were fluid. | +| AMD OpenCL (sims) | Low | Not set up here; needs ROCm/rusticl. GL/Vulkan viewport is fine. | diff --git a/houdini/build-and-push.sh b/houdini/build-and-push.sh new file mode 100644 index 0000000..c44d1ee --- /dev/null +++ b/houdini/build-and-push.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Build both variants (shared base) and push. Heavy: run when ready. +set -euo pipefail + +REGISTRY="${REGISTRY:-registry.lan:5000}" +VERSION="${VERSION:-22.0.429}" +TARBALL="${TARBALL:-houdini-22.0.429-linux_x86_64_gcc14.2.tar.gz}" +# Date the EULA at https://www.sidefx.com/legal/license-agreement/ was last +# updated, format YYYY-MM-DD, no "SideFX-" prefix. +EULA_DATE="${EULA_DATE:-2021-10-13}" +ENGINE="${ENGINE:-podman}" + +ARGS=(-f Dockerfile --build-arg "HOUDINI_TARBALL=${TARBALL}" --build-arg "HOUDINI_EULA_DATE=${EULA_DATE}") + +for target in amd nvidia; do + "${ENGINE}" build "${ARGS[@]}" --target "${target}" \ + -t "${REGISTRY}/houdini-${target}:${VERSION}" \ + -t "${REGISTRY}/houdini-${target}:latest" . + "${ENGINE}" push "${REGISTRY}/houdini-${target}:${VERSION}" + "${ENGINE}" push "${REGISTRY}/houdini-${target}:latest" +done diff --git a/houdini/docker/README b/houdini/docker/README new file mode 100644 index 0000000..a248c8d --- /dev/null +++ b/houdini/docker/README @@ -0,0 +1,47 @@ +There are two versions of the Dockerfiles, one for Ubuntu Linux and one for +Windows. Note that the Ubuntu image size is much smaller. + + +Prerequisites: +1. You need Docker and Docker-compose installed if you're on Linux. +2. You need Docker Desktop installed if you're on a Windows or Mac host. +3. You need to modify "EULA_DATE" in the Dockerfile to specify the date for the + installer's `accept-EULA` argument. For example, if the EULA at + https://www.sidefx.com/legal/license-agreement/ was last updated on + April 10, 2020, you would set "EULA_DATE" in the Dockerfile to 2020-04-10. +4. To run sesinetd within docker you must have container enabled licenses. + Regular licenses will not work within containers. + +To create a Houdini Docker image: +1. Download a build of Houdini from www.sidefx.com for the container's platform. +4. Navigate to one of the "Ubuntu" or "Windows" folders. +3. Ensure you have set "EULA_DATE" in the Dockerfile. +4. Run `docker-compose build` + + +Some handy docker-compose commands: +1. `docker-compose run -d -p 1715:1715 sesinetd` will create a container + running the license server (sesinetd). +2. `docker-compose run hython` will start up hython in the interactive terminal + running the container. In the Linux container hython is in + /opt/hfs[VERSION]. + In the Windows container, hython is in + C:/Program Files/Side Effects Software/Houdini[VERSION]. +3. `docker-compose build` will build/rebuild the Houdini Docker images. + + +Some notes about Docker: +1. Docker requires that the Windows image version matches your host's Windows + version. The current Windows Houdini image is based on windows:1903; you + might need to update the Dockerfile accordingly. +2. The Mac and Windows versions do not support the "host" network, but host is + reachable on the special DNS name "host.docker.internal". If you have a + running sesinetd license server on host and would like to connect to it for + license checkout, you could switch point hserver to it. +3. All platforms (Mac/Linux/Windows) support the Linux version image. Only + Windows hosts support the Windows image. +4. Don't forget to toggle which daemon (Linux or Windows) the Docker CLI talks + to if you are using Windows Docker Desktop. You can switch it from the + Docker Desktop menu by selecting: + "Switch to Windows containers to use Windows containers" and + "Switch to Linux containers to use Linux containers" diff --git a/houdini/docker/Ubuntu/Dockerfile b/houdini/docker/Ubuntu/Dockerfile new file mode 100644 index 0000000..f628a36 --- /dev/null +++ b/houdini/docker/Ubuntu/Dockerfile @@ -0,0 +1,15 @@ +FROM ubuntu:22.04 + +RUN apt-get update && apt-get install -y --no-install-recommends bc fontconfig wget libasound2 libgl1 libglu1 libglu1-mesa libglx0 libice6 libnss3 libopengl0 libpci3 libsm6 libx11-6 libx11-xcb1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcb-sync1 libxcb-util1 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxi6 libxkbcommon-x11-0 libxkbcommon0 libxrandr2 libxrender1 libxss1 libxt6 libxtst6 && rm -rf /var/lib/apt/lists/* + +RUN mkdir houdiniInstaller +COPY houdini* /houdiniInstaller/ + +# Please update the following EULA_DATE to match the latest updated +# date of EULA in yyyy-mm-dd format. E.g. "2020-05-05" +# For Houdini 18.0 and previous version, EULA_DATE should be left empty +ARG EULA_DATE="" +RUN tar -xf /houdiniInstaller/houdini* -C /houdiniInstaller \ + && ./houdiniInstaller/houdini*/houdini.install --auto-install --accept-EULA ${EULA_DATE} \ + && rm -r /houdiniInstaller + diff --git a/houdini/docker/Ubuntu/docker-compose.yml b/houdini/docker/Ubuntu/docker-compose.yml new file mode 100644 index 0000000..03aeea9 --- /dev/null +++ b/houdini/docker/Ubuntu/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' + +services: + hython: + container_name: hython + hostname: hython + build: + context: . + dockerfile: Dockerfile + network_mode: host + image: houdini:22.0 diff --git a/houdini/docker/Windows/Dockerfile b/houdini/docker/Windows/Dockerfile new file mode 100644 index 0000000..349d06b --- /dev/null +++ b/houdini/docker/Windows/Dockerfile @@ -0,0 +1,19 @@ +FROM mcr.microsoft.com/windows:1903 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +COPY "houdini-*-win64-vc141.exe" "C:\\" + +# Please update the following EULA_DATE to match the latest updated +# date of EULA in yyyy-mm-dd format. E.g. "2020-05-05" +# For Houdini 18.0 and previous versions, EULA_DATE should be left empty +ARG EULA_DATE="" + +RUN Start-Process "C:\\houdini-*-win64-vc141.exe" '/S /AcceptEULA=${EULA_DATE} /DesktopIcon=No /FileAssociations=No /StartMenu=No' -Wait; + +RUN Remove-Item -Force "C:\\houdini-*-win64-vc141.exe" + +RUN $vtokens = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Side Effects Software').ActiveVersion.Split('.'); \ + $helppath = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Side Effects Software\Houdini').psobject.properties[$vtokens[0] + '.' + $vtokens[1] + '.0.' + $vtokens[2]].Value + 'houdini\help'; \ + Remove-Item -Force $helppath -Recurse; + diff --git a/houdini/docker/Windows/docker-compose.yml b/houdini/docker/Windows/docker-compose.yml new file mode 100644 index 0000000..6756024 --- /dev/null +++ b/houdini/docker/Windows/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' + +services: + hython: + container_name: hython + hostname: hython + build: + context: . + dockerfile: Dockerfile + image: houdini:22.0 + diff --git a/houdini/houdini-run b/houdini/houdini-run new file mode 100644 index 0000000..0308e6c --- /dev/null +++ b/houdini/houdini-run @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Start sesinetd (required for Apprentice), then launch Houdini. +set -euo pipefail + +HFS="${HFS:-/opt/hfs}" +# distrobox forwards the host shell's environment into the container. On a +# host that sets LD_LIBRARY_PATH itself (e.g. NixOS), that leaks in libs +# built for the host's glibc, which crash Houdini's binaries at load time. +# houdini_setup only ever *prepends* to LD_LIBRARY_PATH, so start it clean. +unset LD_LIBRARY_PATH +# houdini_setup isn't written for strict mode (unset vars, commands like +# `which java` that are expected to fail silently), so relax around the source. +_p="$PWD"; cd "${HFS}" +set +euo pipefail; source ./houdini_setup >/dev/null; set -euo pipefail +cd "${_p}" + +if ! pgrep -x sesinetd >/dev/null 2>&1; then + # sesinetd runs as www-data (dropped from root by sudo below); a license + # file bind-mounted from the host belongs to the host user instead and + # isn't writable by www-data, which makes activation silently fail + # ("Failed to open license file" in /var/log/sidefx/sesinetd.log, visible + # in the GUI as an unrelated-looking "Success (curl error 0)" error). + sudo chmod 666 /usr/lib/sesi/licenses 2>/dev/null || true + # If self-signed cert generation ever gets interrupted, it leaves 0-byte + # cert/key files behind; sesinetd then spins at ~100% CPU retrying + # against them forever instead of regenerating. Clear those out first. + for f in /usr/lib/sesi/ssl/auth.cert /usr/lib/sesi/ssl/auth.priv; do + [ -e "$f" ] && [ ! -s "$f" ] && sudo rm -f "$f" + done + sudo /usr/lib/sesi/sesinetd >/dev/null 2>&1 & + sleep 2 +fi + +exec "${@:-houdinifx}"