unos-repository

APK repository for unos
git clone git://git.finwo.net/misc/unos-repository
Log | Files | Refs | README

commit ccd2525c35defdfa2cf9de1cc769665a4465da34
parent 940e2c245b4543acbc62b88ecbb796df085e9985
Author: Robin Bron <robin.bron@yourhosting.nl>
Date:   Fri, 25 Sep 2026 00:23:29 +0200

Bootstrapping the repository

Diffstat:
M.conductor.yml | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/bootstrap-repo.sh | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmk/gen-pipeline.sh | 14++++++++------
3 files changed, 147 insertions(+), 6 deletions(-)

diff --git a/.conductor.yml b/.conductor.yml @@ -31,6 +31,8 @@ defaults: tasks: check: timeout: 30m + arch: [x86_64] + requires: [unos-sign-key] script: - ./mk/ci-setup.sh # Before deps.sh check, not after: muon is a declared hostmakedepends of @@ -40,8 +42,11 @@ tasks: - ./mk/deps.sh check - ./mk/gen-pipeline.sh --check - ./tests/run.sh --unit + - ./mk/bootstrap-repo.sh pkg-zlib: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -53,6 +58,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" zlib pkg-openssl: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -65,6 +72,7 @@ tasks: pkg-apk-tools: needs: + - check - pkg-zlib - pkg-openssl arch: [x86_64] @@ -78,6 +86,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" apk-tools pkg-base-files: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -89,6 +99,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" base-files pkg-busybox: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -101,6 +113,7 @@ tasks: pkg-curl: needs: + - check - pkg-openssl - pkg-zlib arch: [x86_64] @@ -114,6 +127,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" curl pkg-dosfstools: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -125,6 +140,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" dosfstools pkg-e2fsprogs: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -136,6 +153,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" e2fsprogs pkg-efivar: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -147,6 +166,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" efivar pkg-popt: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -159,6 +180,7 @@ tasks: pkg-efibootmgr: needs: + - check - pkg-efivar - pkg-popt arch: [x86_64] @@ -172,6 +194,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" efibootmgr pkg-glibc: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -183,6 +207,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" glibc pkg-libstdcxx: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -195,6 +221,7 @@ tasks: pkg-gptfdisk: needs: + - check - pkg-e2fsprogs - pkg-popt - pkg-libstdcxx @@ -209,6 +236,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" gptfdisk pkg-xz: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -221,6 +250,7 @@ tasks: pkg-grub: needs: + - check - pkg-xz arch: [x86_64] requires: [unos-sign-key] @@ -233,6 +263,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" grub pkg-libmnl: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -244,6 +276,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" libmnl pkg-libcap: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -256,6 +290,7 @@ tasks: pkg-iproute2: needs: + - check - pkg-libmnl - pkg-libcap arch: [x86_64] @@ -269,6 +304,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" iproute2 pkg-linkd: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -280,6 +317,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" linkd pkg-linux-longterm: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -291,6 +330,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" linux-longterm pkg-linux-mainline: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -302,6 +343,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" linux-mainline pkg-linux-stable: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -314,6 +357,7 @@ tasks: pkg-smartmontools: needs: + - check - pkg-libstdcxx arch: [x86_64] requires: [unos-sign-key] @@ -326,6 +370,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" smartmontools pkg-tinyssh: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -337,6 +383,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" tinyssh pkg-unos-firstboot: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: @@ -348,6 +396,8 @@ tasks: - ./mk/publish.sh --arch "$ARCH" unos-firstboot pkg-unos-keys: + needs: + - check arch: [x86_64] requires: [unos-sign-key] script: diff --git a/mk/bootstrap-repo.sh b/mk/bootstrap-repo.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# mk/bootstrap-repo.sh - ensure an APKINDEX exists in the S3 repo. +# +# If the bucket already has x86_64/APKINDEX.tar.gz, do nothing. +# Otherwise publish an empty signed index so `apk add` against the +# repo stops 404ing before the first real package has been published. +set -eu + +HERE=$(cd "$(dirname "$0")" && pwd) +ROOT=$(cd "${HERE}/.." && pwd) + +ARCH="${ARCH:-x86_64}" +case "${ARCH}" in arm64) ARCH=aarch64 ;; esac + +for v in BUCKET_ACCESS_KEY BUCKET_SECRET_KEY BUCKET_NAME BUCKET_ENDPOINT BUCKET_REGION; do + eval "val=\${${v}:-}" + [ -n "${val}" ] || { echo "bootstrap-repo.sh: ${v} is not set" >&2; exit 1; } +done + +url="${BUCKET_ENDPOINT%/}/${BUCKET_NAME}/${ARCH}/APKINDEX.tar.gz" +code=$(curl -sS -o /dev/null -w '%{http_code}' \ + --aws-sigv4 "aws:amz:${BUCKET_REGION}:s3" \ + --user "${BUCKET_ACCESS_KEY}:${BUCKET_SECRET_KEY}" \ + "${url}") || code=000 + +case "${code}" in + 2*) echo "==> repo already has ${ARCH}/APKINDEX.tar.gz (${code}), nothing to do"; exit 0 ;; + 404|000) echo "==> no ${ARCH}/APKINDEX.tar.gz (${code}), bootstrapping empty index" ;; + *) echo "bootstrap-repo.sh: unexpected HTTP ${code} for ${url}" >&2; exit 1 ;; +esac + +mkdir -p "${ROOT}/build/repo/${ARCH}" + +export PATH="${ROOT}/build/host/bin:${PATH}" +command -v apk >/dev/null 2>&1 || { echo "bootstrap-repo.sh: no apk on PATH; run mk/bootstrap-host.sh first" >&2; exit 1; } + +. "${HERE}/sign-key.inc" +KEY=$(resolve_sign_key) || { echo "bootstrap-repo.sh: no signing key" >&2; exit 1; } +KEYNAME=$(basename "${KEY}" .rsa) + +if [ ! -x "${HERE}/pax-tar" ] || [ "${HERE}/pax-tar.c" -nt "${HERE}/pax-tar" ]; then + cc -std=c99 -O2 -Wall -Wextra -o "${HERE}/pax-tar" "${HERE}/pax-tar.c" +fi + +cd "${ROOT}/build/repo/${ARCH}" + +# apk index with no inputs still needs to produce a valid archive; +# `echo` avoids the shell expanding *.apk to a literal when empty. +echo -n "" | tar -czf APKINDEX.tar.gz -T /dev/null 2>/dev/null || true +# Try the real tool first; fall back to the empty tar if it produced nothing. +if [ ! -s APKINDEX.tar.gz ] || ! tar -tzf APKINDEX.tar.gz >/dev/null 2>&1; then + : > APKINDEX + tar -czf APKINDEX.tar.gz APKINDEX + rm -f APKINDEX +fi + +# Rebuild properly if apk can do it (covers the signed-index header fixup below) +# and ensures the index is well-formed even when empty. +if ls ./*.apk >/dev/null 2>&1; then + apk index --allow-untrusted -o APKINDEX.tar.gz ./*.apk +else + # empty repo: create minimal index that `apk add` accepts + rm -f APKINDEX.tar.gz + mkdir -p .idx-empty + : > .idx-empty/APKINDEX + tar -czf APKINDEX.tar.gz -C .idx-empty APKINDEX + rm -rf .idx-empty +fi + +echo "==> signing APKINDEX.tar.gz with ${KEYNAME}" +openssl dgst -sha1 -sign "${KEY}" -out ".SIGN.RSA.${KEYNAME}.rsa.pub" APKINDEX.tar.gz +mkdir -p "${ROOT}/build/work/.idxsig" +cp ".SIGN.RSA.${KEYNAME}.rsa.pub" "${ROOT}/build/work/.idxsig/" +"${HERE}/pax-tar" --no-checksum "${ROOT}/build/work/.idxsig" idxsig.tar +sigsiz=$(stat -c%s idxsig.tar) +head -c $((sigsiz - 1024)) idxsig.tar > idxsignotr.tar +gzip -n -9 -f idxsignotr.tar +cat idxsignotr.tar.gz APKINDEX.tar.gz > APKINDEX.signed.tar.gz +mv APKINDEX.signed.tar.gz APKINDEX.tar.gz +rm -f ".SIGN.RSA.${KEYNAME}.rsa.pub" idxsig.tar idxsignotr.tar.gz +rm -rf "${ROOT}/build/work/.idxsig" + +echo "==> publishing ${ARCH}/APKINDEX.tar.gz" +code=$(curl -sS -o /dev/null -w '%{http_code}' \ + --aws-sigv4 "aws:amz:${BUCKET_REGION}:s3" \ + --user "${BUCKET_ACCESS_KEY}:${BUCKET_SECRET_KEY}" \ + -X PUT --upload-file APKINDEX.tar.gz \ + "${url}") || { echo "bootstrap-repo.sh: upload failed" >&2; exit 1; } +case "${code}" in 2*) echo "==> bootstrapped ${ARCH}/APKINDEX.tar.gz (${code})" ;; *) echo "bootstrap-repo.sh: upload returned HTTP ${code}" >&2; exit 1 ;; esac diff --git a/mk/gen-pipeline.sh b/mk/gen-pipeline.sh @@ -73,6 +73,8 @@ defaults: tasks: check: timeout: 30m + arch: [x86_64] + requires: [unos-sign-key] script: - ./mk/ci-setup.sh # Before deps.sh check, not after: muon is a declared hostmakedepends of @@ -82,6 +84,7 @@ tasks: - ./mk/deps.sh check - ./mk/gen-pipeline.sh --check - ./tests/run.sh --unit + - ./mk/bootstrap-repo.sh HEADER @@ -89,12 +92,11 @@ HEADER for p in $(cd "${ROOT}" && ./mk/deps.sh order); do deps=$(cd "${ROOT}" && ./mk/deps.sh vars "$p" | sed -n 's/^makedepends: *//p') printf ' %s:\n' "$(task_name "$p")" - if [ -n "${deps}" ]; then - printf ' needs:\n' - for d in ${deps}; do - printf ' - %s\n' "$(task_name "$d")" - done - fi + printf ' needs:\n' + printf ' - check\n' + for d in ${deps}; do + printf ' - %s\n' "$(task_name "$d")" + done # arch is declared so $ARCH exists in the script; it is only injected for # tasks that declare it. One arch today, but adding aarch64 is then a # single edit here rather than a rewrite.