mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 17:57:23 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 06a74375d8 | |||
| de9080e06c | |||
| 80e79f8dc7 | |||
| b6bbff19e9 |
14
cmd/gui/package-lock.json
generated
14
cmd/gui/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "modelrouter-gui",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "modelrouter-gui",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"license": "Proprietary",
|
||||
"devDependencies": {
|
||||
"electron": "^33.0.0",
|
||||
@ -1245,7 +1245,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
||||
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
|
||||
"dev": true,
|
||||
@ -2288,7 +2288,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/global-agent": {
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
|
||||
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
|
||||
"dev": true,
|
||||
@ -2532,7 +2532,7 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
@ -2715,7 +2715,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/matcher": {
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
|
||||
"dev": true,
|
||||
@ -3492,7 +3492,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "modelrouter-gui",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"description": "ModelRouter Desktop — embedded ModelRouter core with tray",
|
||||
"author": "ModelRouter",
|
||||
"main": "main.js",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# One-shot Windows release build for the GUI — ENTIRELY inside docker.
|
||||
#
|
||||
# 1) cross-compile the embedded core in docker (llmsproxy.exe + lua51.dll)
|
||||
# 1) cross-compile the embedded core in docker (modelrouter.exe + lua51.dll)
|
||||
# 2) electron-builder NSIS packaging ALSO inside docker (wine for the
|
||||
# uninstaller step lives in the image — see Dockerfile). This is the fix
|
||||
# for the 1.3.0/1.4.0 broken installers: the host had amd64-only wine
|
||||
@ -37,13 +37,15 @@ docker run --rm \
|
||||
-v "$ROOT":/workspace \
|
||||
-v "$CACHE_VOL":/root/.cache \
|
||||
-e GOPROXY="$PROXY" \
|
||||
-e ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/" \
|
||||
-e ELECTRON_BUILDER_BINARIES_MIRROR="https://npmmirror.com/mirrors/electron-builder-binaries/" \
|
||||
-w /workspace \
|
||||
"$IMAGE" bash -c '
|
||||
set -euo pipefail
|
||||
cp /opt/luajit2/src/lua51.dll /workspace/cmd/gui/bin/lua51.dll
|
||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc \
|
||||
go build -buildvcs=false -tags luajit -trimpath \
|
||||
-o /workspace/cmd/gui/bin/llmsproxy.exe ./cmd/llmsproxy
|
||||
go build -buildvcs=false -tags luajit -trimpath -ldflags "-s -w" \
|
||||
-o /workspace/cmd/gui/bin/modelrouter.exe ./cmd/modelrouter
|
||||
echo " -> core built"
|
||||
# wine needs one prefix initialization so its wow64 runtime (syswow64/ntdll)
|
||||
# exists — the exact thing that was missing on the broken host. Use a shared
|
||||
|
||||
@ -17,7 +17,10 @@ function buildLinux() {
|
||||
fs.mkdirSync(binDir, { recursive: true });
|
||||
execFileSync(
|
||||
"go",
|
||||
["build", "-tags", "luajit", "-trimpath", "-o", out, "./cmd/modelrouter"],
|
||||
// -s -w: same stripping as packaging/core-dist.sh. Without it the bundled
|
||||
// core carries debug info (~14.4 MB vs ~10.3 MB) and every installer pays
|
||||
// for it, for a binary the user never debugs.
|
||||
["build", "-tags", "luajit", "-trimpath", "-ldflags", "-s -w", "-o", out, "./cmd/modelrouter"],
|
||||
{ cwd: projectRoot, stdio: "inherit" },
|
||||
);
|
||||
return out;
|
||||
@ -43,7 +46,7 @@ function buildWin() {
|
||||
}
|
||||
execFileSync(
|
||||
"go",
|
||||
["build", "-tags", "luajit", "-trimpath", "-o", out, "./cmd/modelrouter"],
|
||||
["build", "-tags", "luajit", "-trimpath", "-ldflags", "-s -w", "-o", out, "./cmd/modelrouter"],
|
||||
{
|
||||
cwd: projectRoot,
|
||||
stdio: "inherit",
|
||||
|
||||
17
deploy.sh
17
deploy.sh
@ -115,6 +115,23 @@ precheck() {
|
||||
如需全新部署,先把旧目录移开:mv /etc/llmsproxy /etc/llmsproxy.bak"
|
||||
fi
|
||||
|
||||
# unit 与二进制路径必须一致。包安装把二进制放 /usr/bin,源码部署放
|
||||
# /usr/local/bin;unit 里写错一行,systemctl restart 只会给 203/EXEC,
|
||||
# 看起来像"部署成功但服务起不来"。此处提前拦住。
|
||||
local unit="/etc/systemd/system/modelrouter.service"
|
||||
if [[ -f "$unit" ]]; then
|
||||
local unit_exe
|
||||
unit_exe=$(awk -F'=' '/^ExecStart=/{print $2; exit}' "$unit" | awk '{print $1}')
|
||||
if [[ -n "$unit_exe" && "$unit_exe" != "$TARGET_BIN" && ! -x "$unit_exe" ]]; then
|
||||
fail "unit 的 ExecStart 指向 $unit_exe,但该文件不存在。
|
||||
包安装(deb/rpm)用 /usr/bin/modelrouter;源码部署(本脚本)用 $TARGET_BIN。
|
||||
请把 $unit 的 ExecStart 改成 $TARGET_BIN,或改用包安装。"
|
||||
fi
|
||||
if [[ -n "$unit_exe" && "$unit_exe" != "$TARGET_BIN" ]]; then
|
||||
warn "unit ExecStart=$unit_exe,而本脚本部署到 $TARGET_BIN(两者都存在,确认哪个该生效)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$NEW_CONFIG_SRC" ]]; then
|
||||
[[ -f "$NEW_CONFIG_SRC" ]] || fail "待部署配置不存在: $NEW_CONFIG_SRC"
|
||||
# 同一文件比对:--config 指向线上文件本身时没有"投放"动作可做,
|
||||
|
||||
@ -16,9 +16,14 @@ sudo ./deploy.sh --config other.yaml # 投放并部署另一份配置
|
||||
|
||||
部署目标(改名后):
|
||||
|
||||
| 项 | 路径 |
|
||||
> 两种布局并存,区别只在于二进制位置:**包安装**(deb/rpm)放 `/usr/bin`,
|
||||
> unit 自带;**源码部署**(`deploy.sh`)放 `/usr/local/bin`,需要让 unit 的
|
||||
> `ExecStart` 指向它。`deploy.sh` 会校验这一点,写错时直接中止而不是留下
|
||||
> 一个 203/EXEC 的服务。
|
||||
|
||||
| 项 | 路径(源码部署 / 包安装) |
|
||||
|---|---|
|
||||
| 二进制 | `/usr/local/bin/modelrouter` |
|
||||
| 二进制 | `/usr/local/bin/modelrouter` / `/usr/bin/modelrouter` |
|
||||
| 配置 | `/etc/modelrouter/config.yaml` |
|
||||
| 适配器 | `/etc/modelrouter/adapters/` |
|
||||
| 插件(可选) | `/etc/modelrouter/plugins/`(需在配置里设 `plugin_dir`) |
|
||||
|
||||
@ -20,19 +20,122 @@ BUILD_BIN="$ROOT/cmd/build/modelrouter"
|
||||
|
||||
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 is the primary packager, but it is a `go install` artifact and the build
|
||||
# host may be offline (no GOPROXY) — a release must not depend on being able to
|
||||
# fetch it. Fall back to dpkg-deb / rpmbuild, which are present wherever the
|
||||
# packages are actually verified. Both paths produce the same file layout.
|
||||
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
|
||||
}
|
||||
if [ -n "$NFPM_BIN" ]; then
|
||||
log "packager: nfpm ($NFPM_BIN)"
|
||||
else
|
||||
command -v dpkg-deb >/dev/null || { echo "[core-dist] neither nfpm nor dpkg-deb available"; exit 1; }
|
||||
command -v rpmbuild >/dev/null || { echo "[core-dist] neither nfpm nor rpmbuild available"; exit 1; }
|
||||
log "packager: nfpm missing -> dpkg-deb + rpmbuild fallback"
|
||||
fi
|
||||
|
||||
mkdir -p "$DIST"
|
||||
|
||||
# ---- fallback packagers -------------------------------------------------
|
||||
# Same file layout as packaging/nfpm.yaml. Kept in this file (not a separate
|
||||
# script) so the two paths cannot drift silently: both are exercised by the
|
||||
# archive-content gate at the end.
|
||||
package_deb_fallback() {
|
||||
local root="$ROOT/cmd/build/pkgroot-deb"
|
||||
rm -rf "$root"
|
||||
mkdir -p "$root/DEBIAN" "$root/usr/bin" "$root/etc/systemd/system" \
|
||||
"$root/usr/share/modelrouter/adapters" "$root/usr/share/doc/modelrouter"
|
||||
install -m 0755 "$BUILD_BIN" "$root/usr/bin/modelrouter"
|
||||
install -m 0644 "$ROOT/packaging/modelrouter.service" "$root/etc/systemd/system/modelrouter.service"
|
||||
install -m 0644 "$ROOT/packaging/config.example.yaml" "$root/usr/share/modelrouter/config.example.yaml"
|
||||
install -m 0644 "$ROOT"/internal/lua/adapters/*.lua "$root/usr/share/modelrouter/adapters/"
|
||||
install -m 0755 "$ROOT/packaging/install-browser-stack.sh" "$root/usr/share/modelrouter/install-browser-stack.sh"
|
||||
install -m 0644 "$ROOT/README.md" "$root/usr/share/doc/modelrouter/README.md"
|
||||
install -m 0755 "$ROOT/packaging/postinst.sh" "$root/DEBIAN/postinst"
|
||||
install -m 0755 "$ROOT/packaging/prerm.sh" "$root/DEBIAN/prerm"
|
||||
local inst_size
|
||||
inst_size=$(du -sk "$root" | awk '{print $1}')
|
||||
cat > "$root/DEBIAN/control" <<EOF
|
||||
Package: modelrouter
|
||||
Version: $VERSION
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Installed-Size: $inst_size
|
||||
Maintainer: JianFeeeee <dev@modelrouter.local>
|
||||
Recommends: ca-certificates
|
||||
Homepage: https://gitcode.com/JianFeeeee/ModelRouter
|
||||
Description: Unified OpenAI-compatible multi-source LLM gateway.
|
||||
Routes requests across multiple upstream LLM providers with Lua adapters,
|
||||
model scheduling, quota windows, an elastic Lua worker pool, and a Web UI.
|
||||
EOF
|
||||
dpkg-deb --root-owner-group -Zgzip --build "$root" \
|
||||
"$DIST/modelrouter_${VERSION}_amd64.deb" >/dev/null
|
||||
log " built $(basename "$DIST/modelrouter_${VERSION}_amd64.deb")"
|
||||
}
|
||||
|
||||
package_rpm_fallback() {
|
||||
local top="$ROOT/cmd/build/rpmbuild"
|
||||
rm -rf "$top"
|
||||
mkdir -p "$top"/{BUILD,RPMS,SOURCES,SPECS,BUILDROOT}
|
||||
local spec="$top/SPECS/modelrouter.spec"
|
||||
{
|
||||
cat <<EOF
|
||||
Name: modelrouter
|
||||
Version: $VERSION
|
||||
Release: 1
|
||||
Summary: Unified OpenAI-compatible multi-source LLM gateway
|
||||
License: MIT
|
||||
URL: https://gitcode.com/JianFeeeee/ModelRouter
|
||||
BuildArch: x86_64
|
||||
Requires: ca-certificates
|
||||
AutoReqProv: no
|
||||
%description
|
||||
Unified OpenAI-compatible multi-source LLM gateway. Routes requests across
|
||||
multiple upstream LLM providers with Lua adapters, model scheduling, quota
|
||||
windows, an elastic Lua worker pool, and a Web UI.
|
||||
%install
|
||||
mkdir -p %{buildroot}/usr/bin %{buildroot}/etc/systemd/system \\
|
||||
%{buildroot}/usr/share/modelrouter/adapters \\
|
||||
%{buildroot}/usr/share/doc/modelrouter %{buildroot}/etc/modelrouter
|
||||
install -m 0755 $BUILD_BIN %{buildroot}/usr/bin/modelrouter
|
||||
install -m 0644 $ROOT/packaging/modelrouter.service %{buildroot}/etc/systemd/system/modelrouter.service
|
||||
install -m 0644 $ROOT/packaging/config.example.yaml %{buildroot}/usr/share/modelrouter/config.example.yaml
|
||||
install -m 0644 $ROOT/internal/lua/adapters/*.lua %{buildroot}/usr/share/modelrouter/adapters/
|
||||
install -m 0755 $ROOT/packaging/install-browser-stack.sh %{buildroot}/usr/share/modelrouter/install-browser-stack.sh
|
||||
install -m 0644 $ROOT/README.md %{buildroot}/usr/share/doc/modelrouter/README.md
|
||||
%post
|
||||
EOF
|
||||
sed '1{/^#!/d}' "$ROOT/packaging/postinst.sh"
|
||||
# Script files may lack a trailing newline. Without this, `%preun` is glued
|
||||
# onto the last line of %post and the whole %files section is swallowed —
|
||||
# rpmbuild then fails with "Installed (but unpackaged) file(s) found".
|
||||
echo
|
||||
echo '%preun'
|
||||
sed '1{/^#!/d}' "$ROOT/packaging/prerm.sh"
|
||||
echo
|
||||
cat <<'EOF'
|
||||
%files
|
||||
/usr/bin/modelrouter
|
||||
/etc/systemd/system/modelrouter.service
|
||||
/usr/share/modelrouter
|
||||
/usr/share/doc/modelrouter/README.md
|
||||
%dir /etc/modelrouter
|
||||
EOF
|
||||
} > "$spec"
|
||||
rpmbuild --define "_topdir $top" --define "_binary_payload w9.gzdio" -bb "$spec" \
|
||||
>/dev/null 2>&1 || {
|
||||
echo "[core-dist] FATAL: rpmbuild failed; spec kept at $spec"; exit 1
|
||||
}
|
||||
local built
|
||||
built=$(find "$top/RPMS" -name 'modelrouter-*.rpm' | head -1)
|
||||
[ -n "$built" ] || { echo "[core-dist] FATAL: rpmbuild produced no rpm"; exit 1; }
|
||||
cp "$built" "$DIST/modelrouter-${VERSION}.x86_64.rpm"
|
||||
log " built $(basename "$DIST/modelrouter-${VERSION}.x86_64.rpm")"
|
||||
}
|
||||
|
||||
# 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/modelrouter
|
||||
@ -58,10 +161,15 @@ log " ok: $(stat -c%s "$BUILD_BIN") bytes, symbols present"
|
||||
# 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"
|
||||
if [ -n "$NFPM_BIN" ]; then
|
||||
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"
|
||||
else
|
||||
package_deb_fallback
|
||||
package_rpm_fallback
|
||||
fi
|
||||
|
||||
# 4) tar.gz
|
||||
log "packaging tar.gz..."
|
||||
|
||||
@ -15,7 +15,10 @@ Type=simple
|
||||
# the extra GC cycles are free.
|
||||
Environment=GOGC=50
|
||||
Environment=MALLOC_ARENA_MAX=2
|
||||
ExecStart=/usr/local/bin/modelrouter -config /etc/modelrouter/config.yaml
|
||||
# Package installs put the binary in /usr/bin (FHS). A source deployment via
|
||||
# deploy.sh uses /usr/local/bin — that script verifies the unit below points at
|
||||
# a binary that actually exists, so the two layouts cannot silently disagree.
|
||||
ExecStart=/usr/bin/modelrouter -config /etc/modelrouter/config.yaml
|
||||
WorkingDirectory=/etc/modelrouter
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
Reference in New Issue
Block a user