PKG_VERSION/PKG_RELEASE were hand-written literals nobody bumped, so
v0.2.2 … v0.2.6 all shipped as `shaterd 0.2.0-r3` with different binaries
inside (v0.2.6's ELF is 5 491 616 B against r2's 5 488 336 B). Both opkg
and apk offer an upgrade only when the feed's version string differs from
the installed one, so `apk update` saw nothing new and the routers could
not be updated through the normal path at all.
ci/version.sh is now the single source of truth. It derives the version
from `git describe`:
tag `vX.Y.Z` -> PKG_VERSION=X.Y.Z PKG_RELEASE=1
off-tag build -> nearest tag + PKG_RELEASE=<commits since it> + 1
no tag/no git -> 0.0.0-r1 (below everything ever published)
Ordering verified with the real tools, not from memory — apk-tools 3.0.3
(`apk version -t`) and opkg 38eccbb1 (`opkg compare-versions`) agree that
0.2.0-r3 < 0.2.6-r2 < 0.2.6-r10 < 0.2.6-r12 < 0.2.7-r1 < 0.3.0-r1, so a
release always outranks the rolling builds that preceded it and rolling
builds grow monotonically between releases.
The value travels as SHATER_PKG_VERSION/SHATER_PKG_RELEASE in the SDK
build environment of BOTH lanes; the Makefiles keep a literal fallback so
a manual/offline build still works with no CI and no git. Because the
hand-off crosses docker, `su` and make's env import, ci/sdk-build.sh and
ci/sdk-build-apk.sh now ASSERT that the produced .ipk/.apk really carries
that version — the B4 failure mode was a stale version shipping silently,
and that can no longer happen quietly.
The binary agrees with the package: scripts/build-shaterd.sh takes
constant.Version from the same ci/version.sh (vX.Y.Z-rR[-g<sha>]) instead
of its own `git describe`, and the workflow computes it once per job.
Both build jobs now check out with fetch-depth: 0 — `git describe` needs
tags and ancestry, which the default shallow checkout has neither of.
byedpi is deliberately left alone: PKG_VERSION:=0.17.3 is upstream
ByeDPI's own version, what PKG_HASH pins and what tells an operator which
ByeDPI is installed. Stamping our tag on it would also be a downgrade —
every comparator reads 0.2.7 < 0.17.3 (component-wise, 2 < 17), verified.
Docs: INSTALL.md gains §2.1 (the scheme + the ordering evidence), and the
update sections of §5/§6 now explicitly warn against a bare `opkg upgrade`
/ `apk upgrade` and give the targeted form instead, quoting apk-tools 3:
"If list of packages is provided, only those packages are upgraded along
with needed dependencies". README.md and the release bodies match.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
126 lines
5.8 KiB
Makefile
126 lines
5.8 KiB
Makefile
#
|
|
# shaterd — the single Shater v0.2 Go daemon (PREBUILT binary package).
|
|
#
|
|
# `shaterd` embeds the sing-box engine (box.New, in-process), the control-plane,
|
|
# the in-process DNS filter, the stats aggregator AND the admin-panel SPA
|
|
# (//go:embed all:webroot). shater-core's procd init supervises `shaterd run`;
|
|
# shater-core DEPENDS:=+shaterd, so THIS package is what resolves that dep.
|
|
#
|
|
# WHY PREBUILT (not from-source in the SDK)
|
|
# -----------------------------------------
|
|
# The shipped binary is the product of a toolchain the OpenWrt SDK cannot easily
|
|
# reproduce:
|
|
# * a Vite/npm build of the React SPA (Node is not guaranteed in an SDK env),
|
|
# * that SPA embedded via //go:embed all:webroot at `go build` time,
|
|
# * the D9 musl-static router tag set (CGO_ENABLED=0, fully static ET_EXEC),
|
|
# * a UPX --lzma --best pass (D10) that takes ~42 MB → ~10 MB.
|
|
# Reproducing npm + embed + UPX inside the SDK is fragile; instead we build the
|
|
# binary out-of-tree with scripts/build-shaterd.sh (host or CI) and package the
|
|
# arch-matched artifact. This mirrors the common Go+asset+UPX prebuilt pattern.
|
|
#
|
|
# HOW CI STAGES THE BINARY
|
|
# ------------------------
|
|
# scripts/build-shaterd.sh copies its output into this package's files/ dir:
|
|
# dist/shaterd-<a>.upx -> openwrt/shaterd/files/shaterd-<a>.upx (a ∈ amd64,arm64)
|
|
# The SDK build then picks files/shaterd-$(ARCH-mapped).upx below. So CI order is:
|
|
# 1) scripts/build-shaterd.sh (produces + stages both arches)
|
|
# 2) copy openwrt/* into the SDK feed, `make package/shaterd/compile`
|
|
# The staged binaries are gitignored (they are release artifacts, not source).
|
|
#
|
|
# The binary is a fully static musl-safe ELF, so DEPENDS is empty (no libc/shared
|
|
# deps). The data-plane kmods + ip-full live on shater-core.
|
|
#
|
|
|
|
include $(TOPDIR)/rules.mk
|
|
|
|
PKG_NAME:=shaterd
|
|
|
|
# VERSIONING — derived from the git tag, NOT hand-maintained here (bug B4).
|
|
# ci/version.sh turns `git describe` into SHATER_PKG_VERSION/SHATER_PKG_RELEASE
|
|
# (tag vX.Y.Z -> X.Y.Z + r1; off-tag -> last tag + r<commits+1>), and
|
|
# ci/build-feed.sh / ci/build-feed-apk.sh export them into the SDK build env of
|
|
# both lanes. Both lanes then ASSERT that the produced .ipk/.apk really carries
|
|
# that version, so a lost env can never silently ship a stale one again.
|
|
# The literals below are ONLY the manual/offline fallback (no CI, no git) — they
|
|
# are not "the release version"; releases are named by the tag.
|
|
PKG_VERSION:=$(if $(SHATER_PKG_VERSION),$(SHATER_PKG_VERSION),0.2.0)
|
|
PKG_RELEASE:=$(if $(SHATER_PKG_RELEASE),$(SHATER_PKG_RELEASE),1)
|
|
|
|
PKG_MAINTAINER:=Shater <maqrota@icloud.com>
|
|
PKG_LICENSE:=GPL-3.0-or-later
|
|
|
|
include $(INCLUDE_DIR)/package.mk
|
|
|
|
# Map the OpenWrt target $(ARCH) to the scripts/build-shaterd.sh artifact suffix.
|
|
# Extend BOTH this map and ARCHES in build-shaterd.sh to publish more router arches.
|
|
# x86_64 -> amd64 (x86 routers / the test VM)
|
|
# aarch64 -> arm64 (both BPI routers are aarch64_cortex-a53)
|
|
SHATERD_ARTIFACT:=$(strip \
|
|
$(if $(filter x86_64,$(ARCH)),amd64,\
|
|
$(if $(filter aarch64,$(ARCH)),arm64,)))
|
|
|
|
SHATERD_BIN:=shaterd-$(SHATERD_ARTIFACT).upx
|
|
|
|
# The staged binary is already UPX-compressed; the SDK's default RSTRIP pass would
|
|
# corrupt a packed executable, so disable stripping for this package (no-op `:`).
|
|
RSTRIP:=:
|
|
STRIP:=:
|
|
|
|
define Package/shaterd
|
|
SECTION:=net
|
|
CATEGORY:=Network
|
|
TITLE:=Shater v0.2 daemon (prebuilt static musl, SPA-embedded, UPX)
|
|
URL:=https://github.com/shater
|
|
# Static musl ELF (CGO_ENABLED=0): no shared-lib deps beyond the kernel.
|
|
DEPENDS:=
|
|
endef
|
|
|
|
define Package/shaterd/description
|
|
The single Shater v0.2 daemon. One long-lived Go process that embeds the
|
|
sing-box engine (in-process, box.New), the control-plane, the in-process DNS
|
|
filter, the statistics aggregator and the embedded Faceplate admin-panel SPA.
|
|
Supervised by shater-core's procd init as `shaterd run`. This package ships a
|
|
prebuilt, statically-linked (musl-safe), UPX-compressed binary produced out of
|
|
tree by scripts/build-shaterd.sh (npm SPA build + //go:embed + D9 tags + D10 UPX).
|
|
endef
|
|
|
|
# Nothing to fetch. Build/Compile only VALIDATES that the arch-matched prebuilt
|
|
# artifact was staged (scripts/build-shaterd.sh) before the SDK build.
|
|
define Build/Prepare
|
|
mkdir -p $(PKG_BUILD_DIR)
|
|
endef
|
|
|
|
define Build/Compile
|
|
$(if $(SHATERD_ARTIFACT),,$(error shaterd: no prebuilt artifact mapped for OpenWrt ARCH '$(ARCH)'. Add it to scripts/build-shaterd.sh (ARCHES) and the ARCH map in openwrt/shaterd/Makefile))
|
|
@test -f $(CURDIR)/files/$(SHATERD_BIN) || { \
|
|
echo "shaterd: staged binary files/$(SHATERD_BIN) not found."; \
|
|
echo " Run scripts/build-shaterd.sh first — it stages dist/shaterd-$(SHATERD_ARTIFACT).upx"; \
|
|
echo " into openwrt/shaterd/files/$(SHATERD_BIN) for ARCH=$(ARCH)."; \
|
|
exit 1; }
|
|
endef
|
|
|
|
define Package/shaterd/install
|
|
$(INSTALL_DIR) $(1)/usr/bin
|
|
$(INSTALL_BIN) $(CURDIR)/files/$(SHATERD_BIN) $(1)/usr/bin/shaterd
|
|
endef
|
|
|
|
# This package ships ONLY the binary — no init script — so opkg's default
|
|
# postinst never touches the running service. On `opkg upgrade shaterd` the new
|
|
# ELF lands at /usr/bin/shaterd while the OLD image keeps running from its
|
|
# unlinked inode: the upgrade silently has no effect until the next reboot, and
|
|
# meanwhile the new CLI (`shaterd reconcile`, `status`, `mint-token` — invoked by
|
|
# cron/hotplug/rpcd) talks over the control socket to an old daemon. Restart the
|
|
# service here, but ONLY if it was actually running, so a first install (where
|
|
# shater-core may not be unpacked yet) and offline image builds stay untouched.
|
|
define Package/shaterd/postinst
|
|
#!/bin/sh
|
|
[ -n "$${IPKG_INSTROOT}" ] && exit 0
|
|
if [ -x /etc/init.d/shater ] && pidof shaterd >/dev/null 2>&1; then
|
|
logger -t shaterd -p daemon.notice "binary upgraded — restarting the shater service"
|
|
/etc/init.d/shater restart >/dev/null 2>&1
|
|
fi
|
|
exit 0
|
|
endef
|
|
|
|
$(eval $(call BuildPackage,shaterd))
|