diff --git a/projects/ArchR/packages/archr/autostart/004-seed-pacmandb b/projects/ArchR/packages/archr/autostart/004-seed-pacmandb new file mode 100755 index 0000000000..fcf8e2c0e9 --- /dev/null +++ b/projects/ArchR/packages/archr/autostart/004-seed-pacmandb @@ -0,0 +1,45 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2026 ArchR (https://github.com/archr-linux/Arch-R) +# +# Seed the pacman *installed* (local) db on first boot so archr-update / +# `pacman -Syu` can upgrade the BASE system, not just user-installed addons. +# +# The image rootfs is a squashfs, not a pacman install, so /var/lib/pacman +# (-> /storage/.pacman/db) starts empty: `pacman -Q` returns nothing and +# `pacman -Qu` finds no upgrades even when the repo carries newer base +# packages. scripts/repo/gen-pacman-repo publishes a matching seed +# (-localdb.tar.gz) alongside the packages for every build, so we pull +# it from the same release channel and extract it once. Only seed when the +# local db is still empty, so a user who has installed/removed packages with +# pacman is never clobbered. + +. /etc/profile.d/001-functions 2>/dev/null + +DB=/storage/.pacman/db +REPO_NAME=archr-core +BRANCH="$(get_setting updates.branch 2>/dev/null)" +BRANCH="${BRANCH:-stable}" +SEED_URL="https://github.com/archr-linux/archr-repo/releases/download/repo-${BRANCH}/${REPO_NAME}-localdb.tar.gz" +LOG=/var/log/pacman-seed.log + +mkdir -p "${DB}" + +# Already seeded? Anything beyond ALPM_DB_VERSION means the local db is +# populated (by this hook earlier, or by the user's own pacman activity). +if [ -d "${DB}/local" ] && + [ "$(ls -1 "${DB}/local" 2>/dev/null | grep -vc '^ALPM_DB_VERSION$')" -gt 0 ]; then + exit 0 +fi + +# Needs network; if it is not up yet we silently retry on the next boot. +ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1 || exit 0 + +tmp=/tmp/archr-localdb.tar.gz +if curl -fsSL "${SEED_URL}" -o "${tmp}" 2>>"${LOG}" || + wget -q -O "${tmp}" "${SEED_URL}" 2>>"${LOG}"; then + if tar -C "${DB}" -xzf "${tmp}" 2>>"${LOG}"; then + echo "$(date): seeded pacman local db from ${SEED_URL}" >>"${LOG}" + fi + rm -f "${tmp}" +fi diff --git a/scripts/repo/gen-pacman-repo b/scripts/repo/gen-pacman-repo index cfd1ff7e0f..496e057975 100755 --- a/scripts/repo/gen-pacman-repo +++ b/scripts/repo/gen-pacman-repo @@ -167,6 +167,30 @@ fi ln -sf "${REPO_NAME}.db.tar.gz" "${REPO_NAME}.db" && \ ln -sf "${REPO_NAME}.files.tar.gz" "${REPO_NAME}.files" ) +# Seed an installed (local) db. Without it the shipped image's +# /var/lib/pacman/local is empty: `pacman -Q` returns nothing and +# `pacman -Syu` (archr-update) can only install user addons, never upgrade +# the base. We register every just-built package as installed (db entry +# only; the files already live in the image squashfs) into a staging dbpath +# and tar the resulting local/ tree. It is published as a repo asset and +# pulled in on first boot by the 004-seed-pacmandb autostart hook (so no +# image-build wiring is needed; the seed always matches this build). +echo "gen-pacman-repo: seeding installed (local) db..." +seed_dbpath="${OUT_DIR}/.seed-dbpath" +rm -rf "${seed_dbpath}" "${OUT_DIR}/.seed-root" +mkdir -p "${seed_dbpath}/local" "${seed_dbpath}/sync" +cp "${local_db}" "${seed_dbpath}/sync/${REPO_NAME}.db" +if fakeroot pacman -U --dbonly --noconfirm \ + --root "${OUT_DIR}/.seed-root" --dbpath "${seed_dbpath}" \ + --cachedir "${OUT_DIR}" \ + "${OUT_DIR}"/*.pkg.tar.zst >/dev/null 2>&1; then + tar -C "${seed_dbpath}" -czf "${OUT_DIR}/${REPO_NAME}-localdb.tar.gz" local + echo " wrote ${REPO_NAME}-localdb.tar.gz ($(ls -1 "${seed_dbpath}/local" | wc -l) entries)" +else + echo " WARNING: local-db seed failed; base will not be pacman-upgradable" >&2 +fi +rm -rf "${seed_dbpath}" "${OUT_DIR}/.seed-root" + echo "" echo "gen-pacman-repo: ready at ${OUT_DIR}" ls -1sh "${OUT_DIR}" | head -20