Files
unraid-podman/scripts/update-versions.sh
T
maggesandClaude Sonnet 5 e2fefcdf9c
Build Packages / Build .txz packages (push) Failing after 9s
Lint / ShellCheck (push) Failing after 43s
Lint / Validate .plg XML (push) Successful in 10s
Lint / EditorConfig (push) Failing after 6s
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>
2026-07-11 10:51:14 +00:00

152 lines
5.3 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# scripts/update-versions.sh
#
# Re-pins one (or all) upstream components in versions.env to their current
# latest release, recomputing the SHA256 checksum against the freshly
# downloaded source tarball. This is the ONLY supported way to change a
# version/checksum pair in versions.env — never hand-edit a checksum, since
# that defeats the entire point of pinning it (see the header comment in
# versions.env).
#
# Usage:
# scripts/update-versions.sh # check/update all components
# scripts/update-versions.sh podman crun # only these components
#
# This script only rewrites versions.env. It does not build anything, and it
# does not commit — review the diff (`git diff versions.env`) before
# committing, ideally by also running a build to confirm the new source
# still compiles (scripts/build-packages.sh <name>).
# =============================================================================
set -eu
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VERSIONS_FILE="$REPO_ROOT/versions.env"
# Maps our internal component name -> GitHub "owner/repo", for every
# component that actually has GitHub-tagged releases. passt is handled
# separately below (see versions.env for why).
declare -A GITHUB_REPO=(
[podman]="containers/podman"
[conmon]="containers/conmon"
[crun]="containers/crun"
[netavark]="containers/netavark"
[aardvark-dns]="containers/aardvark-dns"
[fuse-overlayfs]="containers/fuse-overlayfs"
)
# Maps our internal component name -> the *_VERSION variable prefix used in
# versions.env (uppercased, hyphens -> underscores).
env_prefix() {
echo "$1" | tr '[:lower:]-' '[:upper:]_'
}
update_github_component() {
local name="$1"
local repo="${GITHUB_REPO[$name]}"
local prefix
prefix=$(env_prefix "$name")
echo "==> [$name] checking latest release for $repo"
local api_response
api_response=$(curl -sL --max-time 15 "https://api.github.com/repos/$repo/releases/latest")
local tag
tag=$(echo "$api_response" | grep -m1 '"tag_name"' | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
if [ -z "$tag" ]; then
echo "!! [$name] could not determine latest tag (rate-limited or repo has no releases?)" >&2
return 1
fi
# Strip a leading "v" for the version we store, but keep it for the URL
# since GitHub tags for these projects are inconsistent about it (crun
# tags plain "1.28", others tag "v1.28").
local version="${tag#v}"
local url="https://github.com/$repo/archive/refs/tags/$tag.tar.gz"
echo "==> [$name] latest = $version, downloading to verify + checksum"
local tmpfile
tmpfile=$(mktemp)
curl -fL --max-time 120 -o "$tmpfile" "$url"
local sha256
sha256=$(sha256sum "$tmpfile" | awk '{print $1}')
rm -f "$tmpfile"
echo "==> [$name] sha256=$sha256"
apply_update "$prefix" "$version" "$url" "$sha256"
}
apply_update() {
local prefix="$1" version="$2" url="$3" sha256="$4"
# In-place rewrite of the three lines for this component. Using distinct
# sed expressions per variable (rather than one blanket substitution)
# keeps this safe even if variable order in versions.env changes.
sed -i \
-e "s|^${prefix}_VERSION=.*|${prefix}_VERSION=\"${version}\"|" \
-e "s|^${prefix}_SRC_SHA256=.*|${prefix}_SRC_SHA256=\"${sha256}\"|" \
"$VERSIONS_FILE"
# The *_SRC_URL line is templated against *_VERSION (e.g.
# ".../v${PODMAN_VERSION}.tar.gz") in most cases, so it doesn't need
# rewriting — only touch it if it isn't already parameterized.
if ! grep -q "^${prefix}_SRC_URL=.*\${${prefix}_VERSION}" "$VERSIONS_FILE" \
&& ! grep -q "^${prefix}_SRC_URL=.*\$${prefix}_VERSION" "$VERSIONS_FILE"; then
sed -i -e "s|^${prefix}_SRC_URL=.*|${prefix}_SRC_URL=\"${url}\"|" "$VERSIONS_FILE"
fi
echo "==> updated ${prefix}_VERSION / ${prefix}_SRC_SHA256 in $VERSIONS_FILE"
}
update_passt() {
echo "==> [passt] checking latest master commit at https://passt.top/passt/"
local atom
atom=$(curl -sL --max-time 15 "https://passt.top/passt/atom/?h=master")
local commit
commit=$(echo "$atom" | grep -m1 -oE '<id>[a-f0-9]{40}</id>' | sed -E 's/<\/?id>//g')
if [ -z "$commit" ]; then
echo "!! [passt] could not determine latest commit" >&2
return 1
fi
local url="https://passt.top/passt/snapshot/passt-${commit}.tar.gz"
echo "==> [passt] latest commit = $commit, downloading to verify + checksum"
local tmpfile
tmpfile=$(mktemp)
curl -fL --max-time 120 -o "$tmpfile" "$url"
local sha256
sha256=$(sha256sum "$tmpfile" | awk '{print $1}')
rm -f "$tmpfile"
sed -i \
-e "s|^PASST_COMMIT=.*|PASST_COMMIT=\"${commit}\"|" \
-e "s|^PASST_VERSION=.*|PASST_VERSION=\"git${commit:0:7}\"|" \
-e "s|^PASST_SRC_SHA256=.*|PASST_SRC_SHA256=\"${sha256}\"|" \
"$VERSIONS_FILE"
echo "==> updated PASST_COMMIT / PASST_VERSION / PASST_SRC_SHA256 in $VERSIONS_FILE"
}
requested=("$@")
if [ "${#requested[@]}" -eq 0 ]; then
requested=("${!GITHUB_REPO[@]}" passt)
fi
for name in "${requested[@]}"; do
if [ "$name" = "passt" ]; then
update_passt
elif [ -n "${GITHUB_REPO[$name]:-}" ]; then
update_github_component "$name"
else
echo "!! Unknown component: $name" >&2
exit 1
fi
done
echo
echo "==> Done. Review the diff before committing:"
echo " git -C \"$REPO_ROOT\" diff versions.env"