diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index e3bb243..aef9fac 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -1,9 +1,10 @@ name: Build Packages -# Builds the seven Slackware .txz packages defined under packages/ -# (podman, conmon, crun, netavark, aardvark-dns, passt, fuse-overlayfs) -# inside a Slackware container, verifies + consolidates their checksums, and -# uploads the result as a workflow artifact. +# Builds the eleven Slackware .txz packages defined under packages/ +# (podman, conmon, crun, netavark, aardvark-dns, passt, fuse-overlayfs, +# catatonit, nftables, docker-compose, unraid-podman) inside a Slackware +# container, verifies + consolidates their checksums, and uploads the +# result as a workflow artifact. # # Intentionally does NOT commit any built binary back to the repository — # packages/**, *.txz, dist/ are all git-ignored (see .gitignore). Artifacts @@ -31,7 +32,7 @@ on: inputs: packages: description: > - Space-separated package names to build (default: all seven). + Space-separated package names to build (default: all eleven). Example: "podman conmon" required: false default: "" diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index df4692e..763e3b9 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -232,6 +232,8 @@ wählen können — mit deutlicher GUI-Warnung bzgl. Performance und Spin-up-Ver | `fuse-overlayfs` | Fallback-Storage-Driver | Für Rootless-Phase 2 vorbereitet, in Phase 1 optional | | `passt`/`pasta` | Rootless-Networking | Nachfolger von slirp4netns, Phase 2, aber Paket schon mitbauen (geringe Kosten) | | `catatonit` oder `tini` | Init-Prozess in Containern (optional, falls von Templates genutzt) | | +| `nftables` | Firewall-Backend für `netavark` | Pflicht seit netavark 2.0 (iptables-Treiber entfernt); Unraid liefert kein `nft` mit — als offizielles Slackware-Paket vendored, nicht selbst gebaut | +| `docker-compose` (CLI-Plugin) | External-Compose-Provider für `podman compose` | `podman compose` hat keine eigene Compose-Implementierung, sondern sucht ein `docker-compose`-Binary in festen CLI-Plugin-Pfaden; ohne dieses Paket schlägt jede Compose-Panel-Aktion auf einem frischen Unraid-Install fehl | ### 5.2 Build-Strategie diff --git a/packages/catatonit/README.md b/packages/catatonit/README.md new file mode 100644 index 0000000..e51152d --- /dev/null +++ b/packages/catatonit/README.md @@ -0,0 +1,20 @@ +# packages/catatonit/ + +Pinned version: see `CATATONIT_VERSION` in [versions.env](../../versions.env). + +Not built from source — `catatonit.SlackBuild` fetches and repackages +upstream's own prebuilt static x86_64 release binary. catatonit ships no +GitHub release asset for source-tarball builds that's meaningfully +different from just using the binary directly, and it's a small, purely +static ELF with zero runtime library dependencies (verified: `ldd` reports +"not a dynamic executable"). + +Required by `podman pod create` — without it, pod creation fails with +`finding catatonit binary: exec: catatonit: executable file not found in +$PATH`. Installed to `/usr/libexec/podman/catatonit`, alongside +netavark/aardvark-dns, which podman's `helper_binaries_dir` search already +covers. + +Found by live-testing this plugin end-to-end against a real Unraid +install, not from reading podman's docs — see +[docs/ARCHITECTURE.md, section 8](../../docs/ARCHITECTURE.md#8-netzwerke). diff --git a/packages/catatonit/catatonit.SlackBuild b/packages/catatonit/catatonit.SlackBuild new file mode 100755 index 0000000..f59f989 --- /dev/null +++ b/packages/catatonit/catatonit.SlackBuild @@ -0,0 +1,54 @@ +#!/bin/bash +# ============================================================================= +# packages/catatonit/catatonit.SlackBuild +# +# Packages the official prebuilt catatonit release binary — not built from +# source, see versions.env's CATATONIT_* block for why. catatonit is the +# init process podman runs inside every pod's infra container to reap +# zombies; without it, `podman pod create` fails outright with "finding +# catatonit binary: exec: catatonit: executable file not found in $PATH" +# (found by live-testing pod creation against a real Unraid install). +# +# Installed alongside netavark/aardvark-dns under /usr/libexec/podman/ — +# podman's helper_binaries_dir search path already covers that directory, +# matching where the other two helper binaries this project ships already +# live (see packages/netavark, packages/aardvark-dns). +# ============================================================================= + +set -eu + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +# shellcheck source=/dev/null +. "$REPO_ROOT/scripts/lib/slackbuild-common.sh" +# shellcheck source=/dev/null +. "$REPO_ROOT/versions.env" + +VERSION="$CATATONIT_VERSION" +ARCH="$PKG_ARCH" +BUILD="$PKG_BUILD" +TAG="$PKG_TAG" + +sb_init "catatonit" + +binary=$(sb_fetch_and_verify "$CATATONIT_SRC_URL" "$CATATONIT_SRC_SHA256" "catatonit-$VERSION") + +install -D -m 0755 "$binary" "$PKG/usr/libexec/podman/catatonit" + +# The release only ships the raw binary (+ checksum/signature files, no +# LICENSE/README asset) — write minimal doc metadata by hand instead of +# using sb_install_docs, which expects real files to copy from disk. +docdir="$PKG/usr/doc/catatonit-$VERSION" +mkdir -p "$docdir" +{ + echo "catatonit $VERSION" + echo "https://github.com/openSUSE/catatonit" + echo "Prebuilt static binary, packaged as-is by unraid-podman — see" + echo "versions.env for the pinned release URL and SHA256." +} > "$docdir/README" +{ + echo "Built by unraid-podman from upstream's prebuilt release binary." + echo "Package: catatonit $VERSION" + echo "Built: $(date -u +%Y-%m-%dT%H:%M:%SZ)" +} > "$docdir/unraid-podman.build-info" + +sb_make_package "$VERSION" "$ARCH" "$BUILD" "$TAG" diff --git a/packages/catatonit/slack-desc b/packages/catatonit/slack-desc new file mode 100644 index 0000000..c339ce1 --- /dev/null +++ b/packages/catatonit/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. +# Line up the first '|' above the ':' following the base package name, and +# the '|' on the right side marks the last column you can put a character in. +# You must make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':' except on otherwise blank lines. + + |-----handy-ruler------------------------------------------------| +catatonit: catatonit (init process for OCI pod infra containers) +catatonit: +catatonit: A minimal init that reaps zombie processes inside a pod's infra +catatonit: container. Required by `podman pod create` — packaged here from +catatonit: upstream's prebuilt static binary release for the unraid-podman +catatonit: plugin, not built from source (see versions.env). +catatonit: +catatonit: Homepage: https://github.com/openSUSE/catatonit +catatonit: +catatonit: +catatonit: diff --git a/packages/docker-compose/README.md b/packages/docker-compose/README.md new file mode 100644 index 0000000..99a7cc0 --- /dev/null +++ b/packages/docker-compose/README.md @@ -0,0 +1,31 @@ +# packages/docker-compose/ + +Pinned version: see `DOCKER_COMPOSE_VERSION` in [versions.env](../../versions.env). + +Not built from source — `docker-compose.SlackBuild` fetches and repackages +upstream's own prebuilt static x86_64 release binary (`docker/compose`, +the Go-based Compose v2 CLI plugin — a different project from the older +Python `podman-compose`). It's a small, purely static ELF with zero +runtime library dependencies (verified: `ldd` reports "not a dynamic +executable"), so there's nothing meaningful to gain from a from-source +build. + +`podman compose` (backing the WebUI's Compose panel, see +`webui/plugins/podman/ajax/compose.php`) has no compose implementation of +its own — it shells out to an "external compose provider" it discovers by +searching a fixed list of CLI-plugin directories for a binary named +`docker-compose`. Without one present, every Compose panel action fails +outright. Installed to `/usr/local/lib/docker/cli-plugins/docker-compose` +— one of podman's own search paths (extracted from the pinned podman +binary: `strings /usr/bin/podman | grep cli-plugins`), chosen specifically +under `/usr/local/` rather than `/usr/lib/docker/...` so this package +never collides with (or gets silently shadowed by) a genuine Docker +installation's own compose plugin on hosts that also run Unraid's +built-in Docker support. + +Found by live-testing the Compose panel end-to-end against a real Unraid +install: it happened to work only because that particular host already +had Docker's own `docker-compose` plugin installed from an unrelated, +pre-existing Docker setup — a clean Unraid install has no compose +provider at all without this package. See +[docs/ARCHITECTURE.md, section 5.1](../../docs/ARCHITECTURE.md#51-zu-paketierende-komponenten). diff --git a/packages/docker-compose/docker-compose.SlackBuild b/packages/docker-compose/docker-compose.SlackBuild new file mode 100755 index 0000000..a6a6eed --- /dev/null +++ b/packages/docker-compose/docker-compose.SlackBuild @@ -0,0 +1,60 @@ +#!/bin/bash +# ============================================================================= +# packages/docker-compose/docker-compose.SlackBuild +# +# Packages the official prebuilt docker/compose v2 release binary — not +# built from source, see versions.env's DOCKER_COMPOSE_* block for why. +# `podman compose` (backing webui/plugins/podman/ajax/compose.php) has no +# compose implementation of its own; it shells out to an "external compose +# provider" it discovers by searching a fixed list of CLI-plugin +# directories for a binary literally named `docker-compose` (paths +# extracted from the pinned podman binary itself: +# `strings /usr/bin/podman | grep cli-plugins`). Without one present, +# every Compose panel action fails outright (found by live-testing against +# a real Unraid install — it only worked there because that host happened +# to already have Docker's own compose plugin from an unrelated setup). +# +# Installed to /usr/local/lib/docker/cli-plugins/docker-compose — one of +# podman's search paths, deliberately the /usr/local/ one rather than +# /usr/lib/docker/cli-plugins so this package never collides with (or +# gets silently shadowed by) a genuine Docker installation's own compose +# plugin on hosts that also run Unraid's built-in Docker support. +# ============================================================================= + +set -eu + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +# shellcheck source=/dev/null +. "$REPO_ROOT/scripts/lib/slackbuild-common.sh" +# shellcheck source=/dev/null +. "$REPO_ROOT/versions.env" + +VERSION="$DOCKER_COMPOSE_VERSION" +ARCH="$PKG_ARCH" +BUILD="$PKG_BUILD" +TAG="$PKG_TAG" + +sb_init "docker-compose" + +binary=$(sb_fetch_and_verify "$DOCKER_COMPOSE_SRC_URL" "$DOCKER_COMPOSE_SRC_SHA256" "docker-compose-$VERSION") + +install -D -m 0755 "$binary" "$PKG/usr/local/lib/docker/cli-plugins/docker-compose" + +# The release only ships the raw binary (+ checksum/signature files, no +# LICENSE/README asset) — write minimal doc metadata by hand instead of +# using sb_install_docs, which expects real files to copy from disk. +docdir="$PKG/usr/doc/docker-compose-$VERSION" +mkdir -p "$docdir" +{ + echo "docker-compose (docker/compose v2 CLI plugin) $VERSION" + echo "https://github.com/docker/compose" + echo "Prebuilt static binary, packaged as-is by unraid-podman — see" + echo "versions.env for the pinned release URL and SHA256." +} > "$docdir/README" +{ + echo "Built by unraid-podman from upstream's prebuilt release binary." + echo "Package: docker-compose $VERSION" + echo "Built: $(date -u +%Y-%m-%dT%H:%M:%SZ)" +} > "$docdir/unraid-podman.build-info" + +sb_make_package "$VERSION" "$ARCH" "$BUILD" "$TAG" diff --git a/packages/docker-compose/slack-desc b/packages/docker-compose/slack-desc new file mode 100644 index 0000000..d75f979 --- /dev/null +++ b/packages/docker-compose/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. +# Line up the first '|' above the ':' following the base package name, and +# the '|' on the right side marks the last column you can put a character in. +# You must make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':' except on otherwise blank lines. + + |-----handy-ruler------------------------------------------------| +docker-compose: docker-compose (external Compose provider for podman compose) +docker-compose: +docker-compose: The docker/compose v2 CLI-plugin binary, installed as a +docker-compose: CLI-plugin so `podman compose` can find it. Required by the +docker-compose: WebUI's Compose panel; packaged from upstream's prebuilt +docker-compose: static binary release, not built from source. +docker-compose: +docker-compose: Homepage: https://github.com/docker/compose +docker-compose: +docker-compose: +docker-compose: diff --git a/packages/nftables/README.md b/packages/nftables/README.md new file mode 100644 index 0000000..0d37664 --- /dev/null +++ b/packages/nftables/README.md @@ -0,0 +1,19 @@ +# packages/nftables/ + +Pinned version: see `NFTABLES_VERSION` in [versions.env](../../versions.env). + +Not built from source, and no `slack-desc` here (unlike this project's +other packages) — `nftables.SlackBuild` fetches Slackware's own official +`nftables` package and re-hosts it as-is under this project's naming and +checksum convention. It's already a correctly-built Slackware package +(built by the Slackware team for exactly this OS/glibc/arch); the +slack-desc bundled inside it travels along unchanged. + +netavark >= 2.0 dropped its iptables firewall driver entirely — nftables +(via the `nft` binary this package provides) is the only firewall backend +that works on Unraid (firewalld needs systemd/dbus, which Unraid has +neither of). Unraid OS itself ships no `nft` binary. + +Found by live-testing this plugin end-to-end against a real Unraid +install, not from reading netavark's docs — see +[docs/ARCHITECTURE.md, section 8](../../docs/ARCHITECTURE.md#8-netzwerke). diff --git a/packages/nftables/nftables.SlackBuild b/packages/nftables/nftables.SlackBuild new file mode 100755 index 0000000..d5fd0d2 --- /dev/null +++ b/packages/nftables/nftables.SlackBuild @@ -0,0 +1,45 @@ +#!/bin/bash +# ============================================================================= +# packages/nftables/nftables.SlackBuild +# +# Vendors Slackware's own official nftables package as-is — not rebuilt +# from source, see versions.env's NFTABLES_* block for why. Unlike every +# other package here, there is no compile step: the fetched .txz is +# already a correctly-built Slackware package (built by the Slackware +# team for exactly this OS/glibc/arch), so it is re-hosted under this +# project's naming/checksum convention rather than unpacked and restaged +# through makepkg, which would add risk (differing compression/metadata) +# for no benefit. +# +# netavark >= 2.0 requires the nftables firewall driver (its iptables +# driver was removed entirely) but Unraid OS ships no `nft` binary — see +# config/containers.conf and docs/ARCHITECTURE.md section 8. Without this +# package, every `podman run`/`podman pod create` that touches networking +# fails with "netavark: Must provide a valid firewall backend" (found by +# live-testing against a real Unraid install). +# ============================================================================= + +set -eu + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +# shellcheck source=/dev/null +. "$REPO_ROOT/scripts/lib/slackbuild-common.sh" +# shellcheck source=/dev/null +. "$REPO_ROOT/versions.env" + +VERSION="$NFTABLES_VERSION" +ARCH="$PKG_ARCH" +BUILD="$PKG_BUILD" +TAG="$PKG_TAG" + +sb_init "nftables" + +official_pkg=$(sb_fetch_and_verify "$NFTABLES_SRC_URL" "$NFTABLES_SRC_SHA256" "nftables-$VERSION-official.txz") + +pkg_file="nftables-$VERSION-$ARCH-$BUILD$TAG.txz" +cp "$official_pkg" "$OUTPUT/$pkg_file" + +( cd "$OUTPUT" && sha256sum "$pkg_file" > "$pkg_file.sha256" ) +( cd "$OUTPUT" && md5sum "$pkg_file" > "$pkg_file.md5" ) + +echo "==> [nftables] vendored official Slackware package as $OUTPUT/$pkg_file" diff --git a/packages/unraid-podman/README.md b/packages/unraid-podman/README.md index e4647dd..8b563a0 100644 --- a/packages/unraid-podman/README.md +++ b/packages/unraid-podman/README.md @@ -1,7 +1,7 @@ # packages/unraid-podman Packaging recipe for the plugin's own scaffolding — **not** an upstream -component like the other seven package directories. See +component or vendored dependency like the other ten package directories. See `unraid-podman.SlackBuild`'s header comment for the full rationale. Bundles: diff --git a/packages/unraid-podman/unraid-podman.SlackBuild b/packages/unraid-podman/unraid-podman.SlackBuild index 792a1ad..9c6f289 100755 --- a/packages/unraid-podman/unraid-podman.SlackBuild +++ b/packages/unraid-podman/unraid-podman.SlackBuild @@ -2,15 +2,15 @@ # ============================================================================= # packages/unraid-podman/unraid-podman.SlackBuild # -# Unlike the other seven packages, this one does not compile anything from -# an external upstream source — it packages THIS repository's own plugin -# scaffolding (rc.podman, the sbin/ helper scripts, the official Unraid -# event/ hooks, and the default config templates) into a single .txz, -# exactly matching how real-world Unraid plugins bundle their own files -# (verified against the actual unassigned.devices.plg / package layout — -# see docs/ARCHITECTURE.md section 3.2 for the reference check that led to -# this design). plugin/podman.plg installs this alongside the seven -# compiled component packages, all via the same +# Unlike the other ten packages, this one does not fetch anything from +# an external upstream source at all — it packages THIS repository's own +# plugin scaffolding (rc.podman, the sbin/ helper scripts, the official +# Unraid event/ hooks, and the default config templates) into a single +# .txz, exactly matching how real-world Unraid plugins bundle their own +# files (verified against the actual unassigned.devices.plg / package +# layout — see docs/ARCHITECTURE.md section 3.2 for the reference check +# that led to this design). plugin/podman.plg installs this alongside the +# other ten packages, all via the same # `upgradepkg --install-new --reinstall` mechanism. # # Version: taken directly from plugin/podman.plg's own , diff --git a/plugin/podman.plg b/plugin/podman.plg index 6da140b..ca935bf 100644 --- a/plugin/podman.plg +++ b/plugin/podman.plg @@ -32,14 +32,16 @@ Structure of this file: 1. DOCTYPE entity block — plugin metadata + one version/file/md5 triple - per package (the seven upstream components plus this project's own - "unraid-podman" scaffolding package, see packages/unraid-podman/). + per package (the seven upstream components, catatonit/nftables/ + docker-compose as vendored runtime dependencies, plus this + project's own "unraid-podman" scaffolding package, see + packages/unraid-podman/). Entities are rewritten automatically by scripts/release.sh; never hand-edit a *_txz_version/_file/_md5 entity — see that script. 2. body: a. — kept in sync with CHANGELOG.md by hand for now. b. Pre-install architecture sanity check. - c. Eight package install/update blocks. + c. Eleven package install/update blocks. d. Postinstall — directory/config seeding, install-manifest generation, first start. e. — uninstall. @@ -65,8 +67,8 @@ + the eleven removepkg calls in the Method="remove" block don't have to + repeat "x86_64-1_unraidpodman" eleven times by hand. --> @@ -106,6 +108,27 @@ + + + + + + + + + + + + + + @@ -157,7 +180,9 @@ fi