feat: setup houdini image build
This commit is contained in:
203
houdini/README.md
Normal file
203
houdini/README.md
Normal file
@@ -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 <date>`) | 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. |
|
||||
Reference in New Issue
Block a user