mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-19 16:39:15 +00:00
Previously only the Electron GUI had installers; server admins had to build the
core by hand (`make build` -> bare binary). This adds a first-class server
distribution:
- `make core-dist` -> packaging/core-dist.sh -> cmd/build/dist/
llmsproxy_<ver>_amd64.deb (systemd unit + adapters + example config)
llmsproxy-<ver>.x86_64.rpm
llmsproxy-<ver>-linux-amd64.tar.gz
- nfpm config (packaging/nfpm.yaml): binary to /usr/bin, systemd unit with the
measured memory tuning (GOGC=50, MALLOC_ARENA_MAX=2) baked in, Lua adapters to
/usr/share/llmsproxy/adapters, repo's config.yaml as the example.
- postinst seeds /etc/llmsproxy/config.yaml on first install and keeps existing
runtime state across reinstalls; prerm stops the service on removal.
Gotchas handled: nfpm v2 here does not render `{{ .Env.VERSION }}`, so the script
stamps the version into a throwaway config copy; and under `set -o pipefail` the
idiom `strings | grep -q` is broken (grep -q closes the pipe and strings dies on
SIGPIPE -> spurious 141), so the symbol sanity-gate stages strings in a temp file.
README (zh/en) updated: memory figures replaced with production-measured
32-35 MB settled (was 37-42), and the packaging docs now describe core-dist and
the dockerized Windows build.
90 lines
3.7 KiB
Bash
Executable File
90 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build the llmsproxy CORE distribution packages (deb + rpm + tar.gz).
|
|
#
|
|
# Unlike the GUI packages (Electron), the core is a single static-ish binary
|
|
# that server admins install with dpkg/rpm. The systemd unit bakes in the
|
|
# memory tuning (GOGC=50, MALLOC_ARENA_MAX=2) measured on the production box.
|
|
#
|
|
# Requires: go, nfpm (PATH), dpkg-deb/rpmbuild for verification
|
|
# Outputs: cmd/build/dist/llmsproxy_<ver>_amd64.deb
|
|
# cmd/build/dist/llmsproxy-<ver>.x86_64.rpm
|
|
# cmd/build/dist/llmsproxy-<ver>-linux-amd64.tar.gz
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
VERSION="${1:-$(git describe --tags --dirty 2>/dev/null | sed 's/^v//' || echo 0.1.0)}"
|
|
DIST="$ROOT/cmd/build/dist"
|
|
BUILD_BIN="$ROOT/cmd/build/llmsproxy"
|
|
|
|
log() { printf '\033[1;34m[core-dist]\033[0m %s\n' "$*"; }
|
|
|
|
# nfpm is installed via `go install` -> lives in GOPATH/bin, which may not be
|
|
# on the caller's PATH (non-interactive shells, cron). Resolve it explicitly.
|
|
NFPM_BIN="$(command -v nfpm || true)"
|
|
[ -z "$NFPM_BIN" ] && [ -n "$(go env GOPATH)" ] && {
|
|
[ -x "$(go env GOPATH)/bin/nfpm" ] && NFPM_BIN="$(go env GOPATH)/bin/nfpm"
|
|
}
|
|
[ -n "$NFPM_BIN" ] || {
|
|
echo "[core-dist] nfpm missing. Install: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.41.2"
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p "$DIST"
|
|
|
|
# 1) build the core binary (luajit tag, -s -w like deploy.sh)
|
|
log "building core binary (luajit, stripped)..."
|
|
CGO_ENABLED=1 go build -tags luajit -trimpath -ldflags="-s -w" -o "$BUILD_BIN" ./cmd/llmsproxy
|
|
|
|
# 2) sanity gates: binary must contain the expected symbols and not be degenerate.
|
|
# NOTE under `set -o pipefail`, `strings | grep -q` is BROKEN: grep -q exits
|
|
# on first hit and closes the pipe, strings gets SIGPIPE -> pipeline returns
|
|
# 141 -> the check spuriously fails. Stage strings output in a temp file.
|
|
SYMS_TMP="$(mktemp)"
|
|
strings "$BUILD_BIN" > "$SYMS_TMP"
|
|
for sym in ProbeSlots reqRing shrinkStepLocked mergeUsage; do
|
|
grep -qF "$sym" "$SYMS_TMP" || {
|
|
echo "[core-dist] FATAL: binary missing expected symbol '$sym'"; rm -f "$SYMS_TMP"; exit 1
|
|
}
|
|
done
|
|
rm -f "$SYMS_TMP"
|
|
[ "$(stat -c%s "$BUILD_BIN")" -gt 5000000 ] || {
|
|
echo "[core-dist] FATAL: core binary implausibly small"; exit 1
|
|
}
|
|
log " ok: $(stat -c%s "$BUILD_BIN") bytes, symbols present"
|
|
|
|
# 3) deb + rpm via nfpm. nfpm v2 here does not render {{ .Env.VERSION }}, so
|
|
# stamp the version into a throwaway copy of the config; -t places the
|
|
# generated package in the dist dir.
|
|
log "packaging deb + rpm (v$VERSION)..."
|
|
NFPM_CFG="$(mktemp)" && sed "s/__VERSION__/$VERSION/g" "$ROOT/packaging/nfpm.yaml" > "$NFPM_CFG"
|
|
"$NFPM_BIN" package --config "$NFPM_CFG" --packager deb -t "$DIST"
|
|
"$NFPM_BIN" package --config "$NFPM_CFG" --packager rpm -t "$DIST"
|
|
rm -f "$NFPM_CFG"
|
|
|
|
# 4) tar.gz
|
|
log "packaging tar.gz..."
|
|
TAR_DIR="$DIST/llmsproxy-$VERSION-linux-amd64"
|
|
rm -rf "$TAR_DIR"; mkdir -p "$TAR_DIR"
|
|
cp "$BUILD_BIN" "$TAR_DIR/llmsproxy"
|
|
cp "$ROOT/config.yaml" "$TAR_DIR/config.example.yaml"
|
|
cp "$ROOT/packaging/llmsproxy.service" "$TAR_DIR/llmsproxy.service"
|
|
mkdir -p "$TAR_DIR/adapters"
|
|
cp "$ROOT"/internal/lua/adapters/*.lua "$TAR_DIR/adapters/"
|
|
tar -C "$DIST" -czf "$DIST/llmsproxy-$VERSION-linux-amd64.tar.gz" \
|
|
"$(basename "$TAR_DIR")"
|
|
rm -rf "$TAR_DIR"
|
|
|
|
# 5) verify artifacts are healthy (the same gate that would have caught the
|
|
# 264KB exe fiasco)
|
|
log "verifying packages..."
|
|
for f in "$DIST"/llmsproxy_*.deb "$DIST"/llmsproxy-*.rpm "$DIST"/*.tar.gz; do
|
|
[ -f "$f" ] || continue
|
|
sz=$(stat -c%s "$f")
|
|
[ "$sz" -gt 100000 ] || { echo "[core-dist] FATAL: $f suspiciously small ($sz B)"; exit 1; }
|
|
log " ✓ $f ($((sz/1024)) KB)"
|
|
done
|
|
dpkg-deb -I "$DIST"/llmsproxy_*.deb 2>/dev/null | grep -E 'Package|Version' | head -2
|
|
|
|
log "done: $DIST" |