Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
024e9308c9 | ||
|
|
eab1db2c3f | ||
|
|
22d7161c08 |
+179
-40
@@ -133,44 +133,100 @@ fi
|
|||||||
echo "[apk-sdk] feeds install (prefer shater feed)"
|
echo "[apk-sdk] feeds install (prefer shater feed)"
|
||||||
./scripts/feeds install -p shater shaterd shater-core byedpi luci-app-shater
|
./scripts/feeds install -p shater shaterd shater-core byedpi luci-app-shater
|
||||||
|
|
||||||
# --- .config: build a MINIMAL one FROM SCRATCH (never append to the SDK's) ---
|
# --- strip the SDK's generated per-package `default m` blocks ----------------
|
||||||
# The ImmortalWrt SDK ships the buildbot's fully-expanded .config, and that file
|
# Run 60 settled the question that runs 58 and 59 left open. Writing an explicit
|
||||||
# carries CONFIG_ALL_KMODS=y + CONFIG_ALL_NONSHARED=y (verifiable without the
|
# `# CONFIG_PACKAGE_kmod-x is not set` for all 1126 of them and re-running
|
||||||
# tarball: downloads.immortalwrt.org/releases/25.12.1/targets/*/config.buildinfo).
|
# defconfig deselected exactly nothing: the count came back 1078, unchanged.
|
||||||
# Appending our 4 packages to it left those in place, so `make defconfig`
|
# Meanwhile the very same explicit form DID stick for CONFIG_ALL/ALL_KMODS/
|
||||||
# re-selected EVERY kernel module of the target as =m; our kmod deps then pull in
|
# ALL_NONSHARED. The difference is prompts. kconfig only honours a user value for
|
||||||
# `package/kernel/linux/compile`, which builds and `apk mkpkg`s the whole set —
|
# a symbol that has one (sym_calc_value ignores S_DEF_USER for a promptless
|
||||||
# 3593 kmod-* packages (mlx5, amdgpu, isdn, ...) in the v0.2.2 run. On a runner
|
# symbol and falls back to its `default`), and the ALL* symbols carry prompts in
|
||||||
# under a 64 GB ZFS quota that is a guaranteed `Disk quota exceeded`.
|
# the SDK's own Config.in while these generated blocks are bare:
|
||||||
#
|
#
|
||||||
# Fix (same shape as Slava-Shchipunov/awg-openwrt's "Setup SDK and feeds" step):
|
# config PACKAGE_kmod-mlx5-core
|
||||||
# start the .config EMPTY so kconfig can only pull in what our 4 packages
|
# tristate
|
||||||
# actually select. Carried over from the SDK's .config, and nothing else:
|
# default m
|
||||||
# CONFIG_TARGET_<board>[_<subtarget>]=y — the target choice. An SDK ships
|
#
|
||||||
# exactly one target, so defconfig would almost certainly pick it anyway;
|
# So no value we write into .config can ever turn them off — the fix has to
|
||||||
# but guessing wrong means silently cross-compiling for the wrong arch, and
|
# remove the `default m` itself. That is what this does: drop every generated
|
||||||
# carrying two lines is far cheaper than that failure mode.
|
# `config PACKAGE_*` block from the SDK's Config-build.in before the first
|
||||||
# CONFIG_TARGET_{BOARD,SUBTARGET,ARCH_PACKAGES} — the string identities that
|
# defconfig. Nothing is lost by it — these blocks only replay which packages the
|
||||||
# name the bin/ paths and the package arch; kept so a mismatch is impossible.
|
# BUILDBOT happened to build; the packages themselves are still declared, with
|
||||||
# CONFIG_USE_APK — decides .apk vs .ipk output, i.e. the entire point of this
|
# prompts, by the package tree (tmp/.config-package.in), which is what makes our
|
||||||
# lane. 25.12 defaults it to y, but this lane must not depend on a default.
|
# four selectable and what `select` acts on. KERNEL_*/LIBC/TOOLCHAIN blocks are
|
||||||
# CONFIG_KERNEL_* (both `=y` and the `# ... is not set` form) — these feed
|
# left untouched, so the SDK still reproduces its own toolchain settings.
|
||||||
# straight into the generated kernel .config. The SDK ships a PREBUILT kernel
|
CB=$(find . -maxdepth 2 -name 'Config-build.in' -print -quit 2>/dev/null || true)
|
||||||
# tree, and our two nft kmods are packaged out of it; drop a knob the SDK's
|
if [ -n "$CB" ] && command -v perl >/dev/null 2>&1; then
|
||||||
# kernel was configured with and the buildsystem sees a changed kernel
|
pkg_before=$(grep -c '^config PACKAGE_' "$CB" || true)
|
||||||
# .config, reconfigures and REBUILDS the kernel — exactly the long, disk-hungry
|
# Paragraph-wise delete: a block is `config PACKAGE_x`, its indented body, and
|
||||||
# detour we are trying to avoid. Carrying them verbatim keeps that tree valid.
|
# the blank line that ends it. Anchored per-line (/m) so nothing else matches.
|
||||||
# Deliberately NOT carried: CONFIG_ALL*/CONFIG_PACKAGE_* (the bug itself);
|
perl -0777 -pi -e 's/^config PACKAGE_\S+\n(?:[ \t]+\S[^\n]*\n)+\n//gm' "$CB"
|
||||||
# CONFIG_TARGET_DEVICE_*/MULTI_PROFILE/ALL_PROFILES/PER_DEVICE_ROOTFS (image
|
pkg_after=$(grep -c '^config PACKAGE_' "$CB" || true)
|
||||||
# knobs — we only ever run `package/<p>/compile`, never build an image); and
|
echo "[apk-sdk] $CB: stripped $((pkg_before - pkg_after)) generated PACKAGE default blocks ($pkg_before -> $pkg_after)"
|
||||||
# CONFIG_BUILDBOT/CONFIG_COLLECT_KERNEL_DEBUG/CONFIG_JSON_CYCLONEDX_SBOM, which
|
else
|
||||||
# only add artifacts we neither ship nor have the disk for.
|
echo "[apk-sdk] WARNING: no Config-build.in found (or no perl) — per-package"
|
||||||
grep -E '^CONFIG_TARGET_[a-z0-9_]+=y$|^CONFIG_TARGET_(BOARD|SUBTARGET|ARCH_PACKAGES)=|^CONFIG_USE_APK=|^CONFIG_KERNEL_|^# CONFIG_KERNEL_[A-Za-z0-9_]+ is not set$' \
|
echo "[apk-sdk] 'default m' blocks stay; the kmod tripwire will catch it"
|
||||||
.config > .config.shater || true
|
fi
|
||||||
echo "[apk-sdk] .config rebuilt from scratch; $(wc -l < .config.shater) lines carried over"
|
|
||||||
echo "[apk-sdk] (CONFIG_KERNEL_* kept verbatim and not echoed; identity lines:)"
|
# --- .config: turn OFF the SDK's mass-select defaults ------------------------
|
||||||
grep -v '^\(# \)\?CONFIG_KERNEL_' .config.shater | sed 's/^/[apk-sdk] /' || true
|
# Symptom (v0.2.2, and still v0.2.3 run 58): the SDK ran `apk mkpkg` on ~1100
|
||||||
mv -f .config.shater .config
|
# kmod-* packages — mlx5, amdgpu, ata, isdn, none of which we ship — and died
|
||||||
|
# with `Disk quota exceeded` on the runner's 64 GB ZFS quota. Our kmod deps pull
|
||||||
|
# in `package/kernel/linux/compile`, which packs every module marked =m.
|
||||||
|
#
|
||||||
|
# Why they are =m has nothing to do with anything we write here. An OpenWrt SDK
|
||||||
|
# carries its OWN top-level Config.in (target/sdk/files/Config.in), and it reads:
|
||||||
|
#
|
||||||
|
# config ALL_NONSHARED
|
||||||
|
# bool "Select all target specific packages by default"
|
||||||
|
# default ALL
|
||||||
|
# config ALL_KMODS
|
||||||
|
# bool "Select all kernel module packages by default"
|
||||||
|
# default ALL
|
||||||
|
# config ALL
|
||||||
|
# bool "Select all userspace packages by default"
|
||||||
|
# default y <-- y, not n, and ONLY inside the SDK
|
||||||
|
#
|
||||||
|
# In the main tree those three default to n; the SDK flips ALL to y so that
|
||||||
|
# `make world` in a bare SDK builds something useful. So `make defconfig` on ANY
|
||||||
|
# .config — empty or not — selects the entire kernel. This is stock OpenWrt, not
|
||||||
|
# an ImmortalWrt quirk: openwrt/openwrt's target/sdk/files/Config.in is identical.
|
||||||
|
# (It also means the reference we copied, Slava-Shchipunov/awg-openwrt, builds
|
||||||
|
# every kmod too — it just never hits a disk quota on GitHub's runners.)
|
||||||
|
#
|
||||||
|
# Fix: state all three explicitly. They carry prompts in the SDK's Config.in, so
|
||||||
|
# they are user-settable and an explicit value beats the `default`. Note the FORM:
|
||||||
|
# kconfig writes a false bool as `# CONFIG_X is not set` and `CONFIG_X=n` is not
|
||||||
|
# reliably honoured, so `is not set` is the only form used here. All three are set
|
||||||
|
# rather than just the root `ALL`, so this keeps working whichever symbol a future
|
||||||
|
# SDK makes the root of the chain.
|
||||||
|
# Stash anything the SDK shipped (see below — today there is nothing) and start
|
||||||
|
# from a known-empty file, so what we build here is exactly what we intended.
|
||||||
|
if [ -s .config ]; then mv -f .config .config.sdk; fi
|
||||||
|
: > .config
|
||||||
|
for s in ALL ALL_KMODS ALL_NONSHARED; do
|
||||||
|
echo "# CONFIG_$s is not set" >> .config
|
||||||
|
done
|
||||||
|
|
||||||
|
# About that stash: an SDK tarball ships NO top-level .config (run 58 logged
|
||||||
|
# `grep: .config: No such file or directory` — the only `.config` inside the
|
||||||
|
# tarball is the prebuilt KERNEL's, under the linux dir). This is also why the
|
||||||
|
# first version of this fix was aimed at the wrong thing: there was never a
|
||||||
|
# buildbot .config here to append to. Nothing needs carrying over from it either,
|
||||||
|
# because
|
||||||
|
# target/sdk/Makefile bakes the buildbot's non-package settings — every
|
||||||
|
# CONFIG_KERNEL_* included — into the SDK's generated Config-build.in as kconfig
|
||||||
|
# `default`s (target/sdk/convert-config.pl). defconfig therefore reproduces the
|
||||||
|
# exact toolchain/kernel settings the SDK was built with, on its own; an earlier
|
||||||
|
# attempt to copy those lines by hand was redundant and is gone.
|
||||||
|
# Should a future SDK start shipping a .config, this keeps the two things that
|
||||||
|
# would then be worth honouring — the target identity and the package format —
|
||||||
|
# and still lets the lines above override the mass-select.
|
||||||
|
if [ -s .config.sdk ]; then
|
||||||
|
echo "[apk-sdk] SDK shipped a .config — carrying over target identity + format:"
|
||||||
|
grep -E '^CONFIG_TARGET_[a-z0-9_]+=y$|^CONFIG_TARGET_(BOARD|SUBTARGET|ARCH_PACKAGES)=|^CONFIG_USE_APK=' \
|
||||||
|
.config.sdk | tee -a .config | sed 's/^/[apk-sdk] /' || true
|
||||||
|
fi
|
||||||
|
|
||||||
for p in shaterd shater-core byedpi luci-app-shater; do
|
for p in shaterd shater-core byedpi luci-app-shater; do
|
||||||
echo "CONFIG_PACKAGE_$p=m" >> .config
|
echo "CONFIG_PACKAGE_$p=m" >> .config
|
||||||
@@ -190,6 +246,63 @@ fi
|
|||||||
echo "[apk-sdk] defconfig"
|
echo "[apk-sdk] defconfig"
|
||||||
make defconfig >/dev/null
|
make defconfig >/dev/null
|
||||||
|
|
||||||
|
# --- second pass: deselect the kernel, keep only what our packages select -----
|
||||||
|
# Turning ALL/ALL_KMODS/ALL_NONSHARED off (above) provably worked — run 59 shows
|
||||||
|
# all three as `is not set` after defconfig — and changed the kmod count by
|
||||||
|
# exactly zero, 1078 both times. The kmods are not selected through ALL_KMODS at
|
||||||
|
# all. They are selected one by one, and here is where from:
|
||||||
|
#
|
||||||
|
# target/sdk/Makefile:
|
||||||
|
# ./convert-config.pl $(TOPDIR)/.config > $(SDK_BUILD_DIR)/Config-build.in
|
||||||
|
#
|
||||||
|
# The SDK's Config-build.in is GENERATED from the buildbot's .config — a config
|
||||||
|
# in which ALL_KMODS=y had already expanded into a `CONFIG_PACKAGE_kmod-*=m` line
|
||||||
|
# per module. convert-config.pl turns every `CONFIG_X=<val>` line into a kconfig
|
||||||
|
# symbol carrying an unconditional `default <val>`; its `next if
|
||||||
|
# /^(# )?CONFIG_PACKAGE/` filter sits in the `else` branch, which a line with an
|
||||||
|
# `=` in it never reaches. So the SDK ships, verbatim, 1078 blocks of:
|
||||||
|
#
|
||||||
|
# config PACKAGE_kmod-mlx5-core
|
||||||
|
# tristate
|
||||||
|
# default m
|
||||||
|
#
|
||||||
|
# Nothing there consults ALL_KMODS, which is why switching it off was inert.
|
||||||
|
#
|
||||||
|
# Fix: give those symbols an explicit user value. We cannot do it before the
|
||||||
|
# first defconfig — the list of names only exists once kconfig has expanded the
|
||||||
|
# tree — so this is a second pass: rewrite every selected kmod to `is not set`
|
||||||
|
# and re-run defconfig. Two kconfig rules make the result exactly what we want,
|
||||||
|
# and both are already demonstrated in our own logs:
|
||||||
|
# * an explicit value in .config beats a `default` (this is precisely why the
|
||||||
|
# `# CONFIG_ALL* is not set` lines survived defconfig in run 59), so the
|
||||||
|
# ~1078 kmods we do not need stay off;
|
||||||
|
# * `select` is a reverse dependency, OR-ed into the symbol's value AFTER the
|
||||||
|
# user value in sym_calc_value(), so it cannot be overridden by an explicit
|
||||||
|
# `n`. shater-core's `DEPENDS:=+kmod-nft-tproxy +kmod-nft-socket` becomes
|
||||||
|
# `select PACKAGE_kmod-nft-tproxy` (scripts/package-metadata.pl: a `+` flag
|
||||||
|
# sets `$m = "select"`, and it re-emits the dependency's own depends too, so
|
||||||
|
# transitive kmods follow). Those come back on their own.
|
||||||
|
# Net effect: we build the handful of kmods our packages actually pull in.
|
||||||
|
#
|
||||||
|
# Rejected alternatives:
|
||||||
|
# * limiting what `package/kernel/linux/compile` packs — that target has no
|
||||||
|
# such knob; it iterates the selected set, so the selection IS the knob;
|
||||||
|
# * `package/kernel/linux/clean` + a targeted build — the kernel package would
|
||||||
|
# simply be rebuilt in full as a dependency of shater-core, same cost;
|
||||||
|
# * copying OpenWrt's own feed CI (openwrt/gh-action-sdk) — it does nothing
|
||||||
|
# about this; it just runs `make defconfig` and builds. Its one disk-related
|
||||||
|
# setting, CONFIG_AUTOREMOVE=y, is already the SDK's default;
|
||||||
|
# * editing the SDK's generated Config-build.in to strip the offending blocks —
|
||||||
|
# it would work, but it means parsing a generated kconfig file by hand and a
|
||||||
|
# format change would corrupt it silently. The two-pass approach uses only
|
||||||
|
# kconfig's documented semantics and leaves the evidence in .config.
|
||||||
|
kmods_all=$(grep -c '^CONFIG_PACKAGE_kmod-[^=]*=[my]$' .config || true)
|
||||||
|
if [ "$kmods_all" -gt 0 ]; then
|
||||||
|
echo "[apk-sdk] deselecting $kmods_all kmod packages, then defconfig again"
|
||||||
|
sed -i -E 's/^CONFIG_(PACKAGE_kmod-[^=]*)=[my]$/# CONFIG_\1 is not set/' .config
|
||||||
|
make defconfig >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
# --- post-defconfig sanity + disk-cost readout -------------------------------
|
# --- post-defconfig sanity + disk-cost readout -------------------------------
|
||||||
# A failed run leaves a ~27 MB log; digging the cause out of it is miserable, so
|
# A failed run leaves a ~27 MB log; digging the cause out of it is miserable, so
|
||||||
# print the handful of numbers that decide whether this run survives the
|
# print the handful of numbers that decide whether this run survives the
|
||||||
@@ -199,6 +312,25 @@ echo "[apk-sdk] target: board=$(sed -n 's/^CONFIG_TARGET_BOARD=//p' .config)" \
|
|||||||
"subtarget=$(sed -n 's/^CONFIG_TARGET_SUBTARGET=//p' .config)" \
|
"subtarget=$(sed -n 's/^CONFIG_TARGET_SUBTARGET=//p' .config)" \
|
||||||
"arch_packages=$(sed -n 's/^CONFIG_TARGET_ARCH_PACKAGES=//p' .config)"
|
"arch_packages=$(sed -n 's/^CONFIG_TARGET_ARCH_PACKAGES=//p' .config)"
|
||||||
echo "[apk-sdk] kmod packages selected (=m): $kmods"
|
echo "[apk-sdk] kmod packages selected (=m): $kmods"
|
||||||
|
# Proof the mass-select stayed off: these three must come back out of defconfig
|
||||||
|
# as `is not set`. If any reads `=y`, the SDK's `default ALL`/`default y` won and
|
||||||
|
# the kmod count above will be in the four digits.
|
||||||
|
echo "[apk-sdk] mass-select symbols after defconfig:"
|
||||||
|
grep -E '^(# )?CONFIG_ALL(_KMODS|_NONSHARED)?[ =]' .config | sed 's/^/[apk-sdk] /' || true
|
||||||
|
# After the second pass the only kmods left are the ones shater-core's
|
||||||
|
# `DEPENDS:=+kmod-nft-tproxy +kmod-nft-socket` turns into kconfig `select`s, plus
|
||||||
|
# whatever those select in turn — a handful. Worth printing verbatim while the
|
||||||
|
# list is short. A count of 0 is NOT fatal: those kmods ship in the router's own
|
||||||
|
# base feed, so apk resolves them there; but it would mean the selects did not
|
||||||
|
# fire, and that is something we want to see in the log rather than guess at.
|
||||||
|
if [ "$kmods" -le 30 ]; then
|
||||||
|
grep '^CONFIG_PACKAGE_kmod.*=m' .config | sed 's/^/[apk-sdk] /' || true
|
||||||
|
fi
|
||||||
|
# The two cache knobs are written before the first defconfig and have to survive
|
||||||
|
# both of them — losing DOWNLOAD_FOLDER silently costs us the dl/ cache, and
|
||||||
|
# losing LOCALMIRROR brings back the sourceware.org stalls. Cheap to just look.
|
||||||
|
echo "[apk-sdk] cache settings after defconfig:"
|
||||||
|
grep -E '^CONFIG_(LOCALMIRROR|DOWNLOAD_FOLDER)=' .config | sed 's/^/[apk-sdk] /' || true
|
||||||
echo "[apk-sdk] our packages after defconfig:"
|
echo "[apk-sdk] our packages after defconfig:"
|
||||||
grep -E '^CONFIG_PACKAGE_(shaterd|shater-core|byedpi|luci-app-shater)=' .config \
|
grep -E '^CONFIG_PACKAGE_(shaterd|shater-core|byedpi|luci-app-shater)=' .config \
|
||||||
| sed 's/^/[apk-sdk] /' || true
|
| sed 's/^/[apk-sdk] /' || true
|
||||||
@@ -221,9 +353,16 @@ done
|
|||||||
# packing the kernel before dying on `Disk quota exceeded`. Fail now instead.
|
# packing the kernel before dying on `Disk quota exceeded`. Fail now instead.
|
||||||
[ "$kmods" -le 200 ] || {
|
[ "$kmods" -le 200 ] || {
|
||||||
echo "[apk-sdk] ERROR: $kmods kmod packages selected — that is the whole kernel."
|
echo "[apk-sdk] ERROR: $kmods kmod packages selected — that is the whole kernel."
|
||||||
echo " CONFIG_ALL_KMODS/CONFIG_ALL is back in .config; aborting before"
|
echo " Aborting before this fills the runner's disk. Two causes are"
|
||||||
echo " this fills the runner's disk. Offending lines:"
|
echo " possible, and the lines below tell them apart:"
|
||||||
grep '^CONFIG_ALL' .config || true; exit 11; }
|
echo " (a) the mass-select is back on -> a CONFIG_ALL* line reads =y;"
|
||||||
|
echo " (b) the second pass did not take -> ALL* are 'is not set' but the"
|
||||||
|
echo " kmods returned anyway, i.e. the per-kmod 'default m' from the"
|
||||||
|
echo " SDK's generated Config-build.in outlived our explicit 'n'."
|
||||||
|
grep -E '^(# )?CONFIG_ALL(_KMODS|_NONSHARED)?[ =]' .config | sed 's/^/ /' || true
|
||||||
|
echo " first few kmods still selected:"
|
||||||
|
grep -m5 '^CONFIG_PACKAGE_kmod.*=m' .config | sed 's/^/ /' || true
|
||||||
|
exit 11; }
|
||||||
|
|
||||||
for p in shaterd shater-core byedpi luci-app-shater; do
|
for p in shaterd shater-core byedpi luci-app-shater; do
|
||||||
echo "[apk-sdk] === build $p ==="
|
echo "[apk-sdk] === build $p ==="
|
||||||
|
|||||||
Reference in New Issue
Block a user