Fix Void package acceptance gaps

This commit is contained in:
xavierk
2026-09-15 19:43:00 +05:30
parent 95c75badd5
commit a3e6cc3b3c
10 changed files with 114 additions and 38 deletions
+17 -4
View File
@@ -95,6 +95,7 @@ install: check-python check-smartctl dist/fenris-*.whl
@echo "=== Installing runit service files (dormant — not enabled) ===" @echo "=== Installing runit service files (dormant — not enabled) ==="
@sudo install -d -m 0755 /etc/sv/fenris-collect/log @sudo install -d -m 0755 /etc/sv/fenris-collect/log
@sudo install -d -o root -g fenris -m 2770 /var/log/fenris-collect
@sudo install -m 0755 units/runit/fenris-collect/run /etc/sv/fenris-collect/run @sudo install -m 0755 units/runit/fenris-collect/run /etc/sv/fenris-collect/run
@sudo install -m 0755 units/runit/fenris-collect/log/run /etc/sv/fenris-collect/log/run @sudo install -m 0755 units/runit/fenris-collect/log/run /etc/sv/fenris-collect/log/run
@sudo touch /etc/sv/fenris-collect/down @sudo touch /etc/sv/fenris-collect/down
@@ -111,10 +112,14 @@ install: check-python check-smartctl dist/fenris-*.whl
@echo "$(LIBEXEC_DIR)/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(LIBEXEC_DIR)/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(UNIT_DIR)/fenris-collect.timer" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(UNIT_DIR)/fenris-collect.timer" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(UNIT_DIR)/fenris-collect.service" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(UNIT_DIR)/fenris-collect.service" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/run" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/log/run" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/down" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(POLKIT_DIR)/com.bongbetic.fenris.monitor.policy" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(POLKIT_DIR)/com.bongbetic.fenris.monitor.policy" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(VENV_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(VENV_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(DATA_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(DATA_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(CONF_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(CONF_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/var/log/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(MANIFEST)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(MANIFEST)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "=== Install complete ===" @echo "=== Install complete ==="
@@ -150,6 +155,8 @@ upgrade: dist/fenris-*.whl
@sudo install -m 0644 units/fenris-collect.timer $(UNIT_DIR)/ @sudo install -m 0644 units/fenris-collect.timer $(UNIT_DIR)/
@sudo install -m 0644 units/fenris-collect.service $(UNIT_DIR)/ @sudo install -m 0644 units/fenris-collect.service $(UNIT_DIR)/
@sudo install -d -m 0755 /etc/sv/fenris-collect/log @sudo install -d -m 0755 /etc/sv/fenris-collect/log
@sudo groupadd -f fenris
@sudo install -d -o root -g fenris -m 2770 /var/log/fenris-collect
@sudo install -m 0755 units/runit/fenris-collect/run /etc/sv/fenris-collect/run @sudo install -m 0755 units/runit/fenris-collect/run /etc/sv/fenris-collect/run
@sudo install -m 0755 units/runit/fenris-collect/log/run /etc/sv/fenris-collect/log/run @sudo install -m 0755 units/runit/fenris-collect/log/run /etc/sv/fenris-collect/log/run
@sudo install -m 0644 polkit/com.bongbetic.fenris.monitor.policy $(POLKIT_DIR)/ @sudo install -m 0644 polkit/com.bongbetic.fenris.monitor.policy $(POLKIT_DIR)/
@@ -167,10 +174,14 @@ upgrade: dist/fenris-*.whl
@echo "$(LIBEXEC_DIR)/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(LIBEXEC_DIR)/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(UNIT_DIR)/fenris-collect.timer" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(UNIT_DIR)/fenris-collect.timer" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(UNIT_DIR)/fenris-collect.service" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(UNIT_DIR)/fenris-collect.service" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/run" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/log/run" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/etc/sv/fenris-collect/down" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(POLKIT_DIR)/com.bongbetic.fenris.monitor.policy" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(POLKIT_DIR)/com.bongbetic.fenris.monitor.policy" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(VENV_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(VENV_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(DATA_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(DATA_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(CONF_DIR)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(CONF_DIR)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "/var/log/fenris-collect" | sudo tee -a $(MANIFEST) > /dev/null
@echo "$(MANIFEST)" | sudo tee -a $(MANIFEST) > /dev/null @echo "$(MANIFEST)" | sudo tee -a $(MANIFEST) > /dev/null
@echo "=== Restarting timer only if contents changed and active (IN-5) ===" @echo "=== Restarting timer only if contents changed and active (IN-5) ==="
@@ -277,28 +288,30 @@ package: package-deb package-rpm
# XBPS signing key (separate from SSH authentication key) # XBPS signing key (separate from SSH authentication key)
XBPS_SIGNING_KEY ?= $(HOME)/.ssh/id_xbps XBPS_SIGNING_KEY ?= $(HOME)/.ssh/id_xbps
XBPS_REVISION ?= 1
package-xbps: stage package-xbps: stage
@echo "=== Building XBPS package ===" @echo "=== Building XBPS package ==="
cp packaging/xbps/install.sh build/stage/INSTALL cp packaging/xbps/install.sh build/stage/INSTALL
cp packaging/xbps/remove.sh build/stage/REMOVE cp packaging/xbps/remove.sh build/stage/REMOVE
install -D -m 0644 packaging/fenris.conf build/stage/etc/fenris/fenris.conf
chmod 755 build/stage/INSTALL build/stage/REMOVE chmod 755 build/stage/INSTALL build/stage/REMOVE
xbps-create -A x86_64 \ xbps-create -A x86_64 \
-n fenris-$(FENRIS_VERSION)_1 \ -n fenris-$(FENRIS_VERSION)_$(XBPS_REVISION) \
-s "Fenris NVMe wear monitor" \ -s "Fenris NVMe wear monitor" \
-S "NVMe wear monitor with persistent TUI" \ -S "NVMe wear monitor with persistent TUI" \
-m "Fenris Packaging <packaging@bongbetic.com>" \ -m "Fenris Packaging <packaging@bongbetic.com>" \
-H "https://git.bongbetic.com/xavierk/Fenris" \ -H "https://git.bongbetic.com/xavierk/Fenris" \
-l "MIT" \ -l "MIT" \
-D "python3>=3.10 smartmontools" \ -D "python3>=3.10 smartmontools>=0" \
-F "/etc/fenris/fenris.conf" \ -F "/etc/fenris/fenris.conf" \
build/stage build/stage
@echo "=== XBPS package built: fenris-$(FENRIS_VERSION)_1.x86_64.xbps ===" @echo "=== XBPS package built: fenris-$(FENRIS_VERSION)_$(XBPS_REVISION).x86_64.xbps ==="
sign-xbps: package-xbps sign-xbps: package-xbps
@echo "=== Signing XBPS package ===" @echo "=== Signing XBPS package ==="
xbps-rindex --sign-pkg --privkey $(XBPS_SIGNING_KEY) \ xbps-rindex --sign-pkg --privkey $(XBPS_SIGNING_KEY) \
fenris-$(FENRIS_VERSION)_1.x86_64.xbps fenris-$(FENRIS_VERSION)_$(XBPS_REVISION).x86_64.xbps
@echo "=== XBPS package signed ===" @echo "=== XBPS package signed ==="
xbps-publish: xbps-publish:
+12 -5
View File
@@ -68,10 +68,9 @@ TLS).
### Void Linux (XBPS) ### Void Linux (XBPS)
Void x86_64 with glibc and runit is the native target. Its XBPS channel is Void x86_64 with glibc and runit is the native target. Its signed XBPS channel
withheld until the host-acceptance gate passes; do not install proof artifacts is available from the permanent repository below. Add it, refresh its
from it. Once a Fenris Release lists XBPS as available, add the permanent metadata, and install the released package:
signed repository, refresh its metadata, and install the package:
```bash ```bash
sudo install -d -m 0755 /etc/xbps.d sudo install -d -m 0755 /etc/xbps.d
@@ -83,7 +82,7 @@ sudo xbps-install -S fenris
XBPS requires remote repositories to be signed. On the first refresh it XBPS requires remote repositories to be signed. On the first refresh it
displays the repository signing key embedded in the signed metadata; accept it displays the repository signing key embedded in the signed metadata; accept it
only when its RSA SHA256 fingerprint is only when its RSA SHA256 fingerprint is
`SHA256:kC1+z5Z9OtW5qcoXcV7sxr7m1wEvxbTUgRxd9Yib/Qk`. The public key is also `SHA256:AvPMRlKMikPg75u0iKr8AUkxlfU/Ad4k/S4o2M9W4/w`. The public key is also
available at available at
`https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/keys/fenris-xbps-signing.pub`. `https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/keys/fenris-xbps-signing.pub`.
For later updates, always refresh first so XBPS fetches the current index: For later updates, always refresh first so XBPS fetches the current index:
@@ -96,6 +95,14 @@ The runit service remains dormant after installation. `fenris monitor resume`
creates `/var/service/fenris-collect`; pause removes that link and records a creates `/var/service/fenris-collect`; pause removes that link and records a
deliberate disable in the observation history. deliberate disable in the observation history.
Fenris keeps the observation store root-written and readable by the `fenris`
group. Add each TUI user to that group, then start a new login session before
running Fenris:
```bash
sudo usermod -aG fenris "$USER"
```
### Package signature verification ### Package signature verification
The RPM payload is signed with the Fenris packaging key (RSA 3072). The RPM payload is signed with the Fenris packaging key (RSA 3072).
+4 -4
View File
@@ -1,14 +1,14 @@
# 8. Native Void Linux support and XBPS delivery # 8. Native Void Linux support and XBPS delivery
Status: Accepted scope and hosting direction; implementation and acceptance proof pending. Status: Accepted — implementation and host acceptance completed; evidence is recorded in [issue #87](https://git.bongbetic.com/xavierk/Fenris/issues/87).
Fenris will support Void Linux natively with runit and full application feature parity, while retaining its existing Debian/RPM and systemd support. This extends the platform boundary in [ADR 0003](0003-service-lifecycle-and-sanctioned-toggle.md) and the delivery scope in [ADR 0007](0007-package-delivery-amends-0004.md): requiring Void users to replace their init system would not meet the native-support goal. Fenris will support Void Linux natively with runit and full application feature parity, while retaining its existing Debian/RPM and systemd support. This extends the platform boundary in [ADR 0003](0003-service-lifecycle-and-sanctioned-toggle.md) and the delivery scope in [ADR 0007](0007-package-delivery-amends-0004.md): requiring Void users to replace their init system would not meet the native-support goal.
Delivery will include a Fenris-maintained, signed XBPS repository that users configure once for subsequent installation and updates through XBPS, plus versioned release artifacts and notes on Gitea. All downloads must be served directly by Gitea itself; a separate static HTTP repository, even alongside Gitea, does not satisfy this requirement. Delivery will include a Fenris-maintained, signed XBPS repository that users configure once for subsequent installation and updates through XBPS, plus versioned release artifacts and notes on Gitea. All downloads must be served directly by Gitea itself; a separate static HTTP repository, even alongside Gitea, does not satisfy this requirement.
Use a dedicated public Gitea repository, provisionally `xavierk/Fenris-xbps`, with a permanent `stable` branch. Its raw-file URL serves the XBPS index, versioned packages, and package signatures as ordinary Git blobs without LFS. Keeping binaries in a separate repository avoids increasing application source-clone size. This accepts growth in distribution-repository Git history in exchange for publishing index and artifacts together through one branch update, without the generic registry's delete-and-upload index replacement gap. The proposed repository has not yet been created. Use the dedicated public Gitea repository `xavierk/Fenris-xbps` with its permanent `stable` branch. Its raw-file URL serves the XBPS index, versioned packages, and package signatures as ordinary Git blobs without LFS. Keeping binaries in a separate repository avoids increasing application source-clone size. This accepts growth in distribution-repository Git history in exchange for publishing index and artifacts together through one branch update, without the generic registry's delete-and-upload index replacement gap.
Serialize publication, commit the signed index and its new artifacts together, and retain older versioned artifacts in the current tree so clients with cached older indexes can still download them. Native XBPS installation and update tests against the actual endpoint are required before release validation. Verify binary delivery limits and index freshness: the inspected Gitea raw endpoint advertised six-hour HTTP caching, so immediate update visibility has not been established. Serialize publication, commit the signed index and its new artifacts together, and retain older versioned artifacts in the current tree so clients with cached older indexes can still download them. Native XBPS installation and update tests against the actual endpoint are required before release validation. The first release acceptance recorded in issue #87 verified direct artifact delivery, signed metadata, retained packages, and immediate discovery after an explicit refresh. The Gitea raw endpoint advertises six-hour HTTP caching; users should explicitly refresh with `xbps-install -S` when looking for updates.
Immediate availability is required: after successful XBPS publication, an explicit repository refresh against the permanent URL must discover the newly published version without a cache-expiry wait or a URL change. This does not promise automatic installation on client machines. Acceptance must exercise a client that fetched the previous index before publication and verify that refresh retrieves the new index and its signed package afterward. Resolve and document actual client and intermediary cache behavior; if the selected Gitea route cannot meet this requirement, hold XBPS publication and revisit its delivery mechanics rather than silently accepting delayed availability. Immediate availability is required: after successful XBPS publication, an explicit repository refresh against the permanent URL must discover the newly published version without a cache-expiry wait or a URL change. This does not promise automatic installation on client machines. Acceptance must exercise a client that fetched the previous index before publication and verify that refresh retrieves the new index and its signed package afterward. Resolve and document actual client and intermediary cache behavior; if the selected Gitea route cannot meet this requirement, hold XBPS publication and revisit its delivery mechanics rather than silently accepting delayed availability.
@@ -18,4 +18,4 @@ The first supported Void target is x86_64 with glibc, matching the inspected dev
Package formats have independent publication gates: publish each validated format, and hold only formats that have not passed release validation. A failure or pending validation in XBPS must not prevent a validated Debian or RPM package from shipping, and vice versa. Release notes must identify available formats and those still withheld; publication must not imply validation of a missing format. Package formats have independent publication gates: publish each validated format, and hold only formats that have not passed release validation. A failure or pending validation in XBPS must not prevent a validated Debian or RPM package from shipping, and vice versa. Release notes must identify available formats and those still withheld; publication must not imply validation of a missing format.
After successful native acceptance testing, leave the released XBPS package installed on this machine and monitoring the selected NVMe drive. Preserve the observation history collected during testing. Coordinate the reboot test with the user so it can occur at a suitable interruption point. After successful native acceptance testing, leave the released XBPS package installed on this machine and monitoring the selected NVMe drive. Preserve the observation history collected during testing. Coordinate the reboot test with the user so it can occur at a suitable interruption point. Issue #87 records that this final state, including reboot persistence, was achieved for the first supported release.
+1 -1
View File
@@ -63,4 +63,4 @@ Musl, other architectures, additional init systems, official Void repository inc
## Further Notes ## Further Notes
The design decisions are recorded in ADR 0008. Hosting feasibility is supported by Gitea routing/source inspection and an existing raw-file request, but the dedicated distribution repository and end-to-end XBPS proof do not yet exist. Current host inspection found Void x86_64/glibc with runit, polkit support and an NVMe controller; Fenris and smartmontools were absent. Verify these facts again before host changes. The design decisions are recorded in ADR 0008. The dedicated distribution repository and end-to-end XBPS proof are complete; the host acceptance record is [issue #87](https://git.bongbetic.com/xavierk/Fenris/issues/87). The accepted target is Void x86_64/glibc with runit, with the released package installed and monitoring the selected NVMe drive after the coordinated reboot and lifecycle checks.
+1 -2
View File
@@ -69,8 +69,7 @@ print(f'Fenris migration: {n} step(s) applied') if n else None
touch /etc/sv/fenris-collect/down touch /etc/sv/fenris-collect/down
fi fi
# Ensure log directory exists # Ensure log directory exists
mkdir -p /var/log/fenris-collect install -d -o root -g fenris -m 2770 /var/log/fenris-collect 2>/dev/null || true
chown fenris:fenris /var/log/fenris-collect 2>/dev/null || true
fi fi
;; ;;
abort-upgrade|abort-install|disappear) abort-upgrade|abort-install|disappear)
+5 -2
View File
@@ -30,8 +30,7 @@ if [ "$1" -eq 1 ]; then
touch /etc/sv/fenris-collect/down touch /etc/sv/fenris-collect/down
fi fi
# Ensure log directory exists # Ensure log directory exists
mkdir -p /var/log/fenris-collect install -d -o root -g fenris -m 2770 /var/log/fenris-collect 2>/dev/null || true
chown fenris:fenris /var/log/fenris-collect 2>/dev/null || true
fi fi
elif [ "$1" -ge 2 ]; then elif [ "$1" -ge 2 ]; then
# Upgrade — snapshot, migration, init-system-aware reload # Upgrade — snapshot, migration, init-system-aware reload
@@ -67,5 +66,9 @@ print(f'Fenris migration: {n} step(s) applied') if n else None
done done
# Re-apply placement modes (store dir group access, issue #54) # Re-apply placement modes (store dir group access, issue #54)
systemd-tmpfiles --create || true systemd-tmpfiles --create || true
else
# runit: repair log access when upgrading from an older package
groupadd -f fenris
install -d -o root -g fenris -m 2770 /var/log/fenris-collect 2>/dev/null || true
fi fi
fi fi
+3 -4
View File
@@ -48,8 +48,8 @@ print(f'Fenris migration: {n} step(s) applied') if n else None
" 2>&1 || echo "Fenris: migration skipped (store not yet initialized)" " 2>&1 || echo "Fenris: migration skipped (store not yet initialized)"
fi fi
# Ensure log directory exists on upgrade # Ensure log directory exists on upgrade
mkdir -p /var/log/fenris-collect groupadd -f fenris
chown fenris:fenris /var/log/fenris-collect 2>/dev/null || true install -d -o root -g fenris -m 2770 /var/log/fenris-collect 2>/dev/null || true
else else
# Fresh install — runit service setup # Fresh install — runit service setup
groupadd -f fenris groupadd -f fenris
@@ -59,8 +59,7 @@ print(f'Fenris migration: {n} step(s) applied') if n else None
touch /etc/sv/fenris-collect/down touch /etc/sv/fenris-collect/down
fi fi
# Ensure log directory exists # Ensure log directory exists
mkdir -p /var/log/fenris-collect install -d -o root -g fenris -m 2770 /var/log/fenris-collect 2>/dev/null || true
chown fenris:fenris /var/log/fenris-collect 2>/dev/null || true
fi fi
;; ;;
esac esac
+52 -15
View File
@@ -42,7 +42,7 @@ for arg in "$@"; do
echo " --publish Execute the full publication flow" echo " --publish Execute the full publication flow"
echo "" echo ""
echo "Environment:" echo "Environment:"
echo " XBPS_SIGNING_KEY Path to SSH RSA private key (default: ~/.ssh/id_rsa)" echo " XBPS_SIGNING_KEY Path to SSH RSA private key (default: ~/.ssh/id_xbps)"
echo " SIGNED_BY Signature identity (default: Fenris Packaging <packaging@bongbetic.com>)" echo " SIGNED_BY Signature identity (default: Fenris Packaging <packaging@bongbetic.com>)"
exit 0 exit 0
;; ;;
@@ -84,15 +84,24 @@ for tool in xbps-create xbps-rindex git; do
if ! command -v "$tool" &>/dev/null; then if ! command -v "$tool" &>/dev/null; then
echo "ERROR: Required tool not found: $tool" >&2 echo "ERROR: Required tool not found: $tool" >&2
exit 1 exit 1
done fi
done done
# ── Main ───────────────────────────────────────────────────────────────── # ── Main ─────────────────────────────────────────────────────────────────
VERSION=$(_version) VERSION=$(_version)
REVISION=1 REVISION="${XBPS_REVISION:-1}"
PKGVER="fenris-${VERSION}_${REVISION}" PKGVER="fenris-${VERSION}_${REVISION}"
XBPS_FILE="${PKGVER}.${ARCH}.xbps" XBPS_FILE="${PKGVER}.${ARCH}.xbps"
SOURCE_DIR=$(pwd)
XBPS_PATH="${SOURCE_DIR}/${XBPS_FILE}"
GIT_USER_NAME=$(git config user.name || true)
GIT_USER_EMAIL=$(git config user.email || true)
if [[ -z "${GIT_USER_NAME}" || -z "${GIT_USER_EMAIL}" ]]; then
echo "ERROR: Configure git user.name and user.email in the source repository before publishing" >&2
exit 1
fi
echo "=== Fenris XBPS Publication v${VERSION} ===" echo "=== Fenris XBPS Publication v${VERSION} ==="
echo "" echo ""
@@ -105,14 +114,14 @@ fi
# ── Step 1: Build XBPS package ─────────────────────────────────────────── # ── Step 1: Build XBPS package ───────────────────────────────────────────
echo "--- Build XBPS package ---" echo "--- Build XBPS package ---"
_run "make stage" _run "make XBPS_REVISION=${REVISION} package-xbps"
_run "xbps-create -A ${ARCH} -n ${PKGVER} -s 'Fenris NVMe wear monitor' -S 'NVMe wear monitor with persistent TUI' -m 'Fenris Packaging <packaging@bongbetic.com>' -H 'https://git.bongbetic.com/xavierk/Fenris' -l 'MIT' build/stage"
echo "" echo ""
# ── Step 2: Sign package ───────────────────────────────────────────────── # ── Step 2: Sign package ─────────────────────────────────────────────────
echo "--- Sign XBPS package ---" echo "--- Sign XBPS package ---"
_run "xbps-rindex --sign-pkg --privkey ${XBPS_SIGNING_KEY} ${XBPS_FILE}" _run "rm -f ${XBPS_PATH}.sig2"
_run "xbps-rindex --sign-pkg --privkey ${XBPS_SIGNING_KEY} ${XBPS_PATH}"
echo "" echo ""
# ── Step 3: Clone/update distribution repository ───────────────────────── # ── Step 3: Clone/update distribution repository ─────────────────────────
@@ -120,31 +129,59 @@ echo ""
echo "--- Prepare distribution repository ---" echo "--- Prepare distribution repository ---"
WORK_DIR=$(mktemp -d) WORK_DIR=$(mktemp -d)
_run "git clone ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}.git ${WORK_DIR}" _run "git clone ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}.git ${WORK_DIR}"
_run "cd ${WORK_DIR} && git checkout ${GITEA_BRANCH}" _run "git -C ${WORK_DIR} config user.name '${GIT_USER_NAME}'"
_run "git -C ${WORK_DIR} config user.email '${GIT_USER_EMAIL}'"
_run "git -C ${WORK_DIR} checkout ${GITEA_BRANCH}"
_run "mkdir -p ${WORK_DIR}/${ARCH}" _run "mkdir -p ${WORK_DIR}/${ARCH}"
echo "" echo ""
# ── Step 4: Copy artifacts and update index ────────────────────────────── # ── Step 4: Copy artifacts and update index ──────────────────────────────
echo "--- Update repository index ---" echo "--- Update repository index ---"
_run "cp ${XBPS_FILE} ${XBPS_FILE}.sig2 ${WORK_DIR}/${ARCH}/" _run "cp ${XBPS_PATH} ${XBPS_PATH}.sig2 ${WORK_DIR}/${ARCH}/"
_run "cd ${WORK_DIR} && xbps-rindex --add ${ARCH}/${XBPS_FILE}" _run "(cd ${WORK_DIR} && xbps-rindex --add ${ARCH}/${XBPS_FILE})"
_run "cd ${WORK_DIR} && xbps-rindex --sign --privkey ${XBPS_SIGNING_KEY} --signedby '${SIGNED_BY}' ${ARCH}" _run "(cd ${WORK_DIR} && xbps-rindex --sign --privkey ${XBPS_SIGNING_KEY} --signedby '${SIGNED_BY}' ${ARCH})"
echo "" echo ""
# ── Step 5: Commit and push ────────────────────────────────────────────── # ── Step 5: Commit and push ──────────────────────────────────────────────
echo "--- Commit and push ---" echo "--- Commit and push ---"
_run "cd ${WORK_DIR} && git add -A" _run "git -C ${WORK_DIR} add -A"
_run "cd ${WORK_DIR} && git commit -m 'Release fenris ${VERSION}'" _run "git -C ${WORK_DIR} commit -m 'Release fenris ${VERSION}'"
_run "cd ${WORK_DIR} && git push origin ${GITEA_BRANCH}" _run "git -C ${WORK_DIR} push origin ${GITEA_BRANCH}"
echo "" echo ""
# ── Step 6: Verify publication ─────────────────────────────────────────── # ── Step 6: Verify publication ───────────────────────────────────────────
echo "--- Verify publication ---" echo "--- Verify publication ---"
RAW_URL="${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/${GITEA_BRANCH}/${ARCH}/x86_64-repodata" RAW_BASE="${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/${GITEA_BRANCH}/${ARCH}"
_run "curl -sI '${RAW_URL}' | head -5" if $PUBLISH; then
# Compare every served byte with the artifact that was indexed and pushed.
# A successful HEAD request alone can still hide a stale or incomplete
# publication behind the raw endpoint's cache.
for artifact in "${XBPS_FILE}" "${XBPS_FILE}.sig2" "x86_64-repodata" "x86_64-repodata.sig2"; do
case "${artifact}" in
"${XBPS_FILE}") local_path="${XBPS_PATH}" ;;
"${XBPS_FILE}.sig2") local_path="${XBPS_PATH}.sig2" ;;
*) local_path="${WORK_DIR}/${ARCH}/${artifact}" ;;
esac
downloaded="${WORK_DIR}/.${artifact}.download"
curl --fail --silent --show-error --location \
--output "${downloaded}" "${RAW_BASE}/${artifact}"
cmp -- "${local_path}" "${downloaded}"
rm -f "${downloaded}"
done
else
_run "curl --fail --silent --show-error --location --output ${WORK_DIR}/.${XBPS_FILE}.download ${RAW_BASE}/${XBPS_FILE}"
_run "cmp -- ${XBPS_PATH} ${WORK_DIR}/.${XBPS_FILE}.download"
_run "curl --fail --silent --show-error --location --output ${WORK_DIR}/.${XBPS_FILE}.sig2.download ${RAW_BASE}/${XBPS_FILE}.sig2"
_run "cmp -- ${XBPS_PATH}.sig2 ${WORK_DIR}/.${XBPS_FILE}.sig2.download"
_run "curl --fail --silent --show-error --location --output ${WORK_DIR}/.x86_64-repodata.download ${RAW_BASE}/x86_64-repodata"
_run "cmp -- ${WORK_DIR}/${ARCH}/x86_64-repodata ${WORK_DIR}/.x86_64-repodata.download"
_run "curl --fail --silent --show-error --location --output ${WORK_DIR}/.x86_64-repodata.sig2.download ${RAW_BASE}/x86_64-repodata.sig2"
_run "cmp -- ${WORK_DIR}/${ARCH}/x86_64-repodata.sig2 ${WORK_DIR}/.x86_64-repodata.sig2.download"
_run "rm -f ${WORK_DIR}/.${XBPS_FILE}.download ${WORK_DIR}/.${XBPS_FILE}.sig2.download ${WORK_DIR}/.x86_64-repodata.download ${WORK_DIR}/.x86_64-repodata.sig2.download"
fi
echo "" echo ""
# ── Cleanup ────────────────────────────────────────────────────────────── # ── Cleanup ──────────────────────────────────────────────────────────────
+15
View File
@@ -96,6 +96,21 @@ def _find_package(fmt: str) -> Path:
return candidate return candidate
def test_runit_logger_uses_accounts_shipped_by_package():
"""The runit logger must use the package's group-only identity.
The package declares a ``fenris`` group for store/log access, not a
``fenris`` service user. Starting the logger with ``fenris:fenris``
therefore leaves the diagnostics supervisor down on a real Void host;
Void's standard ``nobody`` account supplies the unprivileged uid.
"""
logger = (REPO_ROOT / "units" / "runit" / "fenris-collect" / "log" / "run").read_text()
sysusers = (REPO_ROOT / "packaging" / "sysusers.d" / "fenris.conf").read_text()
assert "g fenris -" in sysusers
assert "chpst -u nobody:fenris" in logger
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Matrix definitions # Matrix definitions
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
+4 -1
View File
@@ -5,5 +5,8 @@
# The logger writes to runit's log directory for diagnostics. # The logger writes to runit's log directory for diagnostics.
# #
# Spec: §8.8 (actionable native diagnostics) # Spec: §8.8 (actionable native diagnostics)
exec chpst -u fenris:fenris \ # The package creates the fenris group for shared diagnostics access; it does
# not create a service user. Use Void's standard unprivileged account while
# giving the logger the declared group identity.
exec chpst -u nobody:fenris \
svlogd -tt /var/log/fenris-collect/ svlogd -tt /var/log/fenris-collect/