unos-repository

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

commit 1a8b74e175f21b92a3c58cdcda83fce1e4329e20
parent e2719bcce01ef537d40015e6497e48eeb736a168
Author: Robin Bron <robin.bron@yourhosting.nl>
Date:   Mon, 28 Sep 2026 22:17:58 +0200

Switch to channels instead of single flat repo

Diffstat:
M.conductor.yml | 1207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Achannels/base/channel.conf | 3+++
Achannels/base/packages/README.md | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Achannels/base/packages/apk-tools/template | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rpackages/base-files/files/fstab -> channels/base/packages/base-files/files/fstab | 0
Rpackages/base-files/files/group -> channels/base/packages/base-files/files/group | 0
Rpackages/base-files/files/hostname -> channels/base/packages/base-files/files/hostname | 0
Rpackages/base-files/files/hosts -> channels/base/packages/base-files/files/hosts | 0
Rpackages/base-files/files/inittab -> channels/base/packages/base-files/files/inittab | 0
Rpackages/base-files/files/ld.so.conf -> channels/base/packages/base-files/files/ld.so.conf | 0
Rpackages/base-files/files/linkd.cnf -> channels/base/packages/base-files/files/linkd.cnf | 0
Rpackages/base-files/files/network/interfaces -> channels/base/packages/base-files/files/network/interfaces | 0
Rpackages/base-files/files/network/ports -> channels/base/packages/base-files/files/network/ports | 0
Rpackages/base-files/files/nsswitch.conf -> channels/base/packages/base-files/files/nsswitch.conf | 0
Rpackages/base-files/files/os-release -> channels/base/packages/base-files/files/os-release | 0
Rpackages/base-files/files/passwd -> channels/base/packages/base-files/files/passwd | 0
Rpackages/base-files/files/profile -> channels/base/packages/base-files/files/profile | 0
Rpackages/base-files/files/rcS -> channels/base/packages/base-files/files/rcS | 0
Rpackages/base-files/files/shadow -> channels/base/packages/base-files/files/shadow | 0
Rpackages/base-files/files/shells -> channels/base/packages/base-files/files/shells | 0
Rpackages/base-files/template -> channels/base/packages/base-files/template | 0
Rpackages/busybox/template -> channels/base/packages/busybox/template | 0
Rpackages/curl/files/post-install -> channels/base/packages/curl/files/post-install | 0
Rpackages/curl/template -> channels/base/packages/curl/template | 0
Rpackages/dosfstools/template -> channels/base/packages/dosfstools/template | 0
Rpackages/e2fsprogs/files/post-install -> channels/base/packages/e2fsprogs/files/post-install | 0
Rpackages/e2fsprogs/template -> channels/base/packages/e2fsprogs/template | 0
Rpackages/efibootmgr/template -> channels/base/packages/efibootmgr/template | 0
Rpackages/efivar/files/post-install -> channels/base/packages/efivar/files/post-install | 0
Rpackages/efivar/template -> channels/base/packages/efivar/template | 0
Rpackages/glibc/files/post-install -> channels/base/packages/glibc/files/post-install | 0
Rpackages/glibc/template -> channels/base/packages/glibc/template | 0
Rpackages/gptfdisk/template -> channels/base/packages/gptfdisk/template | 0
Rpackages/grub/template -> channels/base/packages/grub/template | 0
Rpackages/iproute2/template -> channels/base/packages/iproute2/template | 0
Rpackages/libcap/files/post-install -> channels/base/packages/libcap/files/post-install | 0
Rpackages/libcap/template -> channels/base/packages/libcap/template | 0
Rpackages/libmnl/files/post-install -> channels/base/packages/libmnl/files/post-install | 0
Rpackages/libmnl/template -> channels/base/packages/libmnl/template | 0
Rpackages/libstdc++/files/post-install -> channels/base/packages/libstdc++/files/post-install | 0
Rpackages/libstdc++/template -> channels/base/packages/libstdc++/template | 0
Rpackages/linkd/files/linkd-check -> channels/base/packages/linkd/files/linkd-check | 0
Rpackages/linkd/files/linkd-log-run -> channels/base/packages/linkd/files/linkd-log-run | 0
Rpackages/linkd/files/linkd-run -> channels/base/packages/linkd/files/linkd-run | 0
Rpackages/linkd/template -> channels/base/packages/linkd/template | 0
Rpackages/linux-longterm/files/post-install.linux -> channels/base/packages/linux/files/post-install | 0
Achannels/base/packages/linux/template | 38++++++++++++++++++++++++++++++++++++++
Rpackages/openssl/files/post-install -> channels/base/packages/openssl/files/post-install | 0
Rpackages/openssl/template -> channels/base/packages/openssl/template | 0
Rpackages/popt/files/post-install -> channels/base/packages/popt/files/post-install | 0
Rpackages/popt/template -> channels/base/packages/popt/template | 0
Rpackages/smartmontools/template -> channels/base/packages/smartmontools/template | 0
Rpackages/tinyssh/files/tinyssh-check -> channels/base/packages/tinyssh/files/tinyssh-check | 0
Rpackages/tinyssh/files/tinyssh-log-run -> channels/base/packages/tinyssh/files/tinyssh-log-run | 0
Rpackages/tinyssh/files/tinyssh-run -> channels/base/packages/tinyssh/files/tinyssh-run | 0
Rpackages/tinyssh/template -> channels/base/packages/tinyssh/template | 0
Rpackages/unos-firstboot/files/unos-firstboot -> channels/base/packages/unos-firstboot/files/unos-firstboot | 0
Rpackages/unos-firstboot/template -> channels/base/packages/unos-firstboot/template | 0
Rpackages/unos-keys/files/apk/unos-ci-62a2ab39@rtr.rsa.pub -> channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@rtr.rsa.pub | 0
Rpackages/unos-keys/files/apk/unos-ci-62a2ab39@sat06.rsa.pub -> channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat06.rsa.pub | 0
Rpackages/unos-keys/files/apk/unos-ci-62a2ab39@sat07.rsa.pub -> channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat07.rsa.pub | 0
Rpackages/unos-keys/files/apk/unos-ci-62a2ab39@sat13.rsa.pub -> channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat13.rsa.pub | 0
Rpackages/unos-keys/files/apk/unos-dev@finwo.dev-096b7b41.rsa.pub -> channels/base/packages/unos-keys/files/apk/unos-dev@finwo.dev-096b7b41.rsa.pub | 0
Rpackages/unos-keys/files/unos/unos-ci-62a2ab39@rtr.ed25519.pub -> channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@rtr.ed25519.pub | 0
Rpackages/unos-keys/files/unos/unos-ci-62a2ab39@sat06.ed25519.pub -> channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat06.ed25519.pub | 0
Rpackages/unos-keys/files/unos/unos-ci-62a2ab39@sat07.ed25519.pub -> channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat07.ed25519.pub | 0
Rpackages/unos-keys/files/unos/unos-ci-62a2ab39@sat13.ed25519.pub -> channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat13.ed25519.pub | 0
Rpackages/unos-keys/files/unos/unos-dev@finwo.dev-6a2764d4.ed25519.pub -> channels/base/packages/unos-keys/files/unos/unos-dev@finwo.dev-6a2764d4.ed25519.pub | 0
Rpackages/unos-keys/template -> channels/base/packages/unos-keys/template | 0
Rpackages/xz/files/post-install -> channels/base/packages/xz/files/post-install | 0
Rpackages/xz/template -> channels/base/packages/xz/template | 0
Rpackages/zlib/files/post-install -> channels/base/packages/zlib/files/post-install | 0
Rpackages/zlib/template -> channels/base/packages/zlib/template | 0
Achannels/edge/channel.conf | 1+
Rpackages/linux-mainline/files/post-install.linux -> channels/edge/packages/linux/files/post-install | 0
Achannels/edge/packages/linux/template | 30++++++++++++++++++++++++++++++
Achannels/lts/channel.conf | 1+
Achannels/stable/channel.conf | 1+
Rpackages/linux-stable/files/post-install.linux -> channels/stable/packages/linux/files/post-install | 0
Achannels/stable/packages/linux/template | 27+++++++++++++++++++++++++++
Mmk/README.md | 42+++++++++++++++++++++++++++++++++---------
Mmk/bootstrap-repo.sh | 30++++++++++++++++++++----------
Mmk/build-all.sh | 12++++++++++--
Mmk/build.sh | 41+++++++++++++++++++++++++++--------------
Amk/channel-assemble.sh | 39+++++++++++++++++++++++++++++++++++++++
Amk/channel-lint.sh | 44++++++++++++++++++++++++++++++++++++++++++++
Amk/channels.inc | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmk/check-revision.sh | 28+++++++++++++++++-----------
Mmk/deps.sh | 40++++++++++++++++++++++++++++++++--------
Mmk/gen-pipeline.sh | 135+++++++++++++++++++++++++++++++++----------------------------------------------
Mmk/kernel.inc | 28+++++++++++++++++-----------
Mmk/keymgmt.sh | 9+++++----
Mmk/publish.sh | 21+++++++++++++++++----
Mmk/repo-index.sh | 15++++++++++++---
Mmk/repo-pull.sh | 57+++++++++++++++++++++++++++++----------------------------
Mmk/sign-key.inc | 2+-
Mmk/sysroot.sh | 63+++++++++++++++++++++++++++------------------------------------
Dpackages/README.md | 128-------------------------------------------------------------------------------
Dpackages/apk-tools/template | 55-------------------------------------------------------
Dpackages/linux-longterm/template | 65-----------------------------------------------------------------
Dpackages/linux-mainline/template | 63---------------------------------------------------------------
Dpackages/linux-stable/template | 57---------------------------------------------------------
Mtests/helpers.sh | 13+++++++------
Mtests/unit/test_ascii.sh | 4++--
Mtests/unit/test_deps.sh | 28+++++++++++++++++++---------
105 files changed, 1794 insertions(+), 812 deletions(-)

diff --git a/.conductor.yml b/.conductor.yml @@ -2,24 +2,6 @@ # # Regenerate with: ./mk/gen-pipeline.sh --write # Verified by: tests/unit/test_deps.sh -# -# One task per package, with `needs` taken from each template's makedepends, -# so a package never builds before something it links against. The list is -# written out rather than discovered because the conductor treats this file as -# data and will not execute repository code to build its graph. -# -# No mounts are provided and artifacts are not shared between tasks. Each build -# therefore seeds its sysroot from the published S3 repo (mk/sysroot.sh) and -# publishes its own result back (mk/publish.sh). `needs` is what guarantees a -# dependency is already published by the time a dependent starts. -# -# Credentials arrive as environment: BUCKET_ACCESS_KEY, BUCKET_SECRET_KEY, -# BUCKET_NAME, BUCKET_ENDPOINT (URL), BUCKET_REGION (region name), -# BUCKET_PUBLIC_URL (public https endpoint, e.g. https://repo.unos.finwo.net/). -# -# Signing comes from the unos-sign-key worker feature, which mounts the key and -# exports UNOS_KEY_APK_RSA_PRI. Each worker holds a distinct key, so the signer -# varies with scheduling and packages/unos-keys must trust all of them. version: 1 @@ -40,413 +22,1222 @@ tasks: # apk-tools but is built here rather than installed from a distribution, # so the check reports it missing until bootstrap has produced it. - ./mk/bootstrap-host.sh - - ./mk/deps.sh check + - ./mk/channel-lint.sh - ./mk/gen-pipeline.sh --check - ./tests/run.sh --unit - - ./mk/bootstrap-repo.sh + - ./mk/channel-assemble.sh edge + - ./mk/deps.sh --channel edge check + - ./mk/bootstrap-repo.sh --channel edge + - ./mk/channel-assemble.sh lts + - ./mk/deps.sh --channel lts check + - ./mk/bootstrap-repo.sh --channel lts + - ./mk/channel-assemble.sh stable + - ./mk/deps.sh --channel stable check + - ./mk/bootstrap-repo.sh --channel stable + + pkg-edge-glibc: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge glibc --pkgver 2.44-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" glibc + - ./mk/build.sh --channel edge glibc + - ./mk/publish.sh --channel edge --arch "$ARCH" glibc + + pkg-edge-zlib: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge zlib --pkgver 1.3.1-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" zlib + - ./mk/build.sh --channel edge zlib + - ./mk/publish.sh --channel edge --arch "$ARCH" zlib + + pkg-edge-openssl: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge openssl --pkgver 3.5.8-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" openssl + - ./mk/build.sh --channel edge openssl + - ./mk/publish.sh --channel edge --arch "$ARCH" openssl + + pkg-edge-linux: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge linux --pkgver 7.3_rc3-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux + - ./mk/build.sh --channel edge linux + - ./mk/publish.sh --channel edge --arch "$ARCH" linux + + pkg-edge-apk-tools: + needs: + - check + - pkg-edge-glibc + - pkg-edge-zlib + - pkg-edge-openssl + - pkg-edge-linux + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge apk-tools --pkgver 3.0.8-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" apk-tools + - ./mk/build.sh --channel edge apk-tools + - ./mk/publish.sh --channel edge --arch "$ARCH" apk-tools + + pkg-edge-base-files: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge base-files --pkgver 0.1.0-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" base-files + - ./mk/build.sh --channel edge base-files + - ./mk/publish.sh --channel edge --arch "$ARCH" base-files + + pkg-edge-busybox: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge busybox --pkgver 1.36.1-r8 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" busybox + - ./mk/build.sh --channel edge busybox + - ./mk/publish.sh --channel edge --arch "$ARCH" busybox + + pkg-edge-curl: + needs: + - check + - pkg-edge-openssl + - pkg-edge-zlib + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge curl --pkgver 8.18.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" curl + - ./mk/build.sh --channel edge curl + - ./mk/publish.sh --channel edge --arch "$ARCH" curl + + pkg-edge-dosfstools: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge dosfstools --pkgver 4.2-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" dosfstools + - ./mk/build.sh --channel edge dosfstools + - ./mk/publish.sh --channel edge --arch "$ARCH" dosfstools + + pkg-edge-e2fsprogs: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge e2fsprogs --pkgver 1.47.4-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" e2fsprogs + - ./mk/build.sh --channel edge e2fsprogs + - ./mk/publish.sh --channel edge --arch "$ARCH" e2fsprogs + + pkg-edge-efivar: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge efivar --pkgver 39-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efivar + - ./mk/build.sh --channel edge efivar + - ./mk/publish.sh --channel edge --arch "$ARCH" efivar + + pkg-edge-popt: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge popt --pkgver 1.19-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" popt + - ./mk/build.sh --channel edge popt + - ./mk/publish.sh --channel edge --arch "$ARCH" popt + + pkg-edge-efibootmgr: + needs: + - check + - pkg-edge-efivar + - pkg-edge-popt + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge efibootmgr --pkgver 18-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efibootmgr + - ./mk/build.sh --channel edge efibootmgr + - ./mk/publish.sh --channel edge --arch "$ARCH" efibootmgr + + pkg-edge-libstdcxx: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge libstdc++ --pkgver 14.2.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libstdc++ + - ./mk/build.sh --channel edge libstdc++ + - ./mk/publish.sh --channel edge --arch "$ARCH" libstdc++ + + pkg-edge-gptfdisk: + needs: + - check + - pkg-edge-e2fsprogs + - pkg-edge-popt + - pkg-edge-libstdcxx + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge gptfdisk --pkgver 1.0.10-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" gptfdisk + - ./mk/build.sh --channel edge gptfdisk + - ./mk/publish.sh --channel edge --arch "$ARCH" gptfdisk + + pkg-edge-xz: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge xz --pkgver 5.8.4-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" xz + - ./mk/build.sh --channel edge xz + - ./mk/publish.sh --channel edge --arch "$ARCH" xz + + pkg-edge-grub: + needs: + - check + - pkg-edge-xz + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge grub --pkgver 2.14-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" grub + - ./mk/build.sh --channel edge grub + - ./mk/publish.sh --channel edge --arch "$ARCH" grub + + pkg-edge-libmnl: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge libmnl --pkgver 1.0.5-r5 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libmnl + - ./mk/build.sh --channel edge libmnl + - ./mk/publish.sh --channel edge --arch "$ARCH" libmnl + + pkg-edge-libcap: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge libcap --pkgver 2.78-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libcap + - ./mk/build.sh --channel edge libcap + - ./mk/publish.sh --channel edge --arch "$ARCH" libcap + + pkg-edge-iproute2: + needs: + - check + - pkg-edge-libmnl + - pkg-edge-libcap + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge iproute2 --pkgver 6.19.0-r3 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" iproute2 + - ./mk/build.sh --channel edge iproute2 + - ./mk/publish.sh --channel edge --arch "$ARCH" iproute2 + + pkg-edge-linkd: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge linkd --pkgver 0.1.0-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linkd + - ./mk/build.sh --channel edge linkd + - ./mk/publish.sh --channel edge --arch "$ARCH" linkd + + pkg-edge-smartmontools: + needs: + - check + - pkg-edge-libstdcxx + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge smartmontools --pkgver 7.5-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" smartmontools + - ./mk/build.sh --channel edge smartmontools + - ./mk/publish.sh --channel edge --arch "$ARCH" smartmontools + + pkg-edge-tinyssh: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge tinyssh --pkgver 20260906-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" tinyssh + - ./mk/build.sh --channel edge tinyssh + - ./mk/publish.sh --channel edge --arch "$ARCH" tinyssh + + pkg-edge-unos-firstboot: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge unos-firstboot --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-firstboot + - ./mk/build.sh --channel edge unos-firstboot + - ./mk/publish.sh --channel edge --arch "$ARCH" unos-firstboot + + pkg-edge-unos-keys: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel edge unos-keys --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-keys + - ./mk/build.sh --channel edge unos-keys + - ./mk/publish.sh --channel edge --arch "$ARCH" unos-keys - pkg-glibc: + pkg-lts-glibc: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh glibc --pkgver 2.44-r6 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts glibc --pkgver 2.44-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" glibc - - ./mk/build.sh glibc - - ./mk/publish.sh --arch "$ARCH" glibc + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" glibc + - ./mk/build.sh --channel lts glibc + - ./mk/publish.sh --channel lts --arch "$ARCH" glibc - pkg-zlib: + pkg-lts-zlib: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh zlib --pkgver 1.3.1-r4 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts zlib --pkgver 1.3.1-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" zlib - - ./mk/build.sh zlib - - ./mk/publish.sh --arch "$ARCH" zlib + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" zlib + - ./mk/build.sh --channel lts zlib + - ./mk/publish.sh --channel lts --arch "$ARCH" zlib - pkg-openssl: + pkg-lts-openssl: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh openssl --pkgver 3.5.8-r4 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts openssl --pkgver 3.5.8-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" openssl - - ./mk/build.sh openssl - - ./mk/publish.sh --arch "$ARCH" openssl + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" openssl + - ./mk/build.sh --channel lts openssl + - ./mk/publish.sh --channel lts --arch "$ARCH" openssl - pkg-linux-longterm: + pkg-lts-linux: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh linux-longterm --pkgver 6.18.51-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts linux --pkgver 6.18.51-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux-longterm - - ./mk/build.sh linux-longterm - - ./mk/publish.sh --arch "$ARCH" linux-longterm + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux + - ./mk/build.sh --channel lts linux + - ./mk/publish.sh --channel lts --arch "$ARCH" linux - pkg-apk-tools: + pkg-lts-apk-tools: needs: - check - - pkg-glibc - - pkg-zlib - - pkg-openssl - - pkg-linux-longterm + - pkg-lts-glibc + - pkg-lts-zlib + - pkg-lts-openssl + - pkg-lts-linux arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh apk-tools --pkgver 3.0.8-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts apk-tools --pkgver 3.0.8-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" apk-tools - - ./mk/build.sh apk-tools - - ./mk/publish.sh --arch "$ARCH" apk-tools + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" apk-tools + - ./mk/build.sh --channel lts apk-tools + - ./mk/publish.sh --channel lts --arch "$ARCH" apk-tools - pkg-base-files: + pkg-lts-base-files: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh base-files --pkgver 0.1.0-r6 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts base-files --pkgver 0.1.0-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" base-files - - ./mk/build.sh base-files - - ./mk/publish.sh --arch "$ARCH" base-files + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" base-files + - ./mk/build.sh --channel lts base-files + - ./mk/publish.sh --channel lts --arch "$ARCH" base-files - pkg-busybox: + pkg-lts-busybox: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh busybox --pkgver 1.36.1-r8 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts busybox --pkgver 1.36.1-r8 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" busybox - - ./mk/build.sh busybox - - ./mk/publish.sh --arch "$ARCH" busybox + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" busybox + - ./mk/build.sh --channel lts busybox + - ./mk/publish.sh --channel lts --arch "$ARCH" busybox - pkg-curl: + pkg-lts-curl: needs: - check - - pkg-openssl - - pkg-zlib + - pkg-lts-openssl + - pkg-lts-zlib arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh curl --pkgver 8.18.0-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts curl --pkgver 8.18.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" curl - - ./mk/build.sh curl - - ./mk/publish.sh --arch "$ARCH" curl + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" curl + - ./mk/build.sh --channel lts curl + - ./mk/publish.sh --channel lts --arch "$ARCH" curl - pkg-dosfstools: + pkg-lts-dosfstools: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh dosfstools --pkgver 4.2-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts dosfstools --pkgver 4.2-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" dosfstools - - ./mk/build.sh dosfstools - - ./mk/publish.sh --arch "$ARCH" dosfstools + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" dosfstools + - ./mk/build.sh --channel lts dosfstools + - ./mk/publish.sh --channel lts --arch "$ARCH" dosfstools - pkg-e2fsprogs: + pkg-lts-e2fsprogs: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh e2fsprogs --pkgver 1.47.4-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts e2fsprogs --pkgver 1.47.4-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" e2fsprogs - - ./mk/build.sh e2fsprogs - - ./mk/publish.sh --arch "$ARCH" e2fsprogs + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" e2fsprogs + - ./mk/build.sh --channel lts e2fsprogs + - ./mk/publish.sh --channel lts --arch "$ARCH" e2fsprogs - pkg-efivar: + pkg-lts-efivar: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh efivar --pkgver 39-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts efivar --pkgver 39-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efivar - - ./mk/build.sh efivar - - ./mk/publish.sh --arch "$ARCH" efivar + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efivar + - ./mk/build.sh --channel lts efivar + - ./mk/publish.sh --channel lts --arch "$ARCH" efivar - pkg-popt: + pkg-lts-popt: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh popt --pkgver 1.19-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts popt --pkgver 1.19-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" popt - - ./mk/build.sh popt - - ./mk/publish.sh --arch "$ARCH" popt + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" popt + - ./mk/build.sh --channel lts popt + - ./mk/publish.sh --channel lts --arch "$ARCH" popt - pkg-efibootmgr: + pkg-lts-efibootmgr: needs: - check - - pkg-efivar - - pkg-popt + - pkg-lts-efivar + - pkg-lts-popt arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh efibootmgr --pkgver 18-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts efibootmgr --pkgver 18-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efibootmgr - - ./mk/build.sh efibootmgr - - ./mk/publish.sh --arch "$ARCH" efibootmgr + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efibootmgr + - ./mk/build.sh --channel lts efibootmgr + - ./mk/publish.sh --channel lts --arch "$ARCH" efibootmgr - pkg-libstdcxx: + pkg-lts-libstdcxx: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh libstdc++ --pkgver 14.2.0-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts libstdc++ --pkgver 14.2.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libstdc++ - - ./mk/build.sh libstdc++ - - ./mk/publish.sh --arch "$ARCH" libstdc++ + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libstdc++ + - ./mk/build.sh --channel lts libstdc++ + - ./mk/publish.sh --channel lts --arch "$ARCH" libstdc++ - pkg-gptfdisk: + pkg-lts-gptfdisk: needs: - check - - pkg-e2fsprogs - - pkg-popt - - pkg-libstdcxx + - pkg-lts-e2fsprogs + - pkg-lts-popt + - pkg-lts-libstdcxx arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh gptfdisk --pkgver 1.0.10-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts gptfdisk --pkgver 1.0.10-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" gptfdisk - - ./mk/build.sh gptfdisk - - ./mk/publish.sh --arch "$ARCH" gptfdisk + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" gptfdisk + - ./mk/build.sh --channel lts gptfdisk + - ./mk/publish.sh --channel lts --arch "$ARCH" gptfdisk - pkg-xz: + pkg-lts-xz: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh xz --pkgver 5.8.4-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts xz --pkgver 5.8.4-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" xz - - ./mk/build.sh xz - - ./mk/publish.sh --arch "$ARCH" xz + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" xz + - ./mk/build.sh --channel lts xz + - ./mk/publish.sh --channel lts --arch "$ARCH" xz - pkg-grub: + pkg-lts-grub: needs: - check - - pkg-xz + - pkg-lts-xz arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh grub --pkgver 2.14-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts grub --pkgver 2.14-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" grub - - ./mk/build.sh grub - - ./mk/publish.sh --arch "$ARCH" grub + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" grub + - ./mk/build.sh --channel lts grub + - ./mk/publish.sh --channel lts --arch "$ARCH" grub - pkg-libmnl: + pkg-lts-libmnl: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh libmnl --pkgver 1.0.5-r5 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts libmnl --pkgver 1.0.5-r5 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libmnl - - ./mk/build.sh libmnl - - ./mk/publish.sh --arch "$ARCH" libmnl + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libmnl + - ./mk/build.sh --channel lts libmnl + - ./mk/publish.sh --channel lts --arch "$ARCH" libmnl - pkg-libcap: + pkg-lts-libcap: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh libcap --pkgver 2.78-r4 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts libcap --pkgver 2.78-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libcap - - ./mk/build.sh libcap - - ./mk/publish.sh --arch "$ARCH" libcap + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libcap + - ./mk/build.sh --channel lts libcap + - ./mk/publish.sh --channel lts --arch "$ARCH" libcap - pkg-iproute2: + pkg-lts-iproute2: needs: - check - - pkg-libmnl - - pkg-libcap + - pkg-lts-libmnl + - pkg-lts-libcap arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh iproute2 --pkgver 6.19.0-r3 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts iproute2 --pkgver 6.19.0-r3 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" iproute2 - - ./mk/build.sh iproute2 - - ./mk/publish.sh --arch "$ARCH" iproute2 + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" iproute2 + - ./mk/build.sh --channel lts iproute2 + - ./mk/publish.sh --channel lts --arch "$ARCH" iproute2 - pkg-linkd: + pkg-lts-linkd: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh linkd --pkgver 0.1.0-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts linkd --pkgver 0.1.0-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linkd - - ./mk/build.sh linkd - - ./mk/publish.sh --arch "$ARCH" linkd + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linkd + - ./mk/build.sh --channel lts linkd + - ./mk/publish.sh --channel lts --arch "$ARCH" linkd - pkg-linux-mainline: + pkg-lts-smartmontools: needs: - check + - pkg-lts-libstdcxx arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh linux-mainline --pkgver 7.3_rc3-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts smartmontools --pkgver 7.5-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux-mainline - - ./mk/build.sh linux-mainline - - ./mk/publish.sh --arch "$ARCH" linux-mainline + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" smartmontools + - ./mk/build.sh --channel lts smartmontools + - ./mk/publish.sh --channel lts --arch "$ARCH" smartmontools - pkg-linux-stable: + pkg-lts-tinyssh: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh linux-stable --pkgver 7.2.5-r1 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts tinyssh --pkgver 20260906-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux-stable - - ./mk/build.sh linux-stable - - ./mk/publish.sh --arch "$ARCH" linux-stable + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" tinyssh + - ./mk/build.sh --channel lts tinyssh + - ./mk/publish.sh --channel lts --arch "$ARCH" tinyssh - pkg-smartmontools: + pkg-lts-unos-firstboot: needs: - check - - pkg-libstdcxx arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh smartmontools --pkgver 7.5-r0 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts unos-firstboot --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" smartmontools - - ./mk/build.sh smartmontools - - ./mk/publish.sh --arch "$ARCH" smartmontools + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-firstboot + - ./mk/build.sh --channel lts unos-firstboot + - ./mk/publish.sh --channel lts --arch "$ARCH" unos-firstboot - pkg-tinyssh: + pkg-lts-unos-keys: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh tinyssh --pkgver 20260906-r4 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel lts unos-keys --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh lts - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" tinyssh - - ./mk/build.sh tinyssh - - ./mk/publish.sh --arch "$ARCH" tinyssh + - ./mk/sysroot.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-keys + - ./mk/build.sh --channel lts unos-keys + - ./mk/publish.sh --channel lts --arch "$ARCH" unos-keys - pkg-unos-firstboot: + pkg-stable-glibc: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh unos-firstboot --pkgver 0.1.0-r2 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel stable glibc --pkgver 2.44-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-firstboot - - ./mk/build.sh unos-firstboot - - ./mk/publish.sh --arch "$ARCH" unos-firstboot + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" glibc + - ./mk/build.sh --channel stable glibc + - ./mk/publish.sh --channel stable --arch "$ARCH" glibc - pkg-unos-keys: + pkg-stable-zlib: needs: - check arch: [x86_64] requires: [unos-sign-key] script: - - ./mk/check-revision.sh unos-keys --pkgver 0.1.0-r2 --repo "${BUCKET_PUBLIC_URL%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/check-revision.sh --channel stable zlib --pkgver 1.3.1-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable - ./mk/ci-setup.sh - ./mk/bootstrap-host.sh - - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-keys - - ./mk/build.sh unos-keys - - ./mk/publish.sh --arch "$ARCH" unos-keys + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" zlib + - ./mk/build.sh --channel stable zlib + - ./mk/publish.sh --channel stable --arch "$ARCH" zlib - index: + pkg-stable-openssl: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable openssl --pkgver 3.5.8-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" openssl + - ./mk/build.sh --channel stable openssl + - ./mk/publish.sh --channel stable --arch "$ARCH" openssl + + pkg-stable-linux: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable linux --pkgver 7.2.5-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linux + - ./mk/build.sh --channel stable linux + - ./mk/publish.sh --channel stable --arch "$ARCH" linux + + pkg-stable-apk-tools: + needs: + - check + - pkg-stable-glibc + - pkg-stable-zlib + - pkg-stable-openssl + - pkg-stable-linux + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable apk-tools --pkgver 3.0.8-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" apk-tools + - ./mk/build.sh --channel stable apk-tools + - ./mk/publish.sh --channel stable --arch "$ARCH" apk-tools + + pkg-stable-base-files: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable base-files --pkgver 0.1.0-r6 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" base-files + - ./mk/build.sh --channel stable base-files + - ./mk/publish.sh --channel stable --arch "$ARCH" base-files + + pkg-stable-busybox: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable busybox --pkgver 1.36.1-r8 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" busybox + - ./mk/build.sh --channel stable busybox + - ./mk/publish.sh --channel stable --arch "$ARCH" busybox + + pkg-stable-curl: + needs: + - check + - pkg-stable-openssl + - pkg-stable-zlib + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable curl --pkgver 8.18.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" curl + - ./mk/build.sh --channel stable curl + - ./mk/publish.sh --channel stable --arch "$ARCH" curl + + pkg-stable-dosfstools: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable dosfstools --pkgver 4.2-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" dosfstools + - ./mk/build.sh --channel stable dosfstools + - ./mk/publish.sh --channel stable --arch "$ARCH" dosfstools + + pkg-stable-e2fsprogs: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable e2fsprogs --pkgver 1.47.4-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" e2fsprogs + - ./mk/build.sh --channel stable e2fsprogs + - ./mk/publish.sh --channel stable --arch "$ARCH" e2fsprogs + + pkg-stable-efivar: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable efivar --pkgver 39-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efivar + - ./mk/build.sh --channel stable efivar + - ./mk/publish.sh --channel stable --arch "$ARCH" efivar + + pkg-stable-popt: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable popt --pkgver 1.19-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" popt + - ./mk/build.sh --channel stable popt + - ./mk/publish.sh --channel stable --arch "$ARCH" popt + + pkg-stable-efibootmgr: + needs: + - check + - pkg-stable-efivar + - pkg-stable-popt + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable efibootmgr --pkgver 18-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" efibootmgr + - ./mk/build.sh --channel stable efibootmgr + - ./mk/publish.sh --channel stable --arch "$ARCH" efibootmgr + + pkg-stable-libstdcxx: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable libstdc++ --pkgver 14.2.0-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libstdc++ + - ./mk/build.sh --channel stable libstdc++ + - ./mk/publish.sh --channel stable --arch "$ARCH" libstdc++ + + pkg-stable-gptfdisk: + needs: + - check + - pkg-stable-e2fsprogs + - pkg-stable-popt + - pkg-stable-libstdcxx + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable gptfdisk --pkgver 1.0.10-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" gptfdisk + - ./mk/build.sh --channel stable gptfdisk + - ./mk/publish.sh --channel stable --arch "$ARCH" gptfdisk + + pkg-stable-xz: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable xz --pkgver 5.8.4-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" xz + - ./mk/build.sh --channel stable xz + - ./mk/publish.sh --channel stable --arch "$ARCH" xz + + pkg-stable-grub: + needs: + - check + - pkg-stable-xz + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable grub --pkgver 2.14-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" grub + - ./mk/build.sh --channel stable grub + - ./mk/publish.sh --channel stable --arch "$ARCH" grub + + pkg-stable-libmnl: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable libmnl --pkgver 1.0.5-r5 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libmnl + - ./mk/build.sh --channel stable libmnl + - ./mk/publish.sh --channel stable --arch "$ARCH" libmnl + + pkg-stable-libcap: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable libcap --pkgver 2.78-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" libcap + - ./mk/build.sh --channel stable libcap + - ./mk/publish.sh --channel stable --arch "$ARCH" libcap + + pkg-stable-iproute2: + needs: + - check + - pkg-stable-libmnl + - pkg-stable-libcap + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable iproute2 --pkgver 6.19.0-r3 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" iproute2 + - ./mk/build.sh --channel stable iproute2 + - ./mk/publish.sh --channel stable --arch "$ARCH" iproute2 + + pkg-stable-linkd: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable linkd --pkgver 0.1.0-r1 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" linkd + - ./mk/build.sh --channel stable linkd + - ./mk/publish.sh --channel stable --arch "$ARCH" linkd + + pkg-stable-smartmontools: + needs: + - check + - pkg-stable-libstdcxx + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable smartmontools --pkgver 7.5-r0 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" smartmontools + - ./mk/build.sh --channel stable smartmontools + - ./mk/publish.sh --channel stable --arch "$ARCH" smartmontools + + pkg-stable-tinyssh: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable tinyssh --pkgver 20260906-r4 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" tinyssh + - ./mk/build.sh --channel stable tinyssh + - ./mk/publish.sh --channel stable --arch "$ARCH" tinyssh + + pkg-stable-unos-firstboot: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable unos-firstboot --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-firstboot + - ./mk/build.sh --channel stable unos-firstboot + - ./mk/publish.sh --channel stable --arch "$ARCH" unos-firstboot + + pkg-stable-unos-keys: + needs: + - check + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/check-revision.sh --channel stable unos-keys --pkgver 0.1.0-r2 --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; } + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/sysroot.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" unos-keys + - ./mk/build.sh --channel stable unos-keys + - ./mk/publish.sh --channel stable --arch "$ARCH" unos-keys + + index-edge: after: - - pkg-glibc - - pkg-zlib - - pkg-openssl - - pkg-linux-longterm - - pkg-apk-tools - - pkg-base-files - - pkg-busybox - - pkg-curl - - pkg-dosfstools - - pkg-e2fsprogs - - pkg-efivar - - pkg-popt - - pkg-efibootmgr - - pkg-libstdcxx - - pkg-gptfdisk - - pkg-xz - - pkg-grub - - pkg-libmnl - - pkg-libcap - - pkg-iproute2 - - pkg-linkd - - pkg-linux-mainline - - pkg-linux-stable - - pkg-smartmontools - - pkg-tinyssh - - pkg-unos-firstboot - - pkg-unos-keys - arch: [x86_64] - requires: [unos-sign-key] - script: - - ./mk/ci-setup.sh - - ./mk/bootstrap-host.sh - # Pull every published package down so the index describes the whole - # repo, not just whatever this container happened to build. - - ./mk/repo-pull.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" - - ./mk/repo-index.sh - - ./mk/publish.sh --arch "$ARCH" --index-only + - pkg-edge-glibc + - pkg-edge-zlib + - pkg-edge-openssl + - pkg-edge-linux + - pkg-edge-apk-tools + - pkg-edge-base-files + - pkg-edge-busybox + - pkg-edge-curl + - pkg-edge-dosfstools + - pkg-edge-e2fsprogs + - pkg-edge-efivar + - pkg-edge-popt + - pkg-edge-efibootmgr + - pkg-edge-libstdcxx + - pkg-edge-gptfdisk + - pkg-edge-xz + - pkg-edge-grub + - pkg-edge-libmnl + - pkg-edge-libcap + - pkg-edge-iproute2 + - pkg-edge-linkd + - pkg-edge-smartmontools + - pkg-edge-tinyssh + - pkg-edge-unos-firstboot + - pkg-edge-unos-keys + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/channel-assemble.sh edge + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/repo-pull.sh --channel edge --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" + - ./mk/repo-index.sh --channel edge + - ./mk/publish.sh --channel edge --arch "$ARCH" --index-only + + index-lts: + after: + - pkg-lts-glibc + - pkg-lts-zlib + - pkg-lts-openssl + - pkg-lts-linux + - pkg-lts-apk-tools + - pkg-lts-base-files + - pkg-lts-busybox + - pkg-lts-curl + - pkg-lts-dosfstools + - pkg-lts-e2fsprogs + - pkg-lts-efivar + - pkg-lts-popt + - pkg-lts-efibootmgr + - pkg-lts-libstdcxx + - pkg-lts-gptfdisk + - pkg-lts-xz + - pkg-lts-grub + - pkg-lts-libmnl + - pkg-lts-libcap + - pkg-lts-iproute2 + - pkg-lts-linkd + - pkg-lts-smartmontools + - pkg-lts-tinyssh + - pkg-lts-unos-firstboot + - pkg-lts-unos-keys + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/channel-assemble.sh lts + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/repo-pull.sh --channel lts --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" + - ./mk/repo-index.sh --channel lts + - ./mk/publish.sh --channel lts --arch "$ARCH" --index-only + + index-stable: + after: + - pkg-stable-glibc + - pkg-stable-zlib + - pkg-stable-openssl + - pkg-stable-linux + - pkg-stable-apk-tools + - pkg-stable-base-files + - pkg-stable-busybox + - pkg-stable-curl + - pkg-stable-dosfstools + - pkg-stable-e2fsprogs + - pkg-stable-efivar + - pkg-stable-popt + - pkg-stable-efibootmgr + - pkg-stable-libstdcxx + - pkg-stable-gptfdisk + - pkg-stable-xz + - pkg-stable-grub + - pkg-stable-libmnl + - pkg-stable-libcap + - pkg-stable-iproute2 + - pkg-stable-linkd + - pkg-stable-smartmontools + - pkg-stable-tinyssh + - pkg-stable-unos-firstboot + - pkg-stable-unos-keys + arch: [x86_64] + requires: [unos-sign-key] + script: + - ./mk/channel-assemble.sh stable + - ./mk/ci-setup.sh + - ./mk/bootstrap-host.sh + - ./mk/repo-pull.sh --channel stable --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" + - ./mk/repo-index.sh --channel stable + - ./mk/publish.sh --channel stable --arch "$ARCH" --index-only + diff --git a/channels/base/channel.conf b/channels/base/channel.conf @@ -0,0 +1,3 @@ +# Unpublished channels have no APKINDEX for check-revision.sh to probe, so +# they can never skip. Build with --channel base to validate; never in CI. +publish=no diff --git a/channels/base/packages/README.md b/channels/base/packages/README.md @@ -0,0 +1,130 @@ +# channels/base/packages/ + +Source package definitions for UNOS, one directory per package. This is the +`base` layer; `../../lts`, `../../stable` and `../../edge` overlay it. See +`mk/README.md` for how channels compose. + +Layout follows the Void Linux convention: + +``` +channels/<layer>/packages/<pkgname>/ +|-- template # shell-sourced build definition (required) +|-- patches/ # optional, applied in sorted order +`-- files/ # optional, static files referenced by the template +``` + +A `template` is a shell fragment, not a script: it declares variables and +optionally overrides `do_*` phases: + +```sh +pkgname=example +version=1.0.0 +revision=1 +build_style=gnu-configure +hostmakedepends="pkg-config" +makedepends="libfoo-devel" +short_desc="One-line description" +maintainer="..." +license="BSD-3-Clause" +homepage="https://example.org" +distfiles="https://example.org/example-${version}.tar.gz" +checksum=<sha256> +``` + +Templates are built by our own driver (local now, CI later) into a signed +apk repository (v2 artifacts, apk-tools v3 manager). Nothing in this +directory is ever built by hand on a target switch. + +## Rules + +- **Declare build dependencies.** `makedepends` lists other UNOS packages whose + headers/libs must be in `build/sysroot` before this one compiles; + `hostmakedepends` lists commands that must exist on the build host. Both are + enforced by `mk/build.sh` before anything is fetched, and `makedepends` is + what `mk/deps.sh` uses to compute build order. Keep them accurate in both + directions: a missing entry breaks a clean-checkout build, and a spurious one + fails a build that would otherwise work. `depends` is runtime only and does + **not** affect build order, so a package needed at both times appears twice + (see `gptfdisk`). +- **Pin everything.** Explicit versions and recorded checksums. No moving + targets, no floating branches. +- **Third-party source uses `distfiles=` and must carry `checksum=`.** The + driver refuses to build a template that sets `distfiles` without a matching + sha256, because there we are trusting a server nobody here controls. +- **Our own source uses `srcfiles=` and carries no checksum.** It is fetched by + tag from `git.finwo.net`; the tag is the pin and TLS is the transport. A + forge regenerates tag archives on demand, so they are not byte-stable and a + recorded sha256 would eventually fail for reasons indistinguishable from + tampering. Setting `checksum=` alongside `srcfiles=` is an error, as is + setting both `srcfiles=` and `distfiles=` -- whichever is present supplies + the tarball `WRKSRC` is derived from, and two sources would make that choice + silent and arbitrary. Only `linkd` uses this today. +- **Never vendor upstream source into this repository.** Sources are fetched at + build time from a pinned revision. This keeps history small and keeps our + licensing story unambiguous. +- **Preserve vendor notices.** Templates that patch third-party code must not + strip copyright headers. This is a binding condition of the Broadcom SDK + licence, and stripping headers is the single easiest way to breach it. +- **Kernel-coupled packages must rebuild with the kernel.** Anything producing + a `.ko` has to be rebuilt whenever the `linux` package changes; a stale module + fails at `insmod` time on the switch, which is the worst possible place to + find out. +- **Shared-only C libraries.** Nothing in UNOS links statically, so library + templates pass `--disable-static` (or equivalent) and must not ship `.a` + files. Keep the rootfs lean; revisit only if a static-link need appears. +- **Build-time sysroot (`build/sysroot`, generated, never committed).** + Libraries that other packages build against install twice: once into + `DESTDIR` (the shipped `.apk`) and once into `SYSROOT` (headers + `.so` + + `.pc` files). The driver exports `SYSROOT` and `UNOS_MKDIR` (the mk/ + directory - never `MKDIR`, which collides with libtool's internal + `$MKDIR`), prepends `build/host/bin` (host tools like muon) to `PATH`, + and points `PKG_CONFIG_PATH` at the sysroot. The driver centrally + rewrites every sysroot `.pc` after `do_install` (all of `prefix=`, + `libdir=`, `includedir` to `${SYSROOT}/usr` paths) - hand-rolled + per-template `sed` of only `prefix=` is insufficient (efivar's + `libdir=/includedir=` are literal, not `${prefix}`-relative, so a + prefix-only rewrite left consumers on host `/usr/include`). Templates + only double-install and assert presence; the driver fixes the paths. + efivar additionally patches its `.pc.in` before generation to expose + both `-I${includedir}` and `-I${includedir}/efivar` (upstream only + ships the subdir, which relies on host `/usr/include` as an implicit + search path - absent in a sysroot). +- **Loader cache is generated, never shipped.** The loader's baked-in + search covers `/lib64` + `/usr/lib64` only, so every library package + carries a `files/post-install` running `exec /sbin/ldconfig` (absolute: + glibc installs it to `/sbin`, and the busybox applet is compiled out). + Script-bearing packages order themselves with `depends="glibc busybox"` + (`/bin/sh` must exist before apk runs their scripts). `mk/rootfs.sh` + additionally runs `ldconfig` explicitly after assembly so the chroot + cache never depends on script-execution order. +- **Subpackages: one template, several .apks.** A template may declare + `subpackages="name ..."` with per-sub `short_desc_<underscored>` / + `depends_<underscored>` (provides/replaces optional) and a + `sub_<underscored>()` function partitioning `DESTDIR` into `SUBDEST` + via `spick` (move semantics - never duplicated). Per-subpackage control + scripts live at `files/<script>.<subname>` (e.g. + `post-install.linux`). After all splits `DESTDIR` must be empty: the + primary packs the remainder, so meta primaries are empty by + construction. Version pins between outputs must carry the full pkgver + incl. `-r` (`depends="linux=${version}-r${revision}"`) - apk's `=` + never matches a bare version. Single-output templates are unaffected. +- **Control scripts run chrooted via memfd.** apk v3 executes scripts + through `/proc/self/fd`, so any `apk add` that runs scripts needs + `/proc` mounted in the target (live systems always have it; + `mk/rootfs.sh` binds it for assembly; the installer must too). +- **Kernel image symlink.** `mk/kernel.inc` installs both + `/boot/vmlinuz-${KREL}` and `/boot/vmlinuz -> vmlinuz-${KREL}`; the + static `grub.cfg` references the generic path. Older images had only + the versioned name - the installer creates the symlink idempotently + after unpacking rootfs, so both old and new images boot. +- **GRUB is UEFI-only in this tree.** `grub` builds + `x86_64-efi` only; `i386-pc` fails under binutils 2.44 (mislinked + `kernel.img` `.text` at 0x9074 vs 0x9000, `grub-mkimage` fail-louds). + The installer dies on BIOS firmware with a clear message; revisit + when binutils is fixed or upstream works around it. The grub package + prunes `grub-mkconfig` - the static `grub.cfg` is rendered by the + installer and checked with shipped `grub-script-check`. +- **Host-independence.** `iproute2` scrubs autotools-appended optionals + (`HAVE_ELF` etc.) and asserts `NEEDED` is subset of {libmnl,libcap,libc}; `grub` + trims freetype/tasn1/fuse/zfs/dm; all `CPPFLAGS/LDFLAGS` are + sysroot-first. A build must not silently pick up host libraries. diff --git a/channels/base/packages/apk-tools/template b/channels/base/packages/apk-tools/template @@ -0,0 +1,55 @@ +# Template file for 'apk-tools' +pkgname=apk-tools +version=3.0.8 +revision=1 +short_desc="Package manager for apk packages" +maintainer="finwo <finwo@pm.me>" +license="GPL-2.0-only" +homepage="https://gitlab.alpinelinux.org/alpine/apk-tools" +distfiles="https://gitlab.alpinelinux.org/alpine/apk-tools/-/archive/v3.0.8/apk-tools-v3.0.8.tar.gz" +checksum=e81c64a6e7c3806d45d4622c253e757aee970be84048554fa0eed79310e9453e +depends="glibc zlib openssl" +makedepends="glibc zlib openssl linux-headers" +hostmakedepends="muon" + +# Notes: +# - Same version the host manager was built from (v3.0.8); target and host +# stay on one version until there is a reason to diverge. +# - muon (build/host/bin, on PATH via the driver) configures and builds via +# its vendored samurai, so no ninja on the host; out-of-tree in +# ${WORK}/build, DESTDIR install. +# - url_backend=libfetch (in-tree, no extra package) over wget; crypto +# openssl (zlib + openssl come from the sysroot via PKG_CONFIG_PATH). +# - Disabled: docs (needs host scdoc), help/lua/python (needs lua/python), +# tests (CI runs upstream's suite, not the target build), zstd (no zstd +# package; our artifacts are gzip). No on-device man pages or embedded +# help DB yet - revisit when the operator story needs them. + +do_configure() { + mkdir -p "${WORK}/build" + cd "${WRKSRC}" + # --sysroot: sysroot glibc headers redirect to __isoc23_*, absent in host + # libc. Nothing from the host's /usr/include may mix in, so the kernel UAPI + # headers come from linux-headers in the sysroot. + export CFLAGS="${CFLAGS:-} --sysroot=${SYSROOT}" + export LDFLAGS="${LDFLAGS:-} --sysroot=${SYSROOT} -L${SYSROOT}/usr/lib -Wl,-rpath-link,${SYSROOT}/usr/lib" + muon setup \ + -Dprefix=/usr \ + -Ddocs=disabled \ + -Dhelp=disabled \ + -Dlua=disabled \ + -Dpython=disabled \ + -Dtests=disabled \ + -Dzstd=disabled \ + -Durl_backend=libfetch \ + -Dcrypto_backend=openssl \ + "${WORK}/build" +} + +do_build() { + muon -C "${WORK}/build" samu +} + +do_install() { + DESTDIR="${DESTDIR}" muon -C "${WORK}/build" install +} diff --git a/packages/base-files/files/fstab b/channels/base/packages/base-files/files/fstab diff --git a/packages/base-files/files/group b/channels/base/packages/base-files/files/group diff --git a/packages/base-files/files/hostname b/channels/base/packages/base-files/files/hostname diff --git a/packages/base-files/files/hosts b/channels/base/packages/base-files/files/hosts diff --git a/packages/base-files/files/inittab b/channels/base/packages/base-files/files/inittab diff --git a/packages/base-files/files/ld.so.conf b/channels/base/packages/base-files/files/ld.so.conf diff --git a/packages/base-files/files/linkd.cnf b/channels/base/packages/base-files/files/linkd.cnf diff --git a/packages/base-files/files/network/interfaces b/channels/base/packages/base-files/files/network/interfaces diff --git a/packages/base-files/files/network/ports b/channels/base/packages/base-files/files/network/ports diff --git a/packages/base-files/files/nsswitch.conf b/channels/base/packages/base-files/files/nsswitch.conf diff --git a/packages/base-files/files/os-release b/channels/base/packages/base-files/files/os-release diff --git a/packages/base-files/files/passwd b/channels/base/packages/base-files/files/passwd diff --git a/packages/base-files/files/profile b/channels/base/packages/base-files/files/profile diff --git a/packages/base-files/files/rcS b/channels/base/packages/base-files/files/rcS diff --git a/packages/base-files/files/shadow b/channels/base/packages/base-files/files/shadow diff --git a/packages/base-files/files/shells b/channels/base/packages/base-files/files/shells diff --git a/packages/base-files/template b/channels/base/packages/base-files/template diff --git a/packages/busybox/template b/channels/base/packages/busybox/template diff --git a/packages/curl/files/post-install b/channels/base/packages/curl/files/post-install diff --git a/packages/curl/template b/channels/base/packages/curl/template diff --git a/packages/dosfstools/template b/channels/base/packages/dosfstools/template diff --git a/packages/e2fsprogs/files/post-install b/channels/base/packages/e2fsprogs/files/post-install diff --git a/packages/e2fsprogs/template b/channels/base/packages/e2fsprogs/template diff --git a/packages/efibootmgr/template b/channels/base/packages/efibootmgr/template diff --git a/packages/efivar/files/post-install b/channels/base/packages/efivar/files/post-install diff --git a/packages/efivar/template b/channels/base/packages/efivar/template diff --git a/packages/glibc/files/post-install b/channels/base/packages/glibc/files/post-install diff --git a/packages/glibc/template b/channels/base/packages/glibc/template diff --git a/packages/gptfdisk/template b/channels/base/packages/gptfdisk/template diff --git a/packages/grub/template b/channels/base/packages/grub/template diff --git a/packages/iproute2/template b/channels/base/packages/iproute2/template diff --git a/packages/libcap/files/post-install b/channels/base/packages/libcap/files/post-install diff --git a/packages/libcap/template b/channels/base/packages/libcap/template diff --git a/packages/libmnl/files/post-install b/channels/base/packages/libmnl/files/post-install diff --git a/packages/libmnl/template b/channels/base/packages/libmnl/template diff --git a/packages/libstdc++/files/post-install b/channels/base/packages/libstdc++/files/post-install diff --git a/packages/libstdc++/template b/channels/base/packages/libstdc++/template diff --git a/packages/linkd/files/linkd-check b/channels/base/packages/linkd/files/linkd-check diff --git a/packages/linkd/files/linkd-log-run b/channels/base/packages/linkd/files/linkd-log-run diff --git a/packages/linkd/files/linkd-run b/channels/base/packages/linkd/files/linkd-run diff --git a/packages/linkd/template b/channels/base/packages/linkd/template diff --git a/packages/linux-longterm/files/post-install.linux b/channels/base/packages/linux/files/post-install diff --git a/channels/base/packages/linux/template b/channels/base/packages/linux/template @@ -0,0 +1,38 @@ +# Template file for 'linux' +# +# One template, two outputs: +# linux image + modules + maps (post-install: depmod) +# linux-headers sanitized headers_install (user API only - NOT a +# module-build tree; openbcm needs a follow-up, see +# mk/kernel.inc) +# +# Exactly one layer of a composed channel provides this template, so the +# kernel line is a property of the channel you track, not of the package +# name. Everything except the pin lives in mk/kernel.inc. +pkgname=linux +version=6.18.51 +revision=1 +short_desc="Linux kernel image and modules" +maintainer="finwo <finwo@pm.me>" +license="GPL-2.0-only" +homepage="https://www.kernel.org" +distfiles="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.51.tar.xz" +checksum=ba2f60f858bf4d1f929101faa356c93dc8b925b17aaa9f95eabd4627758df613 +# busybox first: post-install runs depmod under /bin/sh +depends="busybox" +hostmakedepends="bc flex bison rsync depmod" +subpackages="linux-headers" + +short_desc_linux_headers="Linux kernel sanitized headers" +depends_linux_headers= + +# shellcheck disable=SC1091 +. "${UNOS_MKDIR}/kernel.inc" + +do_configure() { kernel_configure; } +do_build() { kernel_build; } +do_install() { kernel_install; } + +sub_linux_headers() { + spick usr/include +} diff --git a/packages/openssl/files/post-install b/channels/base/packages/openssl/files/post-install diff --git a/packages/openssl/template b/channels/base/packages/openssl/template diff --git a/packages/popt/files/post-install b/channels/base/packages/popt/files/post-install diff --git a/packages/popt/template b/channels/base/packages/popt/template diff --git a/packages/smartmontools/template b/channels/base/packages/smartmontools/template diff --git a/packages/tinyssh/files/tinyssh-check b/channels/base/packages/tinyssh/files/tinyssh-check diff --git a/packages/tinyssh/files/tinyssh-log-run b/channels/base/packages/tinyssh/files/tinyssh-log-run diff --git a/packages/tinyssh/files/tinyssh-run b/channels/base/packages/tinyssh/files/tinyssh-run diff --git a/packages/tinyssh/template b/channels/base/packages/tinyssh/template diff --git a/packages/unos-firstboot/files/unos-firstboot b/channels/base/packages/unos-firstboot/files/unos-firstboot diff --git a/packages/unos-firstboot/template b/channels/base/packages/unos-firstboot/template diff --git a/packages/unos-keys/files/apk/unos-ci-62a2ab39@rtr.rsa.pub b/channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@rtr.rsa.pub diff --git a/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat06.rsa.pub b/channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat06.rsa.pub diff --git a/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat07.rsa.pub b/channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat07.rsa.pub diff --git a/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat13.rsa.pub b/channels/base/packages/unos-keys/files/apk/unos-ci-62a2ab39@sat13.rsa.pub diff --git a/packages/unos-keys/files/apk/unos-dev@finwo.dev-096b7b41.rsa.pub b/channels/base/packages/unos-keys/files/apk/unos-dev@finwo.dev-096b7b41.rsa.pub diff --git a/packages/unos-keys/files/unos/unos-ci-62a2ab39@rtr.ed25519.pub b/channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@rtr.ed25519.pub diff --git a/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat06.ed25519.pub b/channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat06.ed25519.pub diff --git a/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat07.ed25519.pub b/channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat07.ed25519.pub diff --git a/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat13.ed25519.pub b/channels/base/packages/unos-keys/files/unos/unos-ci-62a2ab39@sat13.ed25519.pub diff --git a/packages/unos-keys/files/unos/unos-dev@finwo.dev-6a2764d4.ed25519.pub b/channels/base/packages/unos-keys/files/unos/unos-dev@finwo.dev-6a2764d4.ed25519.pub diff --git a/packages/unos-keys/template b/channels/base/packages/unos-keys/template diff --git a/packages/xz/files/post-install b/channels/base/packages/xz/files/post-install diff --git a/packages/xz/template b/channels/base/packages/xz/template diff --git a/packages/zlib/files/post-install b/channels/base/packages/zlib/files/post-install diff --git a/packages/zlib/template b/channels/base/packages/zlib/template diff --git a/channels/edge/channel.conf b/channels/edge/channel.conf @@ -0,0 +1 @@ +upstream=stable diff --git a/packages/linux-mainline/files/post-install.linux b/channels/edge/packages/linux/files/post-install diff --git a/channels/edge/packages/linux/template b/channels/edge/packages/linux/template @@ -0,0 +1,30 @@ +# Template file for 'linux' - mainline snapshot +# +# TOFU pin: git.kernel.org publishes no sha256 for torvalds snapshots, only +# .tar.sign PGP. Re-pin every bump and verify the tag out of band. +pkgname=linux +version=7.3_rc3 +revision=1 +short_desc="Linux kernel image and modules" +maintainer="finwo <finwo@pm.me>" +license="GPL-2.0-only" +homepage="https://www.kernel.org" +distfiles="https://git.kernel.org/torvalds/t/linux-7.3-rc3.tar.gz" +checksum=49b24119d7b92da75bba0daf5da4f7735c8cb948757a282e849092dcc681d8dd +depends="busybox" +hostmakedepends="bc flex bison rsync depmod" +subpackages="linux-headers" + +short_desc_linux_headers="Linux kernel sanitized headers" +depends_linux_headers= + +# shellcheck disable=SC1091 +. "${UNOS_MKDIR}/kernel.inc" + +do_configure() { kernel_configure; } +do_build() { kernel_build; } +do_install() { kernel_install; } + +sub_linux_headers() { + spick usr/include +} diff --git a/channels/lts/channel.conf b/channels/lts/channel.conf @@ -0,0 +1 @@ +upstream=base diff --git a/channels/stable/channel.conf b/channels/stable/channel.conf @@ -0,0 +1 @@ +upstream=lts diff --git a/packages/linux-stable/files/post-install.linux b/channels/stable/packages/linux/files/post-install diff --git a/channels/stable/packages/linux/template b/channels/stable/packages/linux/template @@ -0,0 +1,27 @@ +# Template file for 'linux' - stable line +pkgname=linux +version=7.2.5 +revision=1 +short_desc="Linux kernel image and modules" +maintainer="finwo <finwo@pm.me>" +license="GPL-2.0-only" +homepage="https://www.kernel.org" +distfiles="https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.2.5.tar.xz" +checksum=55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78 +depends="busybox" +hostmakedepends="bc flex bison rsync depmod" +subpackages="linux-headers" + +short_desc_linux_headers="Linux kernel sanitized headers" +depends_linux_headers= + +# shellcheck disable=SC1091 +. "${UNOS_MKDIR}/kernel.inc" + +do_configure() { kernel_configure; } +do_build() { kernel_build; } +do_install() { kernel_install; } + +sub_linux_headers() { + spick usr/include +} diff --git a/mk/README.md b/mk/README.md @@ -1,19 +1,43 @@ # mk/ -UNOS package driver: `packages/<name>/template` in, signed `.apk` (v2) out. -The whole of `build/` is generated output. Only `mk/` is source. +UNOS package driver: `channels/<layer>/packages/<name>/template` in, signed +`.apk` (v2) out. The whole of `build/` is generated output. + +## Channels + +Packages live in layers under `channels/`. Each channel declares its parent in +`channel.conf` (`upstream=`), and composing a channel means applying every +layer from the root down, replacing whole package directories. `publish=no` +marks a layer that is never built in CI and never uploaded. + + base publish=no, the foundation + lts upstream=base + stable upstream=lts + edge upstream=stable + +`channel-assemble.sh <channel>` writes the composed tree to +`build/channels/<channel>/packages`, which is what every other script reads. +Published at `apk/<channel>/<arch>/`; there is no `base` in the bucket. + +Promoting a package between channels is a `git mv`, never a copy -- +`channel-lint.sh` fails the build on a layer identical to the one it shadows, +because such a layer silently stops tracking its upstream forever. ## Files +- `channels.inc` -- chain resolution and repo path layout. Sourced, not run. +- `channel-assemble.sh <channel>` -- compose a channel's package tree. +- `channel-lint.sh` -- reject dead overlays. - `bootstrap-host.sh [--check|--force]` -- builds the host tools in `build/host/bin` from pinned, checksummed tarballs: `muon` (bootstrapped from a single amalgamated C file, so the chain terminates at a C compiler) and `apk`. `--check` verifies presence *and version* and is the gate CI should run first. Everything else assumes these exist. -- `deps.sh {list|vars|graph|order|rdeps|changed|check}` -- the build-dependency - graph, read from each template's `makedepends`. `order` is a topological - sort; `check` validates it (dangling deps, self-deps, cycles, missing - hostmakedepends). +- `deps.sh [--channel <c>] {list|vars|graph|order|rdeps|changed|check|seed|owner| + subpkgs|pkgver|rtdeps|channels|layers}` -- the build-dependency graph, read + from each template's `makedepends`. `order` is a topological sort; `check` + validates it (dangling deps, self-deps, cycles, missing hostmakedepends). + Defaults to `$UNOS_CHANNEL`, then `lts`. - `gen-pipeline.sh [--write|--check]` -- emits `.conductor.yml` from that graph. The pipeline is data (the conductor will not run repository code to build its task graph), so the per-package `needs` edges must be written out @@ -54,7 +78,7 @@ The whole of `build/` is generated output. Only `mk/` is source. - `keymgmt.sh` -- key management: `new [--type rsa|supercop] [--for apk|unos] <stem>` generates `<stem>-<8 hex>` in `~/.unos-keys/` (rsa: 4096-bit; supercop: ed25519) and stages the public half into - `packages/unos-keys/files/<for>/`; `use <name|file>` pins the package + `channels/base/packages/unos-keys/files/<for>/`; `use <name|file>` pins the package signing key by writing its full path to `.sign-key` (never committed; CI sets `UNOS_SIGN_KEY` or writes `.sign-key` itself); `list` shows local keys and marks the active one. apk mandates RSA -- supercop-for-apk is refused. @@ -89,7 +113,7 @@ package; v2 requires the on-disk filename to equal the key name embedded in `.SIGN.RSA.<name>.rsa.pub`, which the driver guarantees by construction. Key ceremony: private halves live only in `~/.unos-keys/`. Public halves are -committed by `keymgmt.sh new` under `packages/unos-keys/files/<for>/` (public +committed by `keymgmt.sh new` under `channels/base/packages/unos-keys/files/<for>/` (public by design) and installed by that package -- `files/apk/*` to `/etc/apk/keys/`, `files/unos/*` to `/etc/unos/keys/`. Rotation = generate, commit the new `.pub` files, bump the `unos-keys` version. @@ -167,7 +191,7 @@ byte-identical rootfs with the dynamic binary. Building it cost 10.6MB against required `libcrypto.a`/`libssl.a`/`libz.a`/`libzstd.a` on the build host -- static libraries that most CI containers do not ship, turning a cosmetic preference into a hard bootstrap failure. If a static apk is ever wanted for -recovering a switch with a broken loader, it belongs in `packages/` as a target +recovering a switch with a broken loader, it belongs in `channels/` as a target artifact. Muon itself is pinned: v0.6.0, diff --git a/mk/bootstrap-repo.sh b/mk/bootstrap-repo.sh @@ -9,16 +9,25 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) -ARCH="${ARCH:-x86_64}" -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +CHANNEL="${UNOS_CHANNEL:-lts}" +case "${1:-}" in + --channel) CHANNEL="${2:?--channel needs a value}"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; +esac + +ARCH=$(chan_arch "${ARCH:-x86_64}") +PREFIX=$(chan_prefix "${CHANNEL}" "${ARCH}") for v in BUCKET_ACCESS_KEY BUCKET_SECRET_KEY BUCKET_NAME BUCKET_ENDPOINT BUCKET_REGION BUCKET_PUBLIC_URL; 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" -public_url="${BUCKET_PUBLIC_URL%/}/${ARCH}/APKINDEX.tar.gz" +url="${BUCKET_ENDPOINT%/}/${BUCKET_NAME}/${PREFIX}/APKINDEX.tar.gz" +public_url=$(chan_url "${BUCKET_PUBLIC_URL}" "${CHANNEL}" "${ARCH}" APKINDEX.tar.gz) tmp_body=$(mktemp) code=$(curl -sS -o "${tmp_body}" -w '%{http_code}' \ --aws-sigv4 "aws:amz:${BUCKET_REGION}:s3" \ @@ -29,16 +38,17 @@ code=$(curl -sS -o "${tmp_body}" -w '%{http_code}' \ case "${code}" in 2*) rm -f "${tmp_body}" anon_code=$(curl -sS -o /dev/null -w '%{http_code}' "${public_url}") || anon_code=000 - case "${anon_code}" in 2*) echo "==> repo already has ${ARCH}/APKINDEX.tar.gz (${code}, anon ${anon_code}), nothing to do"; exit 0 ;; *) echo "==> repo has ${ARCH}/APKINDEX.tar.gz but public fetch is ${anon_code}, re-publishing" ;; esac + case "${anon_code}" in 2*) echo "==> repo already has ${PREFIX}/APKINDEX.tar.gz (${code}, anon ${anon_code}), nothing to do"; exit 0 ;; *) echo "==> repo has ${PREFIX}/APKINDEX.tar.gz but public fetch is ${anon_code}, re-publishing" ;; esac ;; - 404) rm -f "${tmp_body}"; echo "==> no ${ARCH}/APKINDEX.tar.gz (404), bootstrapping empty index" ;; + 404) rm -f "${tmp_body}"; echo "==> no ${PREFIX}/APKINDEX.tar.gz (404), bootstrapping empty index" ;; 000) echo "bootstrap-repo.sh: could not reach ${url} (curl failed)" >&2; cat "${tmp_body}" >&2 2>/dev/null || true; rm -f "${tmp_body}"; exit 1 ;; 400) echo "bootstrap-repo.sh: bad request (400) for ${url} -- check BUCKET_ENDPOINT/BUCKET_NAME/BUCKET_REGION" >&2; echo "--- S3 response ---" >&2; cat "${tmp_body}" >&2 2>/dev/null || true; echo "--- env ---" >&2; echo "ENDPOINT=${BUCKET_ENDPOINT} NAME=${BUCKET_NAME} REGION=${BUCKET_REGION}" >&2; rm -f "${tmp_body}"; exit 1 ;; 403) echo "bootstrap-repo.sh: permission denied (403) for ${url} -- check BUCKET credentials/region" >&2; echo "--- S3 response ---" >&2; cat "${tmp_body}" >&2 2>/dev/null || true; rm -f "${tmp_body}"; exit 1 ;; *) echo "bootstrap-repo.sh: unexpected HTTP ${code} for ${url}" >&2; cat "${tmp_body}" >&2 2>/dev/null || true; rm -f "${tmp_body}"; exit 1 ;; esac -mkdir -p "${ROOT}/build/repo/${ARCH}" +REPODIR=$(chan_repodir "${CHANNEL}" "${ARCH}") +mkdir -p "${REPODIR}" 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; } @@ -51,7 +61,7 @@ if [ ! -x "${HERE}/pax-tar" ] || [ "${HERE}/pax-tar.c" -nt "${HERE}/pax-tar" ]; cc -std=c99 -O2 -Wall -Wextra -o "${HERE}/pax-tar" "${HERE}/pax-tar.c" fi -cd "${ROOT}/build/repo/${ARCH}" +cd "${REPODIR}" # apk index with no inputs still needs to produce a valid archive; # `echo` avoids the shell expanding *.apk to a literal when empty. @@ -89,7 +99,7 @@ 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" +echo "==> publishing ${PREFIX}/APKINDEX.tar.gz" sha=$(sha256sum APKINDEX.tar.gz | cut -d' ' -f1) tmp_put=$(mktemp) code=$(curl -sS -o "${tmp_put}" -w '%{http_code}' \ @@ -98,4 +108,4 @@ code=$(curl -sS -o "${tmp_put}" -w '%{http_code}' \ -H "x-amz-content-sha256: ${sha}" \ -X PUT --upload-file APKINDEX.tar.gz \ "${url}") || { echo "bootstrap-repo.sh: upload failed" >&2; cat "${tmp_put}" >&2 2>/dev/null || true; rm -f "${tmp_put}"; exit 1; } -case "${code}" in 2*) rm -f "${tmp_put}"; echo "==> bootstrapped ${ARCH}/APKINDEX.tar.gz (${code})" ;; *) echo "bootstrap-repo.sh: upload returned HTTP ${code}" >&2; cat "${tmp_put}" >&2 2>/dev/null || true; rm -f "${tmp_put}"; exit 1 ;; esac +case "${code}" in 2*) rm -f "${tmp_put}"; echo "==> bootstrapped ${PREFIX}/APKINDEX.tar.gz (${code})" ;; *) echo "bootstrap-repo.sh: upload returned HTTP ${code}" >&2; cat "${tmp_put}" >&2 2>/dev/null || true; rm -f "${tmp_put}"; exit 1 ;; esac diff --git a/mk/build-all.sh b/mk/build-all.sh @@ -17,22 +17,30 @@ ROOT=$(cd "${HERE}/.." && pwd) DRY=0 SKIP=0 +# shellcheck disable=SC1091 +. "${ROOT}/mk/channels.inc" + ARCH="x86_64" PKGS="" +CHANNEL="${UNOS_CHANNEL:-lts}" for a in "$@"; do case "$a" in --dry-run) DRY=1 ;; --skip-built) SKIP=1 ;; --arch) ARCH="$2"; shift 2; continue ;; --arch=*) ARCH="${a#--arch=}"; continue ;; + --channel) CHANNEL="$2"; shift 2; continue ;; + --channel=*) CHANNEL="${a#--channel=}"; continue ;; -h|--help) sed -n '2,10p' "$0"; exit 0 ;; -*) echo "build-all.sh: unknown option: $a" >&2; exit 1 ;; *) PKGS="${PKGS} $a" ;; esac done -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) die "unsupported ARCH: ${ARCH}" >&2; exit 1 ;; esac export ARCH +export UNOS_CHANNEL="${CHANNEL}" +REPODIR=$(chan_repodir "${CHANNEL}" "${ARCH}") msg() { printf '==> %s\n' "$*"; } die() { printf 'build-all.sh: error: %s\n' "$*" >&2; exit 1; } @@ -56,7 +64,7 @@ skipped=0 for p in ${ORDER}; do n=$((n + 1)) - if [ "${SKIP}" = "1" ] && ls "${ROOT}/build/repo/${ARCH}/${p}"-*.apk >/dev/null 2>&1; then + if [ "${SKIP}" = "1" ] && ls "${REPODIR}/${p}"-*.apk >/dev/null 2>&1; then msg "[${n}/${total}] ${p}: already built, skipping" skipped=$((skipped + 1)) continue diff --git a/mk/build.sh b/mk/build.sh @@ -11,9 +11,21 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) -PKG="${1:?usage: build.sh <pkgname>}" -TEMPLATE="${ROOT}/packages/${PKG}/template" +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +CHANNEL="${UNOS_CHANNEL:-lts}" +case "${1:-}" in + --channel) CHANNEL="${2:?--channel needs a value}"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; +esac +export UNOS_CHANNEL="${CHANNEL}" + +PKG="${1:?usage: build.sh [--channel <c>] <pkgname>}" +PKGDIR=$(chan_pkgdir "${CHANNEL}") + +TEMPLATE="${PKGDIR}/${PKG}/template" [ -f "${TEMPLATE}" ] || { echo "build.sh: no template: ${TEMPLATE}" >&2; exit 1; } # --- template variables (defaults; the template overrides) --- @@ -45,8 +57,8 @@ provides= replaces= subpackages= -FILESDIR="${ROOT}/packages/${PKG}/files" -WORK="${ROOT}/build/work/${PKG}" +FILESDIR="${PKGDIR}/${PKG}/files" +WORK="${ROOT}/build/work/${CHANNEL}/${PKG}" SRCDEST="${ROOT}/build/work/sources" DESTDIR="${WORK}/dest" WRKSRC= @@ -59,7 +71,7 @@ export UNOS_MKDIR # packages build against install twice - once into DESTDIR (the shipped # .apk) and once into SYSROOT (headers + .so + prefix-fixed .pc files). # Consumers find it via PKG_CONFIG_PATH; host tools (muon) via PATH. -SYSROOT="${ROOT}/build/sysroot" +SYSROOT= # --- helpers available to templates --- msg() { printf '==> %s\n' "$*"; } @@ -89,9 +101,10 @@ if [ $# -ge 2 ]; then else ARCH="${ARCH:-x86_64}" fi -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) die "unsupported ARCH: ${ARCH} (want x86_64 or aarch64)" ;; esac -OUTDIR="${ROOT}/build/repo/${ARCH}" +OUTDIR=$(chan_repodir "${CHANNEL}" "${ARCH}") +SYSROOT=$(chan_sysroot "${CHANNEL}" "${ARCH}") export ARCH mkdir -p "${SRCDEST}" "${WORK}" "${OUTDIR}" "${SYSROOT}" @@ -113,7 +126,7 @@ done for _m in ${makedepends}; do "${HERE}/deps.sh" owner "${_m}" >/dev/null 2>&1 \ - || die "makedepends: '${_m}' is not a package or subpackage under packages/" + || die "makedepends: '${_m}' is not a package or subpackage in channel '${CHANNEL}'" # Presence of a built .apk is the signal that its sysroot seed has been # installed; templates that other packages build against install twice # (DESTDIR + SYSROOT), so one implies the other. @@ -145,7 +158,7 @@ done if [ "${UNOS_ALLOW_OVERWRITE:-0}" != "1" ]; then if [ -f "${OUTDIR}/${pkgname}-${PKGVER}.apk" ]; then die "${pkgname}-${PKGVER}.apk already exists in ${OUTDIR}/ - bump revision in packages/${PKG}/template before rebuilding + bump revision in ${PKG}'s template before rebuilding (or UNOS_ALLOW_OVERWRITE=1 ./mk/build.sh ${PKG} to overwrite locally)" fi fi @@ -212,7 +225,7 @@ if [ -n "${distfiles}" ] || [ -n "${srcfiles}" ]; then else WRKSRC=${WORK}/src fi - for p in "${ROOT}/packages/${PKG}"/patches/*.patch; do + for p in "${PKGDIR}/${PKG}"/patches/*.patch; do [ -e "${p}" ] || break msg "applying $(basename "${p}")" patch -d "${WRKSRC}" -p1 --no-backup-if-mismatch -i "${p}" @@ -356,9 +369,9 @@ emit_apk() { # Template declares: subpackages="name ..." (hyphens fine), per-sub # short_desc_<underscored>/depends_<underscored> (provides/replaces optional), # and sub_<underscored>() splitting DESTDIR into SUBDEST via spick (move -# semantics: the tree is partitioned, never duplicated). After all splits -# DESTDIR must be empty - the primary packs the remainder, so for meta -# primaries this asserts the meta carries no files by construction. +# semantics: the tree is partitioned, never duplicated). Whatever no subpackage +# claimed stays with the primary; it is logged rather than asserted empty, +# because a typo'd spick path is visible in that line. if [ -n "${subpackages}" ]; then for _sub in ${subpackages}; do _u=$(printf '%s' "${_sub}" | tr '-' '_') @@ -379,7 +392,7 @@ if [ -n "${subpackages}" ]; then emit_apk "${WORK}/split/${_sub}" "${_sub}" "${_sd}" "${_dd}" "${_pv}" "${_rp}" "${_sub}" done if [ -n "$(ls -A "${DESTDIR}")" ]; then - die "unpartitioned files remain for primary ${pkgname}: $(ls -A "${DESTDIR}" | head)" + msg "${pkgname}: primary keeps $(ls -A "${DESTDIR}" | tr '\n' ' ')" fi fi diff --git a/mk/channel-assemble.sh b/mk/channel-assemble.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# mk/channel-assemble.sh - compose a channel's package tree from its chain. +# +# ./mk/channel-assemble.sh <channel> -> build/channels/<channel>/packages +# +# Layers replace whole package directories rather than merging file by file, so +# a stale patch or files/ entry cannot survive underneath a bumped template. +set -eu + +HERE=$(cd "$(dirname "$0")" && pwd) +ROOT=$(cd "${HERE}/.." && pwd) + +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +CHANNEL="${1:?usage: channel-assemble.sh <channel>}" + +OUT=$(chan_pkgdir "${CHANNEL}") +rm -rf "${OUT}" +mkdir -p "${OUT}" + +for layer in $(chan_layers "${CHANNEL}"); do + src="${CHANDIR}/${layer}/packages" + [ -d "${src}" ] || continue + for pkg in "${src}"/*/; do + [ -d "${pkg}" ] || continue + name=$(basename "${pkg}") + rm -rf "${OUT}/${name}" + cp -R "${pkg}" "${OUT}/${name}" + done + for extra in "${src}"/*.md; do + [ -f "${extra}" ] && cp "${extra}" "${OUT}/" + done +done + +printf '==> channel %s: %s packages from [%s]\n' \ + "${CHANNEL}" \ + "$(find "${OUT}" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')" \ + "$(chan_layers "${CHANNEL}" | tr '\n' ' ' | sed 's/ $//')" diff --git a/mk/channel-lint.sh b/mk/channel-lint.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# mk/channel-lint.sh - reject dead overlays. +# +# A layer carrying a package identical to the one it shadows wins forever and +# stops tracking its upstream. That is what a graduation done by copy instead +# of git mv leaves behind, and nothing else in the build would notice. +set -eu + +HERE=$(cd "$(dirname "$0")" && pwd) +ROOT=$(cd "${HERE}/.." && pwd) + +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +rc=0 + +for d in "${CHANDIR}"/*/; do + channel=$(basename "${d}") + chan_exists "${channel}" || continue + upstream=$(chan_conf "${channel}" upstream) + [ -n "${upstream}" ] || continue + + for pkg in "${d}packages"/*/; do + [ -d "${pkg}" ] || continue + name=$(basename "${pkg}") + + shadowed= + for layer in $(chan_layers "${upstream}"); do + [ -d "${CHANDIR}/${layer}/packages/${name}" ] \ + && shadowed="${CHANDIR}/${layer}/packages/${name}" + done + [ -n "${shadowed}" ] || continue + + if diff -r -q "${shadowed}" "${pkg}" >/dev/null 2>&1; then + printf 'channel-lint: %s/packages/%s is identical to %s\n' \ + "${channel}" "${name}" \ + "$(basename "$(dirname "$(dirname "${shadowed}")")")" >&2 + rc=1 + fi + done +done + +[ "${rc}" = 0 ] && printf 'channel-lint: OK\n' +exit "${rc}" diff --git a/mk/channels.inc b/mk/channels.inc @@ -0,0 +1,94 @@ +#!/bin/sh +# mk/channels.inc - channel chain resolution and repo path layout. +# Sourced, not executed. Expects ROOT to be set. + +CHANDIR="${ROOT}/channels" + +chan_die() { printf 'channels: error: %s\n' "$*" >&2; exit 1; } + +chan_exists() { [ -f "${CHANDIR}/$1/channel.conf" ]; } + +# chan_conf <channel> <key> -- empty when unset. Runs in a subshell, so it +# cannot die; callers guard with chan_exists first. +chan_conf() { + ( + upstream=; publish= + # shellcheck disable=SC1090 + . "${CHANDIR}/$1/channel.conf" >/dev/null 2>&1 || true + eval "printf '%s\n' \"\${$2}\"" + ) +} + +# chan_layers <channel> -- composition order, root first +chan_layers() { + chan_exists "$1" || chan_die "no such channel: $1" + _seen=" " + _stack= + _c="$1" + while [ -n "${_c}" ]; do + case "${_seen}" in + *" ${_c} "*) chan_die "upstream cycle at '${_c}'" ;; + esac + _seen="${_seen}${_c} " + _stack="${_c} ${_stack}" + _c=$(chan_conf "${_c}" upstream) + if [ -n "${_c}" ] && ! chan_exists "${_c}"; then + chan_die "'$1' names upstream '${_c}', which does not exist" + fi + done + printf '%s\n' "${_stack% }" +} + +# chan_targets -- every channel CI builds, i.e. publish != no +chan_targets() { + for _d in "${CHANDIR}"/*/; do + _n=$(basename "${_d}") + chan_exists "${_n}" || continue + [ "$(chan_conf "${_n}" publish)" = "no" ] && continue + printf '%s\n' "${_n}" + done +} + +# chan_pkgdir <channel> -- assembled tree, written by channel-assemble.sh +chan_pkgdir() { printf '%s/build/channels/%s/packages\n' "${ROOT}" "$1"; } + +chan_arch() { + case "$1" in + arm64) printf 'aarch64\n' ;; + *) printf '%s\n' "$1" ;; + esac +} + +# chan_repodir <channel> <arch> +chan_repodir() { + printf '%s/build/repo/%s/%s\n' "${ROOT}" "$1" "$(chan_arch "$2")" +} + +# chan_sysroot <channel> <arch> -- per channel, or edge's kernel headers would +# end up in an lts build +chan_sysroot() { + printf '%s/build/sysroot/%s/%s\n' "${ROOT}" "$1" "$(chan_arch "$2")" +} + +# chan_prefix <channel> <arch> -- bucket object key, relative to bucket root +chan_prefix() { printf 'apk/%s/%s\n' "$1" "$(chan_arch "$2")"; } + +chan_squash() { + sed 's#://#___PROTO___#; s#//*#/#g; s#___PROTO___#://#' +} + +# Repo URLs take the bare public base (https://repo.unos.finwo.net); the apk/ +# segment belongs to this builder, so another package format can sit beside it. + +# chan_url <base> <channel> <arch> [file] +chan_url() { + _u="${1%/}/$(chan_prefix "$2" "$3")" + [ -n "${4:-}" ] && _u="${_u}/$4" + printf '%s' "${_u}" | chan_squash +} + +# chan_repo_url <base> <channel> -- what apk wants in --repository: it appends +# /<arch> itself, so this stops one segment short of chan_url +chan_repo_url() { + printf '%s' "${1%/}/apk/$2" | chan_squash +} diff --git a/mk/check-revision.sh b/mk/check-revision.sh @@ -16,10 +16,14 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + PKG="" ARCH="x86_64" REPO="" PKGVER="" +CHANNEL="${UNOS_CHANNEL:-lts}" while [ $# -gt 0 ]; do case "$1" in @@ -27,6 +31,8 @@ while [ $# -gt 0 ]; do --arch=*) ARCH="${1#--arch=}"; shift ;; --repo) REPO="$2"; shift 2 ;; --repo=*) REPO="${1#--repo=}"; shift ;; + --channel) CHANNEL="$2"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; --pkgver) PKGVER="$2"; shift 2 ;; --pkgver=*) PKGVER="${1#--pkgver=}"; shift ;; -h|--help) sed -n '1,25p' "$0"; exit 0 ;; @@ -43,16 +49,16 @@ done # report the task as skipped rather than as a pass. published() { echo "check-revision.sh: $1" >&2 - echo " bump revision in packages/${PKG}/template to rebuild" >&2 + echo " bump ${PKG}'s revision in channel ${CHANNEL} to rebuild" >&2 echo "::set-state skipped" exit 1 } -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) echo "check-revision.sh: unsupported ARCH ${ARCH}" >&2; exit 1 ;; esac if [ -z "${PKGVER}" ]; then - TEMPLATE="${ROOT}/packages/${PKG}/template" + TEMPLATE="$(chan_pkgdir "${CHANNEL}")/${PKG}/template" [ -f "${TEMPLATE}" ] || { echo "check-revision.sh: no template: ${TEMPLATE}" >&2; exit 1; } # Read version/revision from template (same subshell pattern as deps.sh) @@ -72,21 +78,21 @@ fi APK_NAME="${PKG}-${PKGVER}.apk" +LOCALREPO=$(chan_repodir "${CHANNEL}" "${ARCH}") + # Check local repo first if [ -z "${REPO}" ]; then - if [ -f "${ROOT}/build/repo/${ARCH}/${APK_NAME}" ]; then - published "${APK_NAME} already exists in build/repo/${ARCH}/" + if [ -f "${LOCALREPO}/${APK_NAME}" ]; then + published "${APK_NAME} already exists in ${LOCALREPO}/" fi - # Also check published repo via local path if it exists - REPO="${ROOT}/build/repo/${ARCH}" + REPO="${LOCALREPO}" fi -# If REPO is a URL, use curl HEAD; if local dir, check file existence. +# --repo takes the bucket base; the channel and arch segments are this +# script's to append, same as every other consumer of chan_url. case "${REPO}" in http://*|https://*) - url="${REPO%/}/${APK_NAME}" - # Normalize // in path (BUCKET_PUBLIC_URL may have trailing slash). - url=$(printf "%s" "${url}" | sed 's#://#___PROTO___#; s#//*#/#g; s#___PROTO___#://#') + url=$(chan_url "${REPO}" "${CHANNEL}" "${ARCH}" "${APK_NAME}") if ! command -v curl >/dev/null 2>&1 && command -v apt-get >/dev/null 2>&1; then apt-get update -qq >/dev/null 2>&1 || true diff --git a/mk/deps.sh b/mk/deps.sh @@ -33,10 +33,21 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) -PKGDIR="${ROOT}/packages" + +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +CHANNEL="${UNOS_CHANNEL:-lts}" +case "${1:-}" in + --channel) CHANNEL="${2:?--channel needs a value}"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; +esac +PKGDIR=$(chan_pkgdir "${CHANNEL}") die() { printf 'deps.sh: error: %s\n' "$*" >&2; exit 1; } +[ -d "${PKGDIR}" ] || die "channel '${CHANNEL}' not assembled; run ./mk/channel-assemble.sh ${CHANNEL}" + # Same PATH that mk/build.sh gives templates, so hostmakedepends like `muon` # resolve from build/host/bin rather than appearing absent. PATH="${ROOT}/build/host/bin:${PATH}" @@ -81,7 +92,7 @@ read_vars() { field() { read_vars "$1" | cut -d'|' -f"$2"; } -# A makedepends may name a subpackage (linux-longterm-headers) rather than a +# A makedepends may name a subpackage (linux-headers) rather than a # template. The build graph needs the template that produces it. owner_of() { if [ -f "${PKGDIR}/$1/template" ]; then echo "$1"; return 0; fi @@ -160,10 +171,15 @@ cmd_changed() { # changed packages between two git refs: maps git diff paths to package names. # ./mk/deps.sh changed <base> <head> # - # Only packages/ and mk/ are considered, because that is all this repo + # Only channels/ and mk/ are considered, because that is all this repo # holds. First-party source (linkd) now arrives as a tag-pinned tarball, so # editing it produces no diff here at all: bumping the template's version - # is what marks it changed, and that is a packages/ path like any other. + # is what marks it changed, and that is a channels/ path like any other. + # + # A layer the current channel does not compose is ignored: editing + # channels/edge/ does not dirty lts. Whether the edited layer actually wins + # is not decided here -- it is enough that it is in the chain. + # # Compares <base>...<head> (three-dot, like GitHub PR diff). Falls back to # two-dot if base is not an ancestor. base="${1:-}" @@ -180,16 +196,22 @@ cmd_changed() { pkgs="" mk_changed=0 + layers=" $(chan_layers "${CHANNEL}" | tr '\n' ' ')" for f in ${changed_files}; do case "${f}" in - packages/*) - # packages/<name>/template, patches/*, files/* - pkg=$(printf '%s' "${f}" | cut -d/ -f2) + channels/*/packages/*) + # channels/<layer>/packages/<name>/{template,patches,files} + layer=$(printf '%s' "${f}" | cut -d/ -f2) + case "${layers}" in *" ${layer} "*) ;; *) continue ;; esac + pkg=$(printf '%s' "${f}" | cut -d/ -f4) if [ -f "${PKGDIR}/${pkg}/template" ]; then case " ${pkgs} " in *" ${pkg} "*) ;; *) pkgs="${pkgs} ${pkg}" ;; esac fi ;; + channels/*/channel.conf) + mk_changed=1 + ;; mk/*) mk_changed=1 ;; @@ -223,7 +245,7 @@ visit() { if [ -e "${TMP}/path.$1" ]; then die "dependency cycle involving '$1'" fi - [ -f "${PKGDIR}/$1/template" ] || die "'$1' is a makedepends of something but has no template" + [ -f "${PKGDIR}/$1/template" ] || die "'$1' is a makedepends of something but has no template in channel '${CHANNEL}'" : > "${TMP}/path.$1" for d in $(makedeps_of "$1"); do visit "${d}" @@ -314,6 +336,8 @@ case "${1:-}" in owner) shift; owner_of "${1:?usage: deps.sh owner <name>}" ;; subpkgs) shift; field "${1:?usage: deps.sh subpkgs <pkg>}" 4 ;; rtdeps) shift; cmd_rtdeps "$@" ;; + channels) chan_targets ;; + layers) shift; chan_layers "${1:-${CHANNEL}}" | tr ' ' '\n' ;; # A subpackage carries its owning template's version. pkgver) shift _o=$(owner_of "${1:?usage: deps.sh pkgver <name>}") || die "no such package: $1" diff --git a/mk/gen-pipeline.sh b/mk/gen-pipeline.sh @@ -5,22 +5,22 @@ # ./mk/gen-pipeline.sh --write write it to .conductor.yml # ./mk/gen-pipeline.sh --check exit 1 if .conductor.yml is out of date # -# WHY GENERATED -# ------------- -# The conductor does not run repository code while building its task graph -- -# the pipeline file is data, read at the pushed commit. So the per-package -# dependency edges have to be written out literally. Maintaining ~30 tasks and -# their `needs` by hand against packages/*/template guarantees they drift, and -# the failure mode is a package building before the library it links against. -# -# Generating instead means makedepends stays the single source of truth, and -# tests/unit/test_deps.sh fails if the committed file no longer matches. +# The conductor treats this file as data and will not run repository code to +# build its graph, so every edge has to be written out literally. Generating +# keeps makedepends the single source of truth; test_deps.sh catches drift. set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) OUT="${ROOT}/.conductor.yml" +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +for c in $(chan_targets); do + [ -d "$(chan_pkgdir "${c}")" ] || "${HERE}/channel-assemble.sh" "${c}" >/dev/null +done + MODE=print case "${1:-}" in --write) MODE=write ;; @@ -35,7 +35,7 @@ esac # conventional spelling) rather than a hyphen, which would render it # `libstdc--` and read like a typo. Anything else unexpected becomes a hyphen. task_name() { - printf 'pkg-%s' "$(printf '%s' "$1" | sed 's/+/x/g' | tr -c 'A-Za-z0-9_.-' '-')" + printf 'pkg-%s-%s' "$1" "$(printf '%s' "$2" | sed 's/+/x/g' | tr -c 'A-Za-z0-9_.-' '-')" } # Resolved here rather than in CI: the pipeline is generated, and sourcing a @@ -46,8 +46,8 @@ pkgver() { SYSROOT=; DESTDIR=; WRKSRC=; FILESDIR=; WORK=; SRCDEST= UNOS_MKDIR="${HERE}" die() { :; } ; msg() { :; } ; vinstall() { :; } ; vmkdir() { :; } - . "${ROOT}/packages/$1/template" >/dev/null 2>&1 || true - [ -n "${version}" ] || { echo "gen-pipeline.sh: no version for $1" >&2; exit 1; } + . "$(chan_pkgdir "$1")/$2/template" >/dev/null 2>&1 || true + [ -n "${version}" ] || { echo "gen-pipeline.sh: no version for $2 in $1" >&2; exit 1; } printf '%s-r%s' "${version}" "${revision}" ) } @@ -58,24 +58,6 @@ emit() { # # Regenerate with: ./mk/gen-pipeline.sh --write # Verified by: tests/unit/test_deps.sh -# -# One task per package, with `needs` taken from each template's makedepends, -# so a package never builds before something it links against. The list is -# written out rather than discovered because the conductor treats this file as -# data and will not execute repository code to build its graph. -# -# No mounts are provided and artifacts are not shared between tasks. Each build -# therefore seeds its sysroot from the published S3 repo (mk/sysroot.sh) and -# publishes its own result back (mk/publish.sh). `needs` is what guarantees a -# dependency is already published by the time a dependent starts. -# -# Credentials arrive as environment: BUCKET_ACCESS_KEY, BUCKET_SECRET_KEY, -# BUCKET_NAME, BUCKET_ENDPOINT (URL), BUCKET_REGION (region name), -# BUCKET_PUBLIC_URL (public https endpoint, e.g. https://repo.unos.finwo.net/). -# -# Signing comes from the unos-sign-key worker feature, which mounts the key and -# exports UNOS_KEY_APK_RSA_PRI. Each worker holds a distinct key, so the signer -# varies with scheduling and packages/unos-keys must trust all of them. version: 1 @@ -96,65 +78,62 @@ tasks: # apk-tools but is built here rather than installed from a distribution, # so the check reports it missing until bootstrap has produced it. - ./mk/bootstrap-host.sh - - ./mk/deps.sh check + - ./mk/channel-lint.sh - ./mk/gen-pipeline.sh --check - ./tests/run.sh --unit - - ./mk/bootstrap-repo.sh - HEADER + for c in $(chan_targets); do + printf ' - ./mk/channel-assemble.sh %s\n' "${c}" + printf ' - ./mk/deps.sh --channel %s check\n' "${c}" + printf ' - ./mk/bootstrap-repo.sh --channel %s\n' "${c}" + done + printf '\n' - # One task per package, in dependency order so the file reads top-down. - for p in $(cd "${ROOT}" && ./mk/deps.sh order); do - # graph, not vars: makedepends may name a subpackage, and the task that - # builds it is the owning template's. - deps=$(cd "${ROOT}" && ./mk/deps.sh graph | awk -v p="$p" '$1 == p { print $2 }') - printf ' %s:\n' "$(task_name "$p")" - printf ' needs:\n' - printf ' - check\n' - for d in ${deps}; do - printf ' - %s\n' "$(task_name "$d")" + for c in $(chan_targets); do + for p in $(cd "${ROOT}" && ./mk/deps.sh --channel "${c}" order); do + # graph, not vars: makedepends may name a subpackage, and the task that + # builds it is the owning template's. + deps=$(cd "${ROOT}" && ./mk/deps.sh --channel "${c}" graph | awk -v p="$p" '$1 == p { print $2 }') + printf ' %s:\n' "$(task_name "${c}" "$p")" + printf ' needs:\n' + printf ' - check\n' + for d in ${deps}; do + printf ' - %s\n' "$(task_name "${c}" "$d")" + done + printf ' arch: [x86_64]\n' + printf ' requires: [unos-sign-key]\n' + printf ' script:\n' + printf ' - ./mk/check-revision.sh --channel %s %s --pkgver %s --repo "$BUCKET_PUBLIC_URL" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; }\n' "${c}" "$p" "$(pkgver "${c}" "$p")" + printf ' - ./mk/channel-assemble.sh %s\n' "${c}" + printf ' - ./mk/ci-setup.sh\n' + printf ' - ./mk/bootstrap-host.sh\n' + printf ' - ./mk/sysroot.sh --channel %s --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" %s\n' "${c}" "$p" + printf ' - ./mk/build.sh --channel %s %s\n' "${c}" "$p" + printf ' - ./mk/publish.sh --channel %s --arch "$ARCH" %s\n' "${c}" "$p" + printf '\n' + done + done + + # One index per channel, rewritten after every package in it has published. + # Per-package would race: two finishing together would each rebuild the index + # from their own partial view of the repo. + for c in $(chan_targets); do + printf ' index-%s:\n' "${c}" + printf ' after:\n' + for p in $(cd "${ROOT}" && ./mk/deps.sh --channel "${c}" order); do + printf ' - %s\n' "$(task_name "${c}" "$p")" 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. printf ' arch: [x86_64]\n' - # The signing key lives on the worker and is never seen by the conductor; - # the task asks for it by capability name. Project-scoped on purpose: the - # feature namespace is global to the conductor, which hosts more than UNOS. - # The feature provides UNOS_KEY_APK_RSA_PRI, which mk/sign-key.inc reads. printf ' requires: [unos-sign-key]\n' printf ' script:\n' - printf ' - ./mk/check-revision.sh %s --pkgver %s --repo "${BUCKET_PUBLIC_URL%%/}/$ARCH" || { rc=$?; [ "$rc" = 1 ] && exit 0; exit "$rc"; }\n' "$p" "$(pkgver "$p")" + printf ' - ./mk/channel-assemble.sh %s\n' "${c}" printf ' - ./mk/ci-setup.sh\n' printf ' - ./mk/bootstrap-host.sh\n' - printf ' - ./mk/sysroot.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" %s\n' "$p" - printf ' - ./mk/build.sh %s\n' "$p" - printf ' - ./mk/publish.sh --arch "$ARCH" %s\n' "$p" + printf ' - ./mk/repo-pull.sh --channel %s --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL"\n' "${c}" + printf ' - ./mk/repo-index.sh --channel %s\n' "${c}" + printf ' - ./mk/publish.sh --channel %s --arch "$ARCH" --index-only\n' "${c}" printf '\n' done - - # The index is rewritten once, after every package has been published. - # Doing it per-package would race: two packages finishing together would - # each rebuild the index from their own partial view of the repo. - cat <<'FOOTER' - index: - after: -FOOTER - for p in $(cd "${ROOT}" && ./mk/deps.sh order); do - printf ' - %s\n' "$(task_name "$p")" - done - cat <<'FOOTER' - arch: [x86_64] - requires: [unos-sign-key] - script: - - ./mk/ci-setup.sh - - ./mk/bootstrap-host.sh - # Pull every published package down so the index describes the whole - # repo, not just whatever this container happened to build. - - ./mk/repo-pull.sh --arch "$ARCH" --repo "$BUCKET_PUBLIC_URL" - - ./mk/repo-index.sh - - ./mk/publish.sh --arch "$ARCH" --index-only -FOOTER } case "${MODE}" in diff --git a/mk/kernel.inc b/mk/kernel.inc @@ -1,21 +1,15 @@ #!/bin/sh -# mk/kernel.inc - shared kbuild recipe for the linux-{longterm,stable, -# mainline} templates. Sourced at template top level via +# mk/kernel.inc - shared kbuild recipe and config policy for the packages/linux +# template carried by each channel layer. Sourced at template top level via # . "${UNOS_MKDIR}/kernel.inc" (UNOS_MKDIR is exported by the driver before the # template is sourced). # -# The template sets variables, then the standard phases call in: -# version=... (checksum, distfiles as usual) -# KDELTA_ENABLE="IKCONFIG IKCONFIG_PROC" (forced =y, no CONFIG_ prefix) -# KDELTA_MODULE="NET_VRF" (forced =m) -# KDELTA_DISABLE="MODULE_SIG" (forced n) -# KASSERT_Y="IPV6 ..." KASSERT_M="NET_VRF" KASSERT_N="MODULE_SIG" +# The template supplies only what is genuinely per-line -- version, checksum, +# distfiles -- then calls the standard phases: # do_configure() { kernel_configure; } # do_build() { kernel_build; } # do_install() { kernel_install; } -# sub_linux() { spick boot "lib/modules"; } # linux -# sub_linux_headers() { spick usr/include; } # linux-headers -# empty sub functions (`:`) for the two metas. +# sub_linux_headers() { spick usr/include; } # # Conventions (locked here, not per template): # - defconfig + explicit deltas + olddefconfig. Deltas and asserts are @@ -33,6 +27,18 @@ # - Reproducibility: KBUILD_BUILD_USER/HOST/TIMESTAMP (from # SOURCE_DATE_EPOCH, driver-exported). +# Feature policy is a property of UNOS, not of a kernel line: a switch needs +# the same dataplane whichever channel it tracks. Holding these here rather +# than in each layer's template is what stops lts, stable and edge from +# silently diverging. Symbols move between releases, so the asserts below are +# the tripwire -- a delta that stops applying breaks the build, never the boot. +KDELTA_ENABLE="IKCONFIG IKCONFIG_PROC NET_L3_MASTER_DEV IPV6_MULTIPLE_TABLES BLK_DEV_NVME MMC MMC_BLOCK BRIDGE VLAN_8021Q" +KDELTA_MODULE="NET_VRF" +KDELTA_DISABLE="" +KASSERT_Y="IPV6 IP_MULTIPLE_TABLES IPV6_MULTIPLE_TABLES NET_L3_MASTER_DEV DEVTMPFS_MOUNT BLK_DEV_INITRD SERIAL_8250_CONSOLE MODULES IKCONFIG IKCONFIG_PROC EFI_STUB BLK_DEV_NVME MMC MMC_BLOCK NVME_CORE BRIDGE VLAN_8021Q" +KASSERT_M="NET_VRF" +KASSERT_N="MODULE_SIG" + kernel_configure() { cd "${WRKSRC}" [ -f scripts/config ] || die "kernel: scripts/config missing" diff --git a/mk/keymgmt.sh b/mk/keymgmt.sh @@ -3,7 +3,7 @@ # # keymgmt.sh new [--type rsa|supercop] [--for apk|unos] <stem> # Generate a key named <stem>-<8 hex> in ~/.unos-keys/ and stage its -# public half into packages/unos-keys/files/<for>/. Defaults: rsa for +# public half into channels/base/packages/unos-keys/files/<for>/. Defaults: rsa for # apk (4096-bit), supercop for unos. apk mandates RSA: supercop-for-apk # is refused. After adding keys, bump the unos-keys version and rebuild. # @@ -20,7 +20,8 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) KEYDIR="${HOME}/.unos-keys" -PKGKEYS="${ROOT}/packages/unos-keys/files" +# unos-keys lives in base: trust anchors are not channel-specific. +PKGKEYS="${ROOT}/channels/base/packages/unos-keys/files" msg() { printf '==> %s\n' "$*"; } die() { printf 'keymgmt.sh: error: %s\n' "$*" >&2; exit 1; } @@ -88,8 +89,8 @@ cmd_new() { mkdir -p "${PKGKEYS}/${for}" cp "${KEYDIR}/${pub}" "${PKGKEYS}/${for}/${pub}" msg "key: ${KEYDIR}/${priv}" - msg "pub staged: packages/unos-keys/files/${for}/${pub}" - echo "next: bump packages/unos-keys version, rebuild it, re-index" + msg "pub staged: channels/base/packages/unos-keys/files/${for}/${pub}" + echo "next: bump unos-keys version in channels/base, rebuild it, re-index" } cmd_use() { diff --git a/mk/publish.sh b/mk/publish.sh @@ -22,15 +22,21 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + ARCH="${ARCH:-x86_64}" DRY=0 INDEX_ONLY=0 PKGS="" +CHANNEL="${UNOS_CHANNEL:-lts}" while [ $# -gt 0 ]; do case "$1" in --arch) ARCH="$2"; shift 2 ;; --arch=*) ARCH="${1#--arch=}"; shift ;; + --channel) CHANNEL="$2"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; --dry-run) DRY=1; shift ;; --index-only) INDEX_ONLY=1; shift ;; -h|--help) sed -n '2,20p' "$0"; exit 0 ;; @@ -42,8 +48,15 @@ done msg() { printf '==> %s\n' "$*"; } die() { printf 'publish.sh: error: %s\n' "$*" >&2; exit 1; } -REPODIR="${ROOT}/build/repo/${ARCH}" +ARCH=$(chan_arch "${ARCH}") +export UNOS_CHANNEL="${CHANNEL}" + +chan_exists "${CHANNEL}" || die "no such channel: ${CHANNEL}" +[ "$(chan_conf "${CHANNEL}" publish)" = "no" ] && die "channel '${CHANNEL}' is publish=no" + +REPODIR=$(chan_repodir "${CHANNEL}" "${ARCH}") [ -d "${REPODIR}" ] || die "no such repo dir: ${REPODIR}" +PREFIX=$(chan_prefix "${CHANNEL}" "${ARCH}") if [ "${DRY}" != "1" ]; then for v in BUCKET_ACCESS_KEY BUCKET_SECRET_KEY BUCKET_NAME BUCKET_ENDPOINT BUCKET_REGION; do @@ -124,9 +137,9 @@ else [ -n "${FILES}" ] || die "no .apk files in ${REPODIR}" fi -msg "publishing to ${BUCKET_NAME:-<dry-run>}/${ARCH}" +msg "publishing to ${BUCKET_NAME:-<dry-run>}/${PREFIX}" for f in ${FILES}; do - put "${f}" "${ARCH}/$(basename "${f}")" + put "${f}" "${PREFIX}/$(basename "${f}")" done # The index goes last, always. It is the file clients read to discover what @@ -134,7 +147,7 @@ done # are not there yet; publishing it after is merely briefly stale. IDX="${REPODIR}/APKINDEX.tar.gz" if [ -f "${IDX}" ]; then - put "${IDX}" "${ARCH}/APKINDEX.tar.gz" + put "${IDX}" "${PREFIX}/APKINDEX.tar.gz" else [ "${INDEX_ONLY}" = "1" ] && die "no APKINDEX.tar.gz in ${REPODIR}; run ./mk/repo-index.sh" msg "note: no APKINDEX.tar.gz to publish (run ./mk/repo-index.sh first)" diff --git a/mk/repo-index.sh b/mk/repo-index.sh @@ -10,12 +10,21 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) -# ARCH from $ARCH env or first arg, normalise arm64 -> aarch64 + +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + +CHANNEL="${UNOS_CHANNEL:-lts}" +case "${1:-}" in + --channel) CHANNEL="${2:?--channel needs a value}"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; +esac + ARCH="${ARCH:-${1:-x86_64}}" if [ $# -ge 1 ]; then case "$1" in x86_64|aarch64|arm64) ARCH="$1";; esac; fi -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) echo "repo-index.sh: unsupported ARCH ${ARCH}" >&2; exit 1 ;; esac -REPODIR="${ROOT}/build/repo/${ARCH}" +REPODIR=$(chan_repodir "${CHANNEL}" "${ARCH}") [ -d "${REPODIR}" ] || { echo "repo-index.sh: no such dir: ${REPODIR}" >&2; exit 1; } diff --git a/mk/repo-pull.sh b/mk/repo-pull.sh @@ -1,18 +1,21 @@ #!/bin/sh -# mk/repo-pull.sh - download every published .apk into build/repo/<arch>. +# mk/repo-pull.sh - download every published .apk for a channel. # -# ./mk/repo-pull.sh --arch x86_64 --repo https://repo.unos.finwo.net +# ./mk/repo-pull.sh --channel lts --arch x86_64 --repo https://repo.unos.finwo.net # -# Names are derived from the templates rather than from APKINDEX, so this -# works before a valid index exists. Packages that are not published (failed -# or skipped builds) are simply absent. +# Names come from the templates, not from APKINDEX, so this works before a +# valid index exists. Unpublished packages are simply absent. set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + ARCH="${ARCH:-x86_64}" BASE="" +CHANNEL="${UNOS_CHANNEL:-lts}" while [ $# -gt 0 ]; do case "$1" in @@ -20,46 +23,44 @@ while [ $# -gt 0 ]; do --arch=*) ARCH="${1#--arch=}"; shift ;; --repo) BASE="$2"; shift 2 ;; --repo=*) BASE="${1#--repo=}"; shift ;; + --channel) CHANNEL="$2"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; -h|--help) sed -n '2,9p' "$0"; exit 0 ;; *) echo "repo-pull.sh: unknown argument: $1" >&2; exit 1 ;; esac done -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) echo "repo-pull.sh: unsupported ARCH ${ARCH}" >&2; exit 1 ;; esac [ -n "${BASE}" ] || { echo "repo-pull.sh: --repo is required" >&2; exit 1; } command -v curl >/dev/null 2>&1 || { echo "repo-pull.sh: curl is required" >&2; exit 1; } -OUT="${ROOT}/build/repo/${ARCH}" +export UNOS_CHANNEL="${CHANNEL}" +OUT=$(chan_repodir "${CHANNEL}" "${ARCH}") mkdir -p "${OUT}" -echo "==> pulling published packages from ${BASE} (${ARCH})" +echo "==> pulling ${CHANNEL} packages from ${BASE} (${ARCH})" found=0 for p in $("${ROOT}/mk/deps.sh" list); do - TEMPLATE="${ROOT}/packages/${p}/template" - [ -f "${TEMPLATE}" ] || continue - - eval "$( ( - version=; revision=0 - SYSROOT=; DESTDIR=; WRKSRC=; FILESDIR=; WORK=; SRCDEST=; UNOS_MKDIR= - die() { :; } ; msg() { :; } ; vinstall() { :; } ; vmkdir() { :; } - . "${TEMPLATE}" >/dev/null 2>&1 || true - printf 'VERSION=%s\nREVISION=%s\n' "${version}" "${revision}" - ) )" - [ -n "${VERSION}" ] || continue + for n in "${p}" $("${ROOT}/mk/deps.sh" subpkgs "${p}" 2>/dev/null || true); do + pv=$("${ROOT}/mk/deps.sh" pkgver "${n}" 2>/dev/null) || continue + apk_name="${n}-${pv}.apk" - APK_NAME="${p}-${VERSION}-r${REVISION}.apk" - url=$(printf '%s' "${BASE%/}/${ARCH}/${APK_NAME}" \ - | sed 's#://#___PROTO___#; s#//*#/#g; s#___PROTO___#://#') + if [ -f "${OUT}/${apk_name}" ]; then + found=$((found + 1)) + continue + fi - if curl -fsSL -o "${OUT}/${APK_NAME}" "${url}" 2>/dev/null; then - printf ' %s\n' "${APK_NAME}" - found=$((found + 1)) - else - rm -f "${OUT}/${APK_NAME}" - fi + url=$(chan_url "${BASE}" "${CHANNEL}" "${ARCH}" "${apk_name}") + if curl -fsSL -o "${OUT}/${apk_name}" "${url}" 2>/dev/null; then + printf ' %s\n' "${apk_name}" + found=$((found + 1)) + else + rm -f "${OUT}/${apk_name}" + fi + done done echo "==> pulled ${found} package(s) into ${OUT}" diff --git a/mk/sign-key.inc b/mk/sign-key.inc @@ -12,7 +12,7 @@ # # Note each worker carries its own distinct keypair, so KEYNAME (and therefore # the .SIGN.RSA.<name>.rsa.pub record in every .apk) varies with scheduling. -# packages/unos-keys must ship every worker's public half or verification +# unos-keys must ship every worker's public half or verification # fails for whichever packages happened to land elsewhere. # # Source this file ($ROOT must be set), then: KEY=$(resolve_sign_key). diff --git a/mk/sysroot.sh b/mk/sysroot.sh @@ -22,9 +22,13 @@ set -eu HERE=$(cd "$(dirname "$0")" && pwd) ROOT=$(cd "${HERE}/.." && pwd) +# shellcheck disable=SC1091 +. "${HERE}/channels.inc" + ARCH="x86_64" REPOS="" PKGS="" +CHANNEL="${UNOS_CHANNEL:-lts}" # default repos: local build/repo/<arch> if it exists, else nothing (caller # must supply --repo). CI supplies --repo https://repo.unos.finwo.net/x86_64 # and optionally --repo <staging-url>. @@ -34,6 +38,8 @@ while [ $# -gt 0 ]; do --arch=*) ARCH="${1#--arch=}"; shift ;; --repo) REPOS="${REPOS} $2"; shift 2 ;; --repo=*) REPOS="${REPOS} ${1#--repo=}"; shift ;; + --channel) CHANNEL="$2"; shift 2 ;; + --channel=*) CHANNEL="${1#--channel=}"; shift ;; -h|--help) sed -n '1,45p' "$0" exit 0 @@ -46,16 +52,11 @@ done # remaining args are also pkgs for a in "$@"; do PKGS="${PKGS} $a"; done -case "${ARCH}" in arm64) ARCH=aarch64 ;; esac +ARCH=$(chan_arch "${ARCH}") case "${ARCH}" in x86_64|aarch64) ;; *) echo "sysroot.sh: unsupported ARCH ${ARCH}" >&2; exit 1 ;; esac -SYSROOT="${ROOT}/build/sysroot" -# When seeding for a specific ARCH, keep arch-specific sysroots separate so -# x86_64 and aarch64 headers don't clobber each other. For x86_64 the -# historical path `build/sysroot` is kept as the default (symlink or same). -if [ "${ARCH}" != "x86_64" ]; then - SYSROOT="${SYSROOT}-${ARCH}" -fi +export UNOS_CHANNEL="${CHANNEL}" +SYSROOT=$(chan_sysroot "${CHANNEL}" "${ARCH}") APK="${ROOT}/build/host/bin/apk" if [ ! -x "${APK}" ]; then @@ -66,13 +67,14 @@ if [ ! -x "${APK}" ]; then } fi -# Default repo: local build/repo/<arch> if it exists +# Default repo: local build/repo/<channel>/<arch> if it exists if [ -z "${REPOS}" ]; then - if [ -d "${ROOT}/build/repo/${ARCH}" ] && ls "${ROOT}/build/repo/${ARCH}"/*.apk >/dev/null 2>&1; then - REPOS="${ROOT}/build/repo/${ARCH}" + LOCALREPO=$(chan_repodir "${CHANNEL}" "${ARCH}") + if [ -d "${LOCALREPO}" ] && ls "${LOCALREPO}"/*.apk >/dev/null 2>&1; then + REPOS="${LOCALREPO}" else - echo "sysroot.sh: no --repo given and no local build/repo/${ARCH} with .apk files" >&2 - echo " hint: --repo https://repo.unos.finwo.net/${ARCH} or --repo /path/to/repo" >&2 + echo "sysroot.sh: no --repo given and no local ${LOCALREPO} with .apk files" >&2 + echo " hint: --repo https://repo.unos.finwo.net or --repo /path/to/repo" >&2 exit 1 fi fi @@ -112,11 +114,10 @@ done # Strategy: try to install all, but if apk fails due to missing pkg, retry # without the leaf targets. -# The published APKINDEX only gains a package once the index task reruns, so -# within a single pipeline run it lags behind what has actually been uploaded. -# Fetch the exact version each template pins straight from the repo and index -# it locally; anything missing here still resolves through APKINDEX below. -STAGE_BASE="${ROOT}/build/sysroot-stage" +# The published APKINDEX lags within a pipeline run: it only gains a package +# once the index task reruns. Fetch each template's exact pin directly and +# index it locally; whatever is missed still resolves through APKINDEX below. +STAGE_BASE="${ROOT}/build/sysroot-stage/${CHANNEL}" STAGE="${STAGE_BASE}/${ARCH}" STAGE_ARGS="" for r in ${REPOS}; do @@ -131,7 +132,7 @@ for r in ${REPOS}; do set -- ${queue} n="$1"; shift; queue="$*" - # A dependency may carry a pin: linux-headers=6.18.51-r1 + # depends may carry a pin: linux-headers=6.18.51-r1 base="${n%%=*}" case "${n}" in *=*) pv="${n#*=}" ;; @@ -143,8 +144,7 @@ for r in ${REPOS}; do apk_name="${base}-${pv}.apk" if [ ! -f "${STAGE}/${apk_name}" ]; then - url=$(printf '%s' "${r%/}/${ARCH}/${apk_name}" \ - | sed 's#://#___PROTO___#; s#//*#/#g; s#___PROTO___#://#') + url=$(chan_url "${r}" "${CHANNEL}" "${ARCH}" "${apk_name}") curl -fsSL -o "${STAGE}/${apk_name}" "${url}" 2>/dev/null || { rm -f "${STAGE}/${apk_name}" continue @@ -153,8 +153,6 @@ for r in ${REPOS}; do fi staged=$((staged + 1)) - # Pull in what it needs at runtime; ambiguous names (a subpackage several - # kernel lines all provide) just fall through to APKINDEX. queue="${queue} $("${ROOT}/mk/deps.sh" rtdeps "${base}" 2>/dev/null || true)" done if [ "${staged}" -gt 0 ]; then @@ -164,24 +162,17 @@ for r in ${REPOS}; do break done +# apk appends /<arch> to every --repository, so remote bases stop at the +# channel and local paths stop one above the arch directory. REPO_ARGS="${STAGE_ARGS}" for r in ${REPOS}; do case "${r}" in - http://*|https://*|file://*) REPO_ARGS="${REPO_ARGS} --repository ${r}" ;; - /*) REPO_ARGS="${REPO_ARGS} --repository file://${r}" ;; - *) # relative local path like build/repo/x86_64 -> use base - # If it already ends with /x86_64 or /aarch64, strip to base - case "${r}" in */x86_64|*/aarch64|*/arm64) - base=$(dirname "${r}") - REPO_ARGS="${REPO_ARGS} --repository file://${ROOT}/${base}" - ;; - *) REPO_ARGS="${REPO_ARGS} --repository file://${ROOT}/${r}" ;; - esac - ;; + http://*|https://*) REPO_ARGS="${REPO_ARGS} --repository $(chan_repo_url "${r}" "${CHANNEL}")" ;; + file://*) REPO_ARGS="${REPO_ARGS} --repository ${r}" ;; + /*) REPO_ARGS="${REPO_ARGS} --repository file://$(dirname "${r}")" ;; + *) REPO_ARGS="${REPO_ARGS} --repository file://$(dirname "${ROOT}/${r}")" ;; esac done -# If REPOS was a single arch-specific local path, also allow base form -# e.g. build/repo/x86_64 -> file://.../build/repo # Allow apk to fetch from multiple repos; --allow-untrusted for local unsigned # staging during dev. Published repo is signed; apk will verify via keys in diff --git a/packages/README.md b/packages/README.md @@ -1,128 +0,0 @@ -# packages/ - -Source package definitions for UNOS, one directory per package. - -Layout follows the Void Linux convention: - -``` -packages/<pkgname>/ -|-- template # shell-sourced build definition (required) -|-- patches/ # optional, applied in sorted order -`-- files/ # optional, static files referenced by the template -``` - -A `template` is a shell fragment, not a script: it declares variables and -optionally overrides `do_*` phases: - -```sh -pkgname=example -version=1.0.0 -revision=1 -build_style=gnu-configure -hostmakedepends="pkg-config" -makedepends="libfoo-devel" -short_desc="One-line description" -maintainer="..." -license="BSD-3-Clause" -homepage="https://example.org" -distfiles="https://example.org/example-${version}.tar.gz" -checksum=<sha256> -``` - -Templates are built by our own driver (local now, CI later) into a signed -apk repository (v2 artifacts, apk-tools v3 manager). Nothing in this -directory is ever built by hand on a target switch. - -## Rules - -- **Declare build dependencies.** `makedepends` lists other UNOS packages whose - headers/libs must be in `build/sysroot` before this one compiles; - `hostmakedepends` lists commands that must exist on the build host. Both are - enforced by `mk/build.sh` before anything is fetched, and `makedepends` is - what `mk/deps.sh` uses to compute build order. Keep them accurate in both - directions: a missing entry breaks a clean-checkout build, and a spurious one - fails a build that would otherwise work. `depends` is runtime only and does - **not** affect build order, so a package needed at both times appears twice - (see `gptfdisk`). -- **Pin everything.** Explicit versions and recorded checksums. No moving - targets, no floating branches. -- **Third-party source uses `distfiles=` and must carry `checksum=`.** The - driver refuses to build a template that sets `distfiles` without a matching - sha256, because there we are trusting a server nobody here controls. -- **Our own source uses `srcfiles=` and carries no checksum.** It is fetched by - tag from `git.finwo.net`; the tag is the pin and TLS is the transport. A - forge regenerates tag archives on demand, so they are not byte-stable and a - recorded sha256 would eventually fail for reasons indistinguishable from - tampering. Setting `checksum=` alongside `srcfiles=` is an error, as is - setting both `srcfiles=` and `distfiles=` -- whichever is present supplies - the tarball `WRKSRC` is derived from, and two sources would make that choice - silent and arbitrary. Only `linkd` uses this today. -- **Never vendor upstream source into this repository.** Sources are fetched at - build time from a pinned revision. This keeps history small and keeps our - licensing story unambiguous. -- **Preserve vendor notices.** Templates that patch third-party code must not - strip copyright headers. This is a binding condition of the Broadcom SDK - licence, and stripping headers is the single easiest way to breach it. -- **Kernel-coupled packages must rebuild with the kernel.** Anything producing - a `.ko` has to be rebuilt whenever the `linux` package changes; a stale module - fails at `insmod` time on the switch, which is the worst possible place to - find out. -- **Shared-only C libraries.** Nothing in UNOS links statically, so library - templates pass `--disable-static` (or equivalent) and must not ship `.a` - files. Keep the rootfs lean; revisit only if a static-link need appears. -- **Build-time sysroot (`build/sysroot`, generated, never committed).** - Libraries that other packages build against install twice: once into - `DESTDIR` (the shipped `.apk`) and once into `SYSROOT` (headers + `.so` + - `.pc` files). The driver exports `SYSROOT` and `UNOS_MKDIR` (the mk/ - directory - never `MKDIR`, which collides with libtool's internal - `$MKDIR`), prepends `build/host/bin` (host tools like muon) to `PATH`, - and points `PKG_CONFIG_PATH` at the sysroot. The driver centrally - rewrites every sysroot `.pc` after `do_install` (all of `prefix=`, - `libdir=`, `includedir` to `${SYSROOT}/usr` paths) - hand-rolled - per-template `sed` of only `prefix=` is insufficient (efivar's - `libdir=/includedir=` are literal, not `${prefix}`-relative, so a - prefix-only rewrite left consumers on host `/usr/include`). Templates - only double-install and assert presence; the driver fixes the paths. - efivar additionally patches its `.pc.in` before generation to expose - both `-I${includedir}` and `-I${includedir}/efivar` (upstream only - ships the subdir, which relies on host `/usr/include` as an implicit - search path - absent in a sysroot). -- **Loader cache is generated, never shipped.** The loader's baked-in - search covers `/lib64` + `/usr/lib64` only, so every library package - carries a `files/post-install` running `exec /sbin/ldconfig` (absolute: - glibc installs it to `/sbin`, and the busybox applet is compiled out). - Script-bearing packages order themselves with `depends="glibc busybox"` - (`/bin/sh` must exist before apk runs their scripts). `mk/rootfs.sh` - additionally runs `ldconfig` explicitly after assembly so the chroot - cache never depends on script-execution order. -- **Subpackages: one template, several .apks.** A template may declare - `subpackages="name ..."` with per-sub `short_desc_<underscored>` / - `depends_<underscored>` (provides/replaces optional) and a - `sub_<underscored>()` function partitioning `DESTDIR` into `SUBDEST` - via `spick` (move semantics - never duplicated). Per-subpackage control - scripts live at `files/<script>.<subname>` (e.g. - `post-install.linux`). After all splits `DESTDIR` must be empty: the - primary packs the remainder, so meta primaries are empty by - construction. Version pins between outputs must carry the full pkgver - incl. `-r` (`depends="linux=${version}-r${revision}"`) - apk's `=` - never matches a bare version. Single-output templates are unaffected. -- **Control scripts run chrooted via memfd.** apk v3 executes scripts - through `/proc/self/fd`, so any `apk add` that runs scripts needs - `/proc` mounted in the target (live systems always have it; - `mk/rootfs.sh` binds it for assembly; the installer must too). -- **Kernel image symlink.** `mk/kernel.inc` installs both - `/boot/vmlinuz-${KREL}` and `/boot/vmlinuz -> vmlinuz-${KREL}`; the - static `grub.cfg` references the generic path. Older images had only - the versioned name - the installer creates the symlink idempotently - after unpacking rootfs, so both old and new images boot. -- **GRUB is UEFI-only in this tree.** `packages/grub` builds - `x86_64-efi` only; `i386-pc` fails under binutils 2.44 (mislinked - `kernel.img` `.text` at 0x9074 vs 0x9000, `grub-mkimage` fail-louds). - The installer dies on BIOS firmware with a clear message; revisit - when binutils is fixed or upstream works around it. The grub package - prunes `grub-mkconfig` - the static `grub.cfg` is rendered by the - installer and checked with shipped `grub-script-check`. -- **Host-independence.** `iproute2` scrubs autotools-appended optionals - (`HAVE_ELF` etc.) and asserts `NEEDED` is subset of {libmnl,libcap,libc}; `grub` - trims freetype/tasn1/fuse/zfs/dm; all `CPPFLAGS/LDFLAGS` are - sysroot-first. A build must not silently pick up host libraries. diff --git a/packages/apk-tools/template b/packages/apk-tools/template @@ -1,55 +0,0 @@ -# Template file for 'apk-tools' -pkgname=apk-tools -version=3.0.8 -revision=1 -short_desc="Package manager for apk packages" -maintainer="finwo <finwo@pm.me>" -license="GPL-2.0-only" -homepage="https://gitlab.alpinelinux.org/alpine/apk-tools" -distfiles="https://gitlab.alpinelinux.org/alpine/apk-tools/-/archive/v3.0.8/apk-tools-v3.0.8.tar.gz" -checksum=e81c64a6e7c3806d45d4622c253e757aee970be84048554fa0eed79310e9453e -depends="glibc zlib openssl" -makedepends="glibc zlib openssl linux-longterm-headers" -hostmakedepends="muon" - -# Notes: -# - Same version the host manager was built from (v3.0.8); target and host -# stay on one version until there is a reason to diverge. -# - muon (build/host/bin, on PATH via the driver) configures and builds via -# its vendored samurai, so no ninja on the host; out-of-tree in -# ${WORK}/build, DESTDIR install. -# - url_backend=libfetch (in-tree, no extra package) over wget; crypto -# openssl (zlib + openssl come from the sysroot via PKG_CONFIG_PATH). -# - Disabled: docs (needs host scdoc), help/lua/python (needs lua/python), -# tests (CI runs upstream's suite, not the target build), zstd (no zstd -# package; our artifacts are gzip). No on-device man pages or embedded -# help DB yet - revisit when the operator story needs them. - -do_configure() { - mkdir -p "${WORK}/build" - cd "${WRKSRC}" - # --sysroot: sysroot glibc headers redirect to __isoc23_*, absent in host - # libc. Nothing from the host's /usr/include may mix in, so the kernel UAPI - # headers come from linux-longterm-headers in the sysroot. - export CFLAGS="${CFLAGS:-} --sysroot=${SYSROOT}" - export LDFLAGS="${LDFLAGS:-} --sysroot=${SYSROOT} -L${SYSROOT}/usr/lib -Wl,-rpath-link,${SYSROOT}/usr/lib" - muon setup \ - -Dprefix=/usr \ - -Ddocs=disabled \ - -Dhelp=disabled \ - -Dlua=disabled \ - -Dpython=disabled \ - -Dtests=disabled \ - -Dzstd=disabled \ - -Durl_backend=libfetch \ - -Dcrypto_backend=openssl \ - "${WORK}/build" -} - -do_build() { - muon -C "${WORK}/build" samu -} - -do_install() { - DESTDIR="${DESTDIR}" muon -C "${WORK}/build" install -} diff --git a/packages/linux-longterm/template b/packages/linux-longterm/template @@ -1,65 +0,0 @@ -# Template file for 'linux-longterm' -# -# One template, four outputs (driver subpackages): -# linux-longterm meta, depends linux=<version> -# linux-longterm-headers meta, depends linux-headers=<version> -# linux image + modules + maps (post-install: depmod) -# linux-headers sanitized headers_install (user API only - -# NOT a module-build tree; openbcm needs a -# follow-up, see mk/kernel.inc) -pkgname=linux-longterm -version=6.18.51 -revision=1 -short_desc="UNOS kernel meta - longterm line" -maintainer="finwo <finwo@pm.me>" -license="GPL-2.0-only" -homepage="https://www.kernel.org" -distfiles="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.51.tar.xz" -checksum=ba2f60f858bf4d1f929101faa356c93dc8b925b17aaa9f95eabd4627758df613 -# the meta points at this line's kernel build (exact pin incl. revision - -# apk's `=` only matches the full pkgver, so a bare version never matches) -depends="linux=${version}-r${revision}" -hostmakedepends="bc flex bison rsync depmod" -subpackages="linux-longterm-headers linux linux-headers" - -short_desc_linux_longterm_headers="UNOS kernel headers meta - longterm line" -depends_linux_longterm_headers="linux-headers=${version}-r${revision}" -short_desc_linux="Linux kernel image and modules" -depends_linux="busybox" -short_desc_linux_headers="Linux kernel sanitized headers" -depends_linux_headers= - -# Notes: -# - defconfig + deltas (see mk/kernel.inc for the shared mechanics). -# Verified against 6.18 defconfig: everything load-bearing except VRF -# (absent) and IKCONFIG (off) already defaults right; NEXTHOP is not a -# symbol at all (nexthop objects are unconditional core). MODULE_SIG -# already defaults off (no ephemeral signing keys). VRF's full dep -# chain (IP_MULTIPLE_TABLES + NET_L3_MASTER_DEV + IPV6_MULTIPLE_TABLES) -# is enabled explicitly - olddefconfig silently drops symbols whose -# deps are unmet, which is exactly what the asserts guard against. -# - linux needs busybox first: its post-install runs under /bin/sh -# (same ordering rule as the library packages). - -# shellcheck disable=SC1091 -. "${UNOS_MKDIR}/kernel.inc" - -KDELTA_ENABLE="IKCONFIG IKCONFIG_PROC NET_L3_MASTER_DEV IPV6_MULTIPLE_TABLES BLK_DEV_NVME MMC MMC_BLOCK BRIDGE VLAN_8021Q" -KDELTA_MODULE="NET_VRF" -KDELTA_DISABLE="" -KASSERT_Y="IPV6 IP_MULTIPLE_TABLES IPV6_MULTIPLE_TABLES NET_L3_MASTER_DEV DEVTMPFS_MOUNT BLK_DEV_INITRD SERIAL_8250_CONSOLE MODULES IKCONFIG IKCONFIG_PROC EFI_STUB BLK_DEV_NVME MMC MMC_BLOCK NVME_CORE BRIDGE VLAN_8021Q" -KASSERT_M="NET_VRF" -KASSERT_N="MODULE_SIG" - -do_configure() { kernel_configure; } -do_build() { kernel_build; } -do_install() { kernel_install; } - -sub_linux_longterm_headers() { :; } -sub_linux() { - spick boot - spick lib/modules -} -sub_linux_headers() { - spick usr/include -} diff --git a/packages/linux-mainline/template b/packages/linux-mainline/template @@ -1,63 +0,0 @@ -# Template file for 'linux-mainline' -# -# One template, four outputs (driver subpackages): -# linux-mainline meta, depends linux=<version> -# linux-mainline-headers meta, depends linux-headers=<version> -# linux image + modules + maps (post-install: depmod) -# linux-headers sanitized headers_install (user API only - -# NOT a module-build tree; openbcm needs a -# follow-up, see mk/kernel.inc) -# -# NOTE: mainline is a moving target by design (rc snapshots weekly). The -# pin below is TOFU: git.kernel.org publishes no sha256 for the torvalds -# snapshots (only .tar.sign PGP). Re-pin every bump, verify the tag out -# of band. -pkgname=linux-mainline -version=7.3_rc3 -revision=1 -short_desc="UNOS kernel meta - mainline snapshot" -maintainer="finwo <finwo@pm.me>" -license="GPL-2.0-only" -homepage="https://www.kernel.org" -distfiles="https://git.kernel.org/torvalds/t/linux-7.3-rc3.tar.gz" -checksum=49b24119d7b92da75bba0daf5da4f7735c8cb948757a282e849092dcc681d8dd -# the meta points at this line's kernel build (exact pin incl. revision - -# apk's `=` only matches the full pkgver, so a bare version never matches) -depends="linux=${version}-r${revision}" -hostmakedepends="bc flex bison rsync depmod" -subpackages="linux-mainline-headers linux linux-headers" - -short_desc_linux_mainline_headers="UNOS kernel headers meta - mainline snapshot" -depends_linux_mainline_headers="linux-headers=${version}-r${revision}" -short_desc_linux="Linux kernel image and modules" -depends_linux="busybox" -short_desc_linux_headers="Linux kernel sanitized headers" -depends_linux_headers= - -# Notes: same recipe as linux-longterm (defconfig + deltas, mk/kernel.inc). -# Deltas re-verified per line - symbols move between releases, the asserts -# fail loud if this list rots. KREL here is 7.3.0-rc3 (derived, not equal -# to the 7.3_rc3 apk version) - all install paths use KREL. - -# shellcheck disable=SC1091 -. "${UNOS_MKDIR}/kernel.inc" - -KDELTA_ENABLE="IKCONFIG IKCONFIG_PROC NET_L3_MASTER_DEV IPV6_MULTIPLE_TABLES BLK_DEV_NVME MMC MMC_BLOCK BRIDGE VLAN_8021Q" -KDELTA_MODULE="NET_VRF" -KDELTA_DISABLE="" -KASSERT_Y="IPV6 IP_MULTIPLE_TABLES IPV6_MULTIPLE_TABLES NET_L3_MASTER_DEV DEVTMPFS_MOUNT BLK_DEV_INITRD SERIAL_8250_CONSOLE MODULES IKCONFIG IKCONFIG_PROC EFI_STUB BLK_DEV_NVME MMC MMC_BLOCK NVME_CORE BRIDGE VLAN_8021Q" -KASSERT_M="NET_VRF" -KASSERT_N="MODULE_SIG" - -do_configure() { kernel_configure; } -do_build() { kernel_build; } -do_install() { kernel_install; } - -sub_linux_mainline_headers() { :; } -sub_linux() { - spick boot - spick lib/modules -} -sub_linux_headers() { - spick usr/include -} diff --git a/packages/linux-stable/template b/packages/linux-stable/template @@ -1,57 +0,0 @@ -# Template file for 'linux-stable' -# -# One template, four outputs (driver subpackages): -# linux-stable meta, depends linux=<version> -# linux-stable-headers meta, depends linux-headers=<version> -# linux image + modules + maps (post-install: depmod) -# linux-headers sanitized headers_install (user API only - -# NOT a module-build tree; openbcm needs a -# follow-up, see mk/kernel.inc) -pkgname=linux-stable -version=7.2.5 -revision=1 -short_desc="UNOS kernel meta - stable line" -maintainer="finwo <finwo@pm.me>" -license="GPL-2.0-only" -homepage="https://www.kernel.org" -distfiles="https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.2.5.tar.xz" -checksum=55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78 -# the meta points at this line's kernel build (exact pin incl. revision - -# apk's `=` only matches the full pkgver, so a bare version never matches) -depends="linux=${version}-r${revision}" -hostmakedepends="bc flex bison rsync depmod" -subpackages="linux-stable-headers linux linux-headers" - -short_desc_linux_stable_headers="UNOS kernel headers meta - stable line" -depends_linux_stable_headers="linux-headers=${version}-r${revision}" -short_desc_linux="Linux kernel image and modules" -depends_linux="busybox" -short_desc_linux_headers="Linux kernel sanitized headers" -depends_linux_headers= - -# Notes: same recipe as linux-longterm (defconfig + deltas, mk/kernel.inc). -# Deltas re-verified per line - symbols move between releases, the asserts -# fail loud if this list rots. - -# shellcheck disable=SC1091 -. "${UNOS_MKDIR}/kernel.inc" - -KDELTA_ENABLE="IKCONFIG IKCONFIG_PROC NET_L3_MASTER_DEV IPV6_MULTIPLE_TABLES BLK_DEV_NVME MMC MMC_BLOCK BRIDGE VLAN_8021Q" -KDELTA_MODULE="NET_VRF" -KDELTA_DISABLE="" -KASSERT_Y="IPV6 IP_MULTIPLE_TABLES IPV6_MULTIPLE_TABLES NET_L3_MASTER_DEV DEVTMPFS_MOUNT BLK_DEV_INITRD SERIAL_8250_CONSOLE MODULES IKCONFIG IKCONFIG_PROC EFI_STUB BLK_DEV_NVME MMC MMC_BLOCK NVME_CORE BRIDGE VLAN_8021Q" -KASSERT_M="NET_VRF" -KASSERT_N="MODULE_SIG" - -do_configure() { kernel_configure; } -do_build() { kernel_build; } -do_install() { kernel_install; } - -sub_linux_stable_headers() { :; } -sub_linux() { - spick boot - spick lib/modules -} -sub_linux_headers() { - spick usr/include -} diff --git a/tests/helpers.sh b/tests/helpers.sh @@ -52,10 +52,11 @@ assert_path_exists() { # a revision: doing so silently tests a stale artifact and then silently skips # once that artifact is pruned. newest_apk() { - # newest_apk <pkg> [arch] - _p=$1; _a=${2:-x86_64}; _root=${ROOT:?ROOT must be set} + # newest_apk <pkg> [arch] [channel] + _p=$1; _a=${2:-x86_64}; _c=${3:-${UNOS_CHANNEL:-lts}} + _root=${ROOT:?ROOT must be set} _found="" - for f in "${_root}/build/repo/${_a}/${_p}"-*.apk; do + for f in "${_root}/build/repo/${_c}/${_a}/${_p}"-*.apk; do [ -e "${f}" ] || continue # `zlib-1.3.1-r0.apk` belongs to zlib; `zlib-doc-...` does not, so require # the character after the name to begin a version field. @@ -69,9 +70,9 @@ newest_apk() { # Revision a template currently declares, so tests follow the template rather # than a copy of it that rots. template_pkgver() { - # template_pkgver <pkg> - _p=$1; _root=${ROOT:?ROOT must be set} - _t="${_root}/packages/${_p}/template" + # template_pkgver <pkg> [channel] + _p=$1; _c=${2:-${UNOS_CHANNEL:-lts}}; _root=${ROOT:?ROOT must be set} + _t="${_root}/build/channels/${_c}/packages/${_p}/template" [ -f "${_t}" ] || return 1 _v=$(sed -n 's/^version=//p' "${_t}" | head -1) _r=$(sed -n 's/^revision=//p' "${_t}" | head -1) diff --git a/tests/unit/test_ascii.sh b/tests/unit/test_ascii.sh @@ -12,7 +12,7 @@ echo "==> test_ascii: source and docs are pure ASCII" cd "$ROOT" hits=$(git ls-files -z \ ':!:build/**' \ - ':!:packages/unos-keys/files/**' \ + ':!:channels/*/packages/unos-keys/files/**' \ | xargs -0 grep -nIP '[^\x00-\x7F]' 2>/dev/null || true) if [ -n "$hits" ]; then @@ -25,7 +25,7 @@ echo "PASS: no non-ASCII in tracked sources" # Untracked working-tree sources count too, otherwise new files sneak past. new=$(git ls-files -zo --exclude-standard \ ':!:build/**' \ - ':!:packages/unos-keys/files/**' \ + ':!:channels/*/packages/unos-keys/files/**' \ | xargs -0 grep -nIP '[^\x00-\x7F]' 2>/dev/null || true) if [ -n "$new" ]; then diff --git a/tests/unit/test_deps.sh b/tests/unit/test_deps.sh @@ -65,10 +65,9 @@ assert_file_contains "${ROOT}/mk/bootstrap-host.sh" "-Dmeson-docs=disabled" "muo assert_file_contains "${ROOT}/mk/bootstrap-host.sh" "-Dmeson-tests=disabled" "muon tests subproject disabled (no build-time git fetch)" # --- the CI pipeline is generated from that same graph --------------------- -# .conductor.yml carries ~30 tasks and their `needs` edges. Hand-maintaining -# those against packages/*/template drifts, and the failure mode is a package -# building before the library it links against -- which usually still succeeds, -# quietly, against a stale copy. +# Hand-maintaining the `needs` edges drifts, and the failure mode is a package +# building against a stale copy of what it links against -- quietly, and still +# succeeding. [ -f "${ROOT}/.conductor.yml" ] || { echo "FAIL: no .conductor.yml" >&2; exit 1; } out=$("${ROOT}/mk/gen-pipeline.sh" --check 2>&1) || { echo "FAIL: .conductor.yml is out of date; run ./mk/gen-pipeline.sh --write" >&2 @@ -77,14 +76,25 @@ out=$("${ROOT}/mk/gen-pipeline.sh" --check 2>&1) || { } echo "PASS: .conductor.yml matches the dependency graph" -# Every package must have a task, or a push would silently not build it. -npkg=$("${ROOT}/mk/deps.sh" list | wc -l | tr -d ' ') +# Every package of every published channel must have a task, or a push would +# silently not build it. +expected=0 +for c in $("${ROOT}/mk/deps.sh" channels); do + n=$("${ROOT}/mk/deps.sh" --channel "$c" list | wc -l | tr -d ' ') + expected=$((expected + n)) + ntask=$(grep -c "^ pkg-${c}-" "${ROOT}/.conductor.yml") + assert_eq "$ntask" "$n" "every ${c} package has a pipeline task" + grep -q "^ index-${c}:" "${ROOT}/.conductor.yml" \ + && echo "PASS: ${c} has an index task" \ + || { echo "FAIL: ${c} has no index task" >&2; exit 1; } +done ntask=$(grep -c '^ pkg-' "${ROOT}/.conductor.yml") -assert_eq "$ntask" "$npkg" "every package has a pipeline task" +assert_eq "$ntask" "$expected" "no pipeline task outside a published channel" # The credentials the runner provides, and nothing invented alongside them. -assert_file_contains "${ROOT}/.conductor.yml" "BUCKET_ENDPOINT" "pipeline uses BUCKET_ENDPOINT" -assert_file_contains "${ROOT}/.conductor.yml" "BUCKET_NAME" "pipeline uses BUCKET_NAME" +# The rest of the BUCKET_* set is read inside publish.sh and bootstrap-repo.sh, +# which the pipeline calls but does not parameterise. +assert_file_contains "${ROOT}/.conductor.yml" "BUCKET_PUBLIC_URL" "pipeline uses BUCKET_PUBLIC_URL" if grep -q 'REPO_URL' "${ROOT}/.conductor.yml"; then echo "FAIL: pipeline references REPO_URL, which the runner does not provide" >&2 exit 1