build: an apk-managed root, with SchOS as a package
make aroot builds a SchFS root from Alpine's minirootfs, the packages ports/alpine/world lists, and SchOS itself as the signed apk package schos-base, in its own repository inside the root. apk add installs from Alpine; apk upgrade updates both. Booted: zsh is Alpine's, apk update sees 28669 packages, apk add htop works, and so does xorg-server. world.lock pins every package with its sha256; a build fetches only what dist/alpine/ lacks and never looks for newer versions. make alpine-lock is the one step that does. Alpine's zsh, busybox commands and hwdata replace SchOS's copies; SchOS keeps its own tools, toybox's other commands, and static mksh, which schinit's recovery shell now tries first. Also: the dependency-file include matched Alpine's usr/lib/sysctl.d, a directory, and stopped every make. See docs/plan/alpine.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
2c5a278d56
commit
406cff2ec0
9 changed files with 473 additions and 1 deletions
80
ports/alpine/Makefile
Normal file
80
ports/alpine/Makefile
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Alpine Linux -- the base the apk-managed root is built on: https://alpinelinux.org/
|
||||
#
|
||||
# Alpine is musl with a different init, which is what SchOS is, and its
|
||||
# binaries run here unmodified -- Alpine's own dynamic linker, busybox, and
|
||||
# apk with TLS. So rather than port each program by hand, the root becomes an
|
||||
# Alpine root that apk manages, with SchOS's own programs as an apk package of
|
||||
# their own (schos-base, built by tools/posix/mkaroot.sh).
|
||||
#
|
||||
# Two downloads, both pinned:
|
||||
# the minirootfs musl, busybox, apk-tools, alpine-keys, ca-certificates:
|
||||
# the smallest root apk can work in
|
||||
# apk.static apk itself, static, for the build host: it makes the
|
||||
# schos-base package and its index, and installs it into
|
||||
# the root, without anything from Alpine on the host
|
||||
#
|
||||
# Nothing goes into sysroot/: this is input to the root image, not part of the
|
||||
# ramdisk-root system.
|
||||
|
||||
include ../mk/port.mk
|
||||
|
||||
ALPINE_BRANCH := 3.24
|
||||
ALPINE_VERSION := 3.24.3
|
||||
ALPINE_MIRROR := https://dl-cdn.alpinelinux.org/alpine/v$(ALPINE_BRANCH)
|
||||
|
||||
MINI := alpine-minirootfs-$(ALPINE_VERSION)-x86_64.tar.gz
|
||||
MINI_URL := $(ALPINE_MIRROR)/releases/x86_64/$(MINI)
|
||||
MINI_SHA256 := f8e1cafba9b1b283b5d30d06f9885c8d2bc161ffe9083ade8e2e157813a53407
|
||||
|
||||
APKS := apk-tools-static-3.0.8-r0.apk
|
||||
APKS_URL := $(ALPINE_MIRROR)/main/x86_64/$(APKS)
|
||||
# Recorded on first download. Alpine signs the package itself, but nothing on
|
||||
# the build host could check that signature before apk.static exists.
|
||||
APKS_SHA256 := c8e2c88c13ba12a12269b79a3543e1190ff8c0ab0beb32b58cadfd5881c619e3
|
||||
|
||||
APK_STATIC := $(PORTDIR)/apk.static
|
||||
|
||||
$(DISTDIR)/$(MINI): | $(DISTDIR)
|
||||
curl -fsSL -o $@ $(MINI_URL)
|
||||
sh $(SHA256CHECK) "$(MINI_SHA256)" "$@"
|
||||
|
||||
$(DISTDIR)/$(APKS): | $(DISTDIR)
|
||||
curl -fsSL -o $@ $(APKS_URL)
|
||||
sh $(SHA256CHECK) "$(APKS_SHA256)" "$@"
|
||||
|
||||
download: $(DISTDIR)/$(MINI) $(DISTDIR)/$(APKS)
|
||||
|
||||
# An .apk is gzipped tar streams back to back; tar reads through them and
|
||||
# warns about the signature's odd headers, which is harmless.
|
||||
$(APK_STATIC): $(DISTDIR)/$(APKS)
|
||||
mkdir -p $(PORTDIR)/x
|
||||
tar -xzf $< -C $(PORTDIR)/x 2>/dev/null || test -f $(PORTDIR)/x/sbin/apk.static
|
||||
cp $(PORTDIR)/x/sbin/apk.static $@
|
||||
rm -rf $(PORTDIR)/x
|
||||
|
||||
build install: $(APK_STATIC) $(DISTDIR)/$(MINI) world
|
||||
|
||||
clean:
|
||||
rm -rf $(PORTDIR)
|
||||
|
||||
# world.lock's packages, into dist/alpine/. Only what is missing is fetched,
|
||||
# and each file is checked against the lock: a build never asks Alpine what
|
||||
# is newer. `make alpine-lock` at the top level is what does that.
|
||||
WORLD_DIST := $(DISTDIR)/alpine
|
||||
|
||||
world: | $(DISTDIR)
|
||||
mkdir -p $(WORLD_DIST)
|
||||
grep -v '^#' world.lock | while read -r f sum repo; do \
|
||||
if [ ! -f $(WORLD_DIST)/$$f ]; then \
|
||||
echo "alpine: fetching $$f"; \
|
||||
curl -fsSL -o $(WORLD_DIST)/$$f.part $(ALPINE_MIRROR)/$$repo/x86_64/$$f && \
|
||||
mv $(WORLD_DIST)/$$f.part $(WORLD_DIST)/$$f || exit 1; \
|
||||
fi; \
|
||||
sh $(SHA256CHECK) "$$sum" $(WORLD_DIST)/$$f >/dev/null || exit 1; \
|
||||
done
|
||||
|
||||
lock: $(APK_STATIC) $(DISTDIR)/$(MINI)
|
||||
sh $(TOPDIR)/tools/posix/alpine-lock.sh $(APK_STATIC) $(DISTDIR)/$(MINI) \
|
||||
world world.lock $(WORLD_DIST)
|
||||
|
||||
.PHONY: world lock
|
||||
18
ports/alpine/world
Normal file
18
ports/alpine/world
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Alpine packages built into the apk-managed root, one per line.
|
||||
#
|
||||
# Edit this, then run `make alpine-lock` to resolve it, with every dependency,
|
||||
# into world.lock -- exact versions and checksums. A normal build installs
|
||||
# exactly what world.lock says from dist/alpine/, downloading only files it
|
||||
# does not have yet, and never asks Alpine what is newer. That happens only
|
||||
# when you run `make alpine-lock` again.
|
||||
#
|
||||
# Anything else is one `apk add` away on the running system; this list is
|
||||
# what a fresh image starts with.
|
||||
|
||||
# The login shell. Replaces SchOS's own zsh port.
|
||||
zsh
|
||||
# Terminal descriptions for zsh, htop, and everything else that draws.
|
||||
ncurses-terminfo-base
|
||||
# The PCI and USB ID databases: lspci, fastfetch and Xorg read them.
|
||||
hwdata-pci
|
||||
hwdata-usb
|
||||
12
ports/alpine/world.lock
Normal file
12
ports/alpine/world.lock
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Generated by tools/posix/alpine-lock.sh from world. Do not edit;
|
||||
# change world and run `make alpine-lock`.
|
||||
# file sha256 repository
|
||||
busybox-1.37.0-r31.apk 0e626fa97cf937fda7bba4ed4dde8e2f2dbb5083ac34e02180cec0c4eba9351b main
|
||||
busybox-binsh-1.37.0-r31.apk 93f803ae5db6b729c0f66f4afba6e907ccc17d7d5f8b8c3d25bdb4636de2c48a main
|
||||
hwdata-pci-0.408-r0.apk fe61404e6d2bd1e04c021d53641c0ebce97911084d77994e43a288a1278686c1 main
|
||||
hwdata-usb-0.408-r0.apk 272d365cb05dd085dd8022154cf71e3f3b0aaddd41c1269eeaf939c9d38675c8 main
|
||||
libcap2-2.78-r0.apk 42886a7b4bcde26347c712925c8dc7db202b6029ef9b8c7ee81577ab7bdd8fad main
|
||||
libncursesw-6.6_p20260516-r0.apk cf8caa8a88bc4ce9d9e395567fefaf9ef7fbd55c50ae6155b35c1b58f3755023 main
|
||||
musl-1.2.6-r3.apk e142255d0fa397f14318996bc10378093dcc069dc3dd1b6818c8f28a789c21da main
|
||||
ncurses-terminfo-base-6.6_p20260516-r0.apk ce83be6d0bd10584a53c3a5868cc1595ce5f0f8e0b621f8f7f70b6144e521fc9 main
|
||||
zsh-5.9-r7.apk 22ec3c4de69e38437e351ba5a881f5d88e9b518a248c8aa06d36b148cf16ce32 main
|
||||
Loading…
Reference in a new issue