Add reproducible build system, native Unraid plugin, and WebUI
- versions.env pins podman, conmon, crun, netavark, aardvark-dns, passt, and fuse-overlayfs to verified upstream source checksums; SlackBuild recipes, scripts/build-packages.sh, checksums.sh, release.sh, and update-versions.sh implement the reproducible pipeline; GitHub Actions workflows build in a Slackware container and publish releases without committing any binaries. - plugin/podman.plg installs/updates/removes all eight packages (the seven components plus the plugin's own unraid-podman scaffolding package) via upgradepkg, using the official Unraid array-event hook mechanism (event/disks_mounted, event/stopping) instead of editing /boot/config/go. rc.podman and the sbin/ helper scripts implement storage creation, config seeding/sync, preflight checks, autostart with per-container Safe-Mode, and package verify/update/rollback. - webui/plugins/podman implements the Dashboard, Containers, Pods, Images, Volumes, Networks, Logs, Terminal, Compose, and Settings panels against the approved mockup (webui/mockups/prototype.html), talking to podman system service exclusively via PodmanClient.php (libpod REST API over the Unix socket), with two documented exceptions: Terminal's one-shot exec model and Compose's use of the podman compose CLI, since libpod has no REST equivalent for either. - docs/ARCHITECTURE.md and docs/ROADMAP.md record the design decisions and honest current status (syntax-checked, unit- and integration-tested against fake sockets/servers; not yet run against a real Unraid/Podman/Slackware system). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+152
@@ -0,0 +1,152 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# scripts/ci/setup-slackware-buildenv.sh
|
||||
#
|
||||
# Prepares a Slackware container (see .github/workflows/build-packages.yml)
|
||||
# to build all seven packages under packages/. Idempotent and safe to re-run.
|
||||
#
|
||||
# Strategy: detect what's already present (a stock "full" Slackware 15.0
|
||||
# install already provides gcc/make/autotools/glib2/libcap/fuse3) and only
|
||||
# bootstrap what's genuinely missing (libseccomp, yajl — neither ships in
|
||||
# stock Slackware — plus the Go and Rust toolchains, which no Slackware
|
||||
# install ships). This makes the script tolerant of small differences
|
||||
# between Slackware base image variants instead of assuming one exact image
|
||||
# layout, while still failing loudly if something we cannot self-provision
|
||||
# (a C compiler, basically) is missing.
|
||||
#
|
||||
# Exits non-zero with a clear message if a required tool cannot be found or
|
||||
# provisioned — this script is meant to run early in CI so failures surface
|
||||
# immediately, not halfway through a 20-minute podman build.
|
||||
# =============================================================================
|
||||
|
||||
set -eu
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
. "$REPO_ROOT/scripts/ci/buildenv-versions.env"
|
||||
|
||||
WORK="/tmp/unraid-podman-buildenv"
|
||||
mkdir -p "$WORK"
|
||||
|
||||
require_binary() {
|
||||
local bin="$1" hint="$2"
|
||||
if ! command -v "$bin" > /dev/null 2>&1; then
|
||||
echo "!! Required tool '$bin' not found in the build image." >&2
|
||||
echo "!! $hint" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "==> found $bin: $(command -v "$bin")"
|
||||
}
|
||||
|
||||
require_pkgconfig() {
|
||||
local module="$1" hint="$2"
|
||||
if ! pkg-config --exists "$module" 2>/dev/null; then
|
||||
echo "!! Required library '$module' not found via pkg-config." >&2
|
||||
echo "!! $hint" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "==> found pkg-config module: $module ($(pkg-config --modversion "$module"))"
|
||||
return 0
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 1. Baseline toolchain expected to already be present in the base image.
|
||||
# -----------------------------------------------------------------------------
|
||||
require_binary gcc "Use a Slackware base image with the 'D' (development) series installed."
|
||||
require_binary make "Use a Slackware base image with the 'D' (development) series installed."
|
||||
require_binary autoconf "Needed by crun/fuse-overlayfs; part of Slackware's 'D' series."
|
||||
require_binary automake "Needed by crun/fuse-overlayfs; part of Slackware's 'D' series."
|
||||
require_binary libtool "Needed by crun/fuse-overlayfs; part of Slackware's 'D' series."
|
||||
require_binary pkg-config "Needed to locate C library dependencies."
|
||||
require_binary git "Needed to fetch crun's git submodules."
|
||||
require_binary curl "Needed to fetch pinned source tarballs."
|
||||
require_binary makepkg "Slackware's own packaging tool (pkgtools); should always be present."
|
||||
require_binary strip "Part of binutils; part of Slackware's 'D' series."
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 2. C library dependencies expected to already be present.
|
||||
# -----------------------------------------------------------------------------
|
||||
require_pkgconfig glib-2.0 "Install Slackware's glib2 package (needed by conmon)."
|
||||
require_pkgconfig libcap "Install Slackware's libcap package (needed by crun)." || true
|
||||
require_pkgconfig fuse3 "Install Slackware's fuse3 package (needed by fuse-overlayfs)." || true
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 3. libseccomp — not part of stock Slackware, build from source if missing.
|
||||
# -----------------------------------------------------------------------------
|
||||
if ! pkg-config --exists libseccomp 2>/dev/null; then
|
||||
echo "==> libseccomp not found, building v$LIBSECCOMP_VERSION from source"
|
||||
d="$WORK/libseccomp"
|
||||
mkdir -p "$d"
|
||||
curl -fL --retry 3 -o "$d/src.tar.gz" "$LIBSECCOMP_SRC_URL"
|
||||
actual=$(sha256sum "$d/src.tar.gz" | awk '{print $1}')
|
||||
[ "$actual" = "$LIBSECCOMP_SRC_SHA256" ] || {
|
||||
echo "!! libseccomp checksum mismatch (expected $LIBSECCOMP_SRC_SHA256, got $actual)" >&2
|
||||
exit 1
|
||||
}
|
||||
mkdir -p "$d/src" && tar -xf "$d/src.tar.gz" -C "$d/src" --strip-components=1
|
||||
( cd "$d/src" && ./autogen.sh && ./configure --prefix=/usr && make -j"$(nproc)" && make install )
|
||||
else
|
||||
echo "==> libseccomp already present, skipping bootstrap build"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 4. yajl — not part of stock Slackware, build from source if missing.
|
||||
# -----------------------------------------------------------------------------
|
||||
if ! pkg-config --exists yajl 2>/dev/null; then
|
||||
echo "==> yajl not found, building v$YAJL_VERSION from source"
|
||||
d="$WORK/yajl"
|
||||
mkdir -p "$d"
|
||||
curl -fL --retry 3 -o "$d/src.tar.gz" "$YAJL_SRC_URL"
|
||||
actual=$(sha256sum "$d/src.tar.gz" | awk '{print $1}')
|
||||
[ "$actual" = "$YAJL_SRC_SHA256" ] || {
|
||||
echo "!! yajl checksum mismatch (expected $YAJL_SRC_SHA256, got $actual)" >&2
|
||||
exit 1
|
||||
}
|
||||
mkdir -p "$d/src" && tar -xf "$d/src.tar.gz" -C "$d/src" --strip-components=1
|
||||
# yajl uses its own cmake-free ./configure wrapper script.
|
||||
( cd "$d/src" && ./configure -p /usr && make -C build install )
|
||||
ldconfig 2>/dev/null || true
|
||||
else
|
||||
echo "==> yajl already present, skipping bootstrap build"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 5. Go toolchain (podman) — official upstream tarball.
|
||||
# -----------------------------------------------------------------------------
|
||||
if ! command -v go > /dev/null 2>&1; then
|
||||
echo "==> Go not found, installing $GO_VERSION"
|
||||
curl -fL --retry 3 -o "$WORK/go.tar.gz" "$GO_SRC_URL"
|
||||
actual=$(sha256sum "$WORK/go.tar.gz" | awk '{print $1}')
|
||||
[ "$actual" = "$GO_SRC_SHA256" ] || {
|
||||
echo "!! Go toolchain checksum mismatch (expected $GO_SRC_SHA256, got $actual)" >&2
|
||||
exit 1
|
||||
}
|
||||
rm -rf /usr/local/go
|
||||
tar -C /usr/local -xf "$WORK/go.tar.gz"
|
||||
export PATH="/usr/local/go/bin:$PATH"
|
||||
# Persist PATH for subsequent steps in the same GitHub Actions job.
|
||||
if [ -n "${GITHUB_PATH:-}" ]; then
|
||||
echo "/usr/local/go/bin" >> "$GITHUB_PATH"
|
||||
fi
|
||||
else
|
||||
echo "==> Go already present: $(go version)"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 6. Rust toolchain (netavark, aardvark-dns) — via rustup.
|
||||
# -----------------------------------------------------------------------------
|
||||
if ! command -v cargo > /dev/null 2>&1; then
|
||||
echo "==> Rust/cargo not found, installing via rustup ($RUST_CHANNEL channel)"
|
||||
curl -fL --retry 3 --proto '=https' --tlsv1.2 -sSf "$RUSTUP_INIT_URL" \
|
||||
| sh -s -- -y --default-toolchain "$RUST_CHANNEL" --profile minimal
|
||||
# shellcheck source=/dev/null
|
||||
. "$HOME/.cargo/env"
|
||||
if [ -n "${GITHUB_PATH:-}" ]; then
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
fi
|
||||
else
|
||||
echo "==> Rust already present: $(cargo --version)"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "==> Build environment ready."
|
||||
Reference in New Issue
Block a user