Research: deb + rpm packaging toolchain for bundled-venv builds #34

Closed
opened 2026-09-02 18:31:19 +00:00 by xavierk · 1 comment
Owner

Parent map: Fenris deb + rpm release plan

Question

Which packaging toolchain builds both a .deb and an .rpm containing a bundled venv with textual>=0.40 vendored, from as close to a single source of truth as feasible? Compare dh-virtualenv, rpmbuild spec + vendored venv, nfpm, fpm. Answer per format: recommended route, shared assets (version, file lists), build prerequisites (host tools, containers), how the venv maps to the package file list, and upgrade/removal behavior each tool yields. Note maintenance status of each tool.

Parent map: [Fenris deb + rpm release plan](https://git.bongbetic.com/xavierk/Fenris/issues/33) ## Question Which packaging toolchain builds both a .deb and an .rpm containing a bundled venv with `textual>=0.40` vendored, from as close to a single source of truth as feasible? Compare dh-virtualenv, rpmbuild spec + vendored venv, nfpm, fpm. Answer per format: recommended route, shared assets (version, file lists), build prerequisites (host tools, containers), how the venv maps to the package file list, and upgrade/removal behavior each tool yields. Note maintenance status of each tool.
xavierk added this to the Wayfinder: Fenris deb + rpm release plan milestone 2026-09-02 18:31:19 +00:00
xavierk added the wayfinder:research label 2026-09-02 18:31:19 +00:00
xavierk added a new dependency 2026-09-02 18:34:06 +00:00
xavierk self-assigned this 2026-09-02 18:34:20 +00:00
Author
Owner

Research done — findings on branch research/toolchain (commit cca27d0), file docs/research/deb-rpm-toolchain.md (not pushed).

Answer: nfpm + staged --copies venv at /opt/fenris

Single source of truth: one nfpm.yaml (version, depends, file list, scripts) → nfpm pkg -p deb && nfpm pkg -p rpm. Note: -p accepts one format per invocation (verified in internal/cmd/package.go), so it's one config, two invocations — still the closest to single-source of the four.

Per tool:

  • nfpm — recommended. Contents list maps venv via type: tree, config via type: config|noreplace (=%config(noreplace) rpm / conffile deb), /var/lib/fenris store via type: ghost (deb: create in postinst), per-format deltas via overrides:. Prereq: one static Go binary. Upgrade/removal: native dpkg/rpm semantics. Active: v2.47.0 (2026-06-20), repo pushed 2026-08-31.
  • fpm — fallback. Same staging tree, -s dir -t deb|rpm, --deb-systemd, --config-files. But "config" = CLI flags per invocation → drift risk; source of truth is a shell script. Active: v1.18.0 (2026-08-26), docs thin.
  • dh-virtualenv — reject. debhelper add-on, deb-only, venv fully automatic at /opt/venvs/<pkg>. Cannot emit rpm at all → fails criterion. Dormant: last upstream release 1.2.2 = 2020-10-22, RTD docs 404, PyPI gone; Debian 12 still ships 1.2.2-1.3.
  • rpmbuild spec — reject. Best rpm-native behavior (%ghost, systemd macros) but hand-maintained spec = second file list; no deb side; needs rpm-build/mock.

Constraint check (measured): python3-textual = 0.1.13-1 on Debian 12, Ubuntu 22.04 AND 24.04 → far below the >=0.40 floor. Fedora 40+ actually ships 0.48.1/0.69/1.0/4.0 — meets floor but not our textual==8.2.8 pin. Vendoring inside the package stays correct for all targets.

Doc includes a sketch Makefile stage target + packaging/nfpm.yaml covering units, polkit action, /usr/libexec/fenris helpers, /etc/fenris conffile, /var/lib/fenris ghost, postinst (fenris group, 2750 store dir, daemon-reload; units shipped dormant per current design).

Full per-tool detail, comparison matrix, and source links in the file.

Refs #34 (closes). Parent plan: #33.

Research done — findings on branch **`research/toolchain`** (commit `cca27d0`), file **`docs/research/deb-rpm-toolchain.md`** (not pushed). ## Answer: nfpm + staged `--copies` venv at `/opt/fenris` **Single source of truth:** one `nfpm.yaml` (version, depends, file list, scripts) → `nfpm pkg -p deb && nfpm pkg -p rpm`. Note: `-p` accepts one format per invocation (verified in `internal/cmd/package.go`), so it's one config, two invocations — still the closest to single-source of the four. Per tool: - **nfpm — recommended.** Contents list maps venv via `type: tree`, config via `type: config|noreplace` (=%config(noreplace) rpm / conffile deb), `/var/lib/fenris` store via `type: ghost` (deb: create in postinst), per-format deltas via `overrides:`. Prereq: one static Go binary. Upgrade/removal: native dpkg/rpm semantics. **Active**: v2.47.0 (2026-06-20), repo pushed 2026-08-31. - **fpm — fallback.** Same staging tree, `-s dir -t deb|rpm`, `--deb-systemd`, `--config-files`. But "config" = CLI flags per invocation → drift risk; source of truth is a shell script. **Active**: v1.18.0 (2026-08-26), docs thin. - **dh-virtualenv — reject.** debhelper add-on, deb-only, venv fully automatic at `/opt/venvs/<pkg>`. Cannot emit rpm at all → fails criterion. **Dormant**: last upstream release 1.2.2 = 2020-10-22, RTD docs 404, PyPI gone; Debian 12 still ships 1.2.2-1.3. - **rpmbuild spec — reject.** Best rpm-native behavior (%ghost, systemd macros) but hand-maintained spec = second file list; no deb side; needs rpm-build/mock. Constraint check (measured): python3-textual = **0.1.13-1** on Debian 12, Ubuntu 22.04 AND 24.04 → far below the >=0.40 floor. Fedora 40+ actually ships 0.48.1/0.69/1.0/4.0 — meets floor but not our `textual==8.2.8` pin. Vendoring inside the package stays correct for all targets. Doc includes a sketch Makefile `stage` target + `packaging/nfpm.yaml` covering units, polkit action, `/usr/libexec/fenris` helpers, `/etc/fenris` conffile, `/var/lib/fenris` ghost, postinst (fenris group, 2750 store dir, daemon-reload; units shipped dormant per current design). Full per-tool detail, comparison matrix, and source links in the file. Refs #34 (closes). Parent plan: #33.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: xavierk/Fenris#34