2190dad2ad
Layering is a last resort per the Bazzite docs (slows every OS update, can block upgrades until removed); a sysext never enters an rpm-ostree transaction, survives OS updates, and installs/updates with no reboot — the mechanism Fedora Atomic ships via fedora-sysexts. - build-sysext.sh wraps the built host+web RPMs into punktfunk-<V-R>-x86-64.raw: /etc payload relocated to /usr/share/punktfunk/etc (a sysext carries only /usr), the punktfunk-sysext helper embedded, ID=fedora + VERSION_ID pinned (merges on Bazzite via ID_LIKE; REFUSED after a major rebase instead of running soname-broken binaries — both behaviors validated live on Bazzite 43). SELinux labels are baked in as squashfs pseudo-xattrs from matchpathcon: unlabeled files run fine for user units but system daemons are DENIED (udev couldn't read the gamepad rule under enforcing) — validated on-glass. Refuses duplicate input package names (a stale noarch punktfunk-web next to the x86_64 one built a chimera image with the dead node launcher once). - punktfunk-sysext.sh: install/update/status/remove against per-Fedora-major feeds (…/generic/punktfunk-sysext/f43[-canary]), SHA-256-verified, applies the udev/sysctl scriptlet work + /etc copies, prints the layering-migration hint. Live-validated on the .41 Bazzite box incl. service restart + web console. - publish-sysext-feed.sh + rpm.yml: build + publish the image per matrix leg (fedver 43/44), canary feeds pruned to 6, stable release assets attached. - update-punktfunk.sh warns when the sysext shadows a layered install. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
2.6 KiB
Bash
52 lines
2.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Publish a punktfunk sysext image into its feed on the Gitea generic package registry —
|
|
# called by .gitea/workflows/rpm.yml after the RPM publish. A feed is one fixed URL
|
|
# (…/punktfunk-sysext/<feed>/) holding versioned .raw files plus a SHA256SUMS manifest;
|
|
# punktfunk-sysext(8) on the boxes reads SHA256SUMS to find + verify the newest image
|
|
# (the layout is also exactly what systemd-sysupdate's url-file source expects, so a
|
|
# .transfer feed can be added later without re-publishing anything).
|
|
#
|
|
# Usage: TOKEN=… [KEEP=6] bash publish-sysext-feed.sh <feed> <image.raw>
|
|
# <feed> e.g. f43, f43-canary, f44 (Fedora major x channel)
|
|
# KEEP newest images to keep in the feed; 0/unset-for-stable = keep all
|
|
# Env: REGISTRY (git.unom.io), OWNER (unom), TOKEN (write:package PAT), CURL_USER (login name)
|
|
set -euo pipefail
|
|
|
|
FEED="${1:?usage: publish-sysext-feed.sh <feed> <image.raw>}"
|
|
RAW="${2:?usage: publish-sysext-feed.sh <feed> <image.raw>}"
|
|
[ -f "$RAW" ] || { echo "no such image: $RAW" >&2; exit 1; }
|
|
REGISTRY="${REGISTRY:-git.unom.io}"
|
|
OWNER="${OWNER:-unom}"
|
|
KEEP="${KEEP:-0}"
|
|
AUTH=(--user "${CURL_USER:-enricobuehler}:${TOKEN:?TOKEN (write:package PAT) required}")
|
|
BASE="https://$REGISTRY/api/packages/$OWNER/generic/punktfunk-sysext/$FEED"
|
|
|
|
FNAME="$(basename "$RAW")"
|
|
SHA="$(sha256sum "$RAW" | cut -d' ' -f1)"
|
|
|
|
# Merge into the existing manifest: drop any prior line for this filename, append ours.
|
|
SUMS="$(mktemp)"; trap 'rm -f "$SUMS"' EXIT
|
|
curl -fsS "${AUTH[@]}" "$BASE/SHA256SUMS" 2>/dev/null | grep -v " $FNAME\$" > "$SUMS" || true
|
|
printf '%s %s\n' "$SHA" "$FNAME" >> "$SUMS"
|
|
|
|
# Prune: keep only the newest $KEEP images (by version sort) in manifest + registry.
|
|
PRUNE=()
|
|
if [ "$KEEP" -gt 0 ]; then
|
|
mapfile -t PRUNE < <(awk '{print $2}' "$SUMS" | sort -V | head -n -"$KEEP")
|
|
for f in "${PRUNE[@]:-}"; do
|
|
[ -n "$f" ] && sed -i "\| $f\$|d" "$SUMS"
|
|
done
|
|
fi
|
|
|
|
# Upload order keeps consumers consistent: image first, then the manifest referencing it,
|
|
# then prune deletions (already absent from the manifest). Delete-before-put makes workflow
|
|
# re-runs idempotent (the registry 409s on duplicate filenames; first-publish 404s are fine).
|
|
curl -fsS -o /dev/null "${AUTH[@]}" -X DELETE "$BASE/$FNAME" || true
|
|
curl -fsS -o /dev/null "${AUTH[@]}" --upload-file "$RAW" "$BASE/$FNAME"
|
|
curl -fsS -o /dev/null "${AUTH[@]}" -X DELETE "$BASE/SHA256SUMS" || true
|
|
curl -fsS -o /dev/null "${AUTH[@]}" --upload-file "$SUMS" "$BASE/SHA256SUMS"
|
|
for f in "${PRUNE[@]:-}"; do
|
|
[ -n "$f" ] && { echo "pruning $f"; curl -fsS -o /dev/null "${AUTH[@]}" -X DELETE "$BASE/$f" || true; }
|
|
done
|
|
echo "published $FNAME -> $BASE ($(wc -l <"$SUMS") image(s) in the feed)"
|