mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
产品名早已是 ModelRouter,但仓库标识符仍沿用旧名。这次统一,读写两侧都做兼容, 已部署的机器不会因为顺序问题立刻失效。 - go module `llmsproxy` → `modelrouter`;全仓 import 与 `cmd/modelrouter` 同步。 - `Makefile BINARY=modelrouter`;发行包名、systemd unit、/usr/share 资源、 `/usr/local/bin` 目标全部改为 modelrouter。 - 默认配置目录 `/etc/llmsproxy` → `/etc/modelrouter`。**读取侧回退**:插件与 `storeDir` 仍会检查旧路径,所以"先换二进制、后改 unit"不会立即失效。 - 环境变量 `LLMSPROXY_*`(PLUGIN_DIR / XDISPLAY_BASE / ARCH / LIVE_ZEN / BUILD_DIR)改为 `MODELROUTER_*`;`LLMS_PROXY_MASTER_KEY` → `MODELROUTER_MASTER_KEY`。旧名在读取侧继续接受。 - 桌面端内嵌核心 `bin/llmsproxy` → `bin/modelrouter`,并保留旧文件名回退, 避免升级到一半的 profile 被判成"core binary missing"。 - 新增 `packaging/migrate-to-modelrouter.sh`:**默认 dry-run**,复制而非移动、 旧目录永不删除、支持 `--rollback`;随 release tar 分发并由 core-dist 校验。 - `deploy.sh` 增加改名保护:发现旧 `/etc/llmsproxy` 而新配置不存在时**中止**, 否则会部署出一个"能启动但没有 key、没有源"的空实例。 - 临时目录前缀 `/tmp/llmsproxy-*` → `/tmp/modelrouter-*`;清理逻辑同时回收两代。 兼容别名(`__llmsproxy_*` 全局、`llmsproxy` SDK 别名、旧路径/旧 env)刻意保留, 它们是升级路径而非遗留;docs/plugins.md 已标注为废弃。 本提交未包含:`adapters/opencodezen.lua`、`adapter_opencodezen_test.go`、 `adapter_opencodezen_live_test.go`(OpenCode UA/免费池的既有改动,另批提交)。
202 lines
6.8 KiB
Bash
Executable File
202 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# migrate-to-modelrouter.sh — 把 llmsproxy 时代的部署迁到 modelrouter 命名。
|
||
#
|
||
# 背景:产品名早已是 ModelRouter,但二进制/配置目录/服务名/插件目录仍沿用
|
||
# 仓库旧名 llmsproxy。这次改名不留"半新半旧"的机器:脚本复制(不是移动)
|
||
# 旧目录到新路径、改写 systemd unit、安装新二进制,并在最后做一遍校验。
|
||
#
|
||
# 安全约定:
|
||
# * **默认 dry-run**,只打印将要做什么;加 --apply 才真正执行。
|
||
# * 旧目录**永不删除**,迁移结束仍可 `--rollback` 回到旧布局。
|
||
# * 已存在的新路径不会被静默覆盖:先备份成 .bak-<时间戳>,再写入。
|
||
# * 不自动重启正在运行的服务,除非显式 --restart。
|
||
#
|
||
# 用法:
|
||
# sudo ./packaging/migrate-to-modelrouter.sh # 预演
|
||
# sudo ./packaging/migrate-to-modelrouter.sh --apply # 执行
|
||
# sudo ./packaging/migrate-to-modelrouter.sh --apply --restart
|
||
# sudo ./packaging/migrate-to-modelrouter.sh --rollback --apply
|
||
set -euo pipefail
|
||
|
||
OLD_NAME="llmsproxy"
|
||
NEW_NAME="modelrouter"
|
||
OLD_ETC="/etc/${OLD_NAME}"
|
||
NEW_ETC="/etc/${NEW_NAME}"
|
||
OLD_BIN="/usr/local/bin/${OLD_NAME}"
|
||
NEW_BIN="/usr/local/bin/${NEW_NAME}"
|
||
OLD_UNIT="/etc/systemd/system/${OLD_NAME}.service"
|
||
NEW_UNIT="/etc/systemd/system/${NEW_NAME}.service"
|
||
OLD_SHARE="/usr/share/${OLD_NAME}"
|
||
NEW_SHARE="/usr/share/${NEW_NAME}"
|
||
|
||
APPLY=0
|
||
RESTART=0
|
||
ROLLBACK=0
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
--apply) APPLY=1 ;;
|
||
--restart) RESTART=1 ;;
|
||
--rollback) ROLLBACK=1 ;;
|
||
-h|--help) sed -n '2,30p' "$0"; exit 0 ;;
|
||
*) echo "unknown argument: $arg" >&2; exit 2 ;;
|
||
esac
|
||
done
|
||
|
||
ok() { printf ' \033[32m✓\033[0m %s\n' "$*"; }
|
||
skip() { printf ' \033[90m·\033[0m %s\n' "$*"; }
|
||
plan() { printf ' \033[33m→\033[0m %s\n' "$*"; }
|
||
die() { printf '\033[31mfail\033[0m %s\n' "$*" >&2; exit 1; }
|
||
|
||
run() {
|
||
if [ "$APPLY" -eq 1 ]; then
|
||
"$@"
|
||
else
|
||
printf ' [dry-run] %s\n' "$*"
|
||
fi
|
||
}
|
||
|
||
backup_if_exists() {
|
||
local p="$1"
|
||
if [ -e "$p" ]; then
|
||
local b="${p}.bak-$(date +%Y%m%d%H%M%S)"
|
||
plan "备份已存在的 $p → $b"
|
||
run cp -a "$p" "$b"
|
||
fi
|
||
}
|
||
|
||
stamp() { date +%Y%m%d%H%M%S; }
|
||
|
||
if [ "$(id -u)" -ne 0 ] && [ "$APPLY" -eq 1 ]; then
|
||
die "--apply 需要 root(会写 /etc 与 /usr/local/bin)"
|
||
fi
|
||
|
||
if [ "$ROLLBACK" -eq 1 ]; then
|
||
echo "== 回滚到 ${OLD_NAME} 布局 =="
|
||
[ -d "$NEW_ETC" ] || die "$NEW_ETC 不存在,没有可回滚的内容"
|
||
if [ -e "$OLD_ETC" ]; then
|
||
plan "$OLD_ETC 已存在,保留它(回滚包在 ${NEW_ETC} 原地)"
|
||
plan "如需覆盖请先手工比对:diff -r $OLD_ETC $NEW_ETC"
|
||
else
|
||
plan "复制 $NEW_ETC → $OLD_ETC(不删除新目录)"
|
||
run cp -a "$NEW_ETC" "$OLD_ETC"
|
||
fi
|
||
if [ -e "$NEW_UNIT" ]; then
|
||
plan "恢复 $OLD_UNIT"
|
||
run cp "$NEW_UNIT" "$OLD_UNIT"
|
||
run sed -i "s#${NEW_NAME}#${OLD_NAME}#g" "$OLD_UNIT"
|
||
fi
|
||
if [ "$RESTART" -eq 1 ]; then
|
||
run systemctl daemon-reload
|
||
run systemctl enable --now "${OLD_NAME}.service"
|
||
fi
|
||
echo
|
||
echo "回滚$( [ "$APPLY" -eq 1 ] && echo '完成' || echo '预演完成(未改动任何文件)' )"
|
||
exit 0
|
||
fi
|
||
|
||
echo "== 迁移 ${OLD_NAME} → ${NEW_NAME}$( [ "$APPLY" -eq 1 ] && echo '' || echo '(dry-run,加 --apply 执行)' ) =="
|
||
echo
|
||
|
||
# ---- 1. 状态目录 -------------------------------------------------------
|
||
echo "[1/5] 配置与状态目录"
|
||
if [ -d "$OLD_ETC" ]; then
|
||
if [ -d "$NEW_ETC" ]; then
|
||
ok "$NEW_ETC 已存在,保持不动(旧目录仍保留在 $OLD_ETC)"
|
||
plan "合并前请人工比对:diff -r $OLD_ETC $NEW_ETC"
|
||
else
|
||
plan "复制 $OLD_ETC → $NEW_ETC(保留原目录,可回滚)"
|
||
run cp -a "$OLD_ETC" "$NEW_ETC"
|
||
fi
|
||
else
|
||
skip "$OLD_ETC 不存在,跳过(新安装无需迁移)"
|
||
fi
|
||
|
||
# 配置内的绝对路径也要跟着改;只改这些键,避免误伤注释里的示例。
|
||
if [ -d "$NEW_ETC" ] && [ -f "$NEW_ETC/config.yaml" ]; then
|
||
if grep -q "$OLD_ETC" "$NEW_ETC/config.yaml"; then
|
||
plan "把 $NEW_ETC/config.yaml 中的 $OLD_ETC 改为 $NEW_ETC"
|
||
backup_if_exists "$NEW_ETC/config.yaml"
|
||
run sed -i "s#${OLD_ETC}#${NEW_ETC}#g" "$NEW_ETC/config.yaml"
|
||
else
|
||
ok "config.yaml 内无旧路径"
|
||
fi
|
||
# master.key 的权限是安全边界,迁移后复核一次。
|
||
if [ -f "$NEW_ETC/master.key" ]; then
|
||
plan "复核 master.key 权限为 0600"
|
||
run chmod 0600 "$NEW_ETC/master.key"
|
||
fi
|
||
fi
|
||
|
||
# ---- 2. 二进制 ---------------------------------------------------------
|
||
echo "[2/5] 二进制"
|
||
if [ -x "$NEW_BIN" ]; then
|
||
ok "$NEW_BIN 已存在(安装包已就位)"
|
||
elif [ -x "$OLD_BIN" ]; then
|
||
plan "复制 $OLD_BIN → $NEW_BIN 并保留旧文件"
|
||
run cp -a "$OLD_BIN" "$NEW_BIN"
|
||
run chmod 0755 "$NEW_BIN"
|
||
else
|
||
plan "尚无二进制:从发行包或 'make build' 得到 $NEW_BIN 后重跑本脚本"
|
||
fi
|
||
|
||
# ---- 3. systemd ------------------------------------------------------
|
||
echo "[3/5] systemd unit"
|
||
if [ -f "$NEW_UNIT" ]; then
|
||
ok "$NEW_UNIT 已存在"
|
||
elif [ -f "$OLD_UNIT" ]; then
|
||
plan "生成 $NEW_UNIT(改写 ExecStart/WorkingDirectory/ReadWritePaths)"
|
||
if [ "$APPLY" -eq 1 ]; then
|
||
sed "s#/usr/local/bin/${OLD_NAME}#${NEW_BIN}#g; s#${OLD_ETC}#${NEW_ETC}#g" \
|
||
"$OLD_UNIT" > "$NEW_UNIT"
|
||
chmod 0644 "$NEW_UNIT"
|
||
else
|
||
printf ' [dry-run] sed ... %s > %s\n' "$OLD_UNIT" "$NEW_UNIT"
|
||
fi
|
||
plan "旧 unit 保留:$OLD_UNIT(确认新服务可用后再 disable)"
|
||
else
|
||
skip "没有 systemd unit,跳过"
|
||
fi
|
||
|
||
# ---- 4. 分享目录(安装脚本/示例配置)----------------------------------
|
||
echo "[4/5] /usr/share 资源"
|
||
if [ -d "$OLD_SHARE" ] && [ ! -d "$NEW_SHARE" ]; then
|
||
plan "复制 $OLD_SHARE → $NEW_SHARE"
|
||
run cp -a "$OLD_SHARE" "$NEW_SHARE"
|
||
else
|
||
skip "$OLD_SHARE → $NEW_SHARE 无需处理"
|
||
fi
|
||
|
||
# ---- 5. 校验 ---------------------------------------------------------
|
||
echo "[5/5] 校验"
|
||
if [ "$APPLY" -eq 1 ]; then
|
||
[ -x "$NEW_BIN" ] || die "$NEW_BIN 不可执行"
|
||
ok "$NEW_BIN 可执行"
|
||
if [ -f "$NEW_ETC/config.yaml" ]; then
|
||
"$NEW_BIN" -config "$NEW_ETC/config.yaml" -check >/dev/null || die "配置校验失败"
|
||
ok "配置校验通过($NEW_ETC/config.yaml)"
|
||
fi
|
||
if [ -f "$NEW_UNIT" ]; then
|
||
systemctl daemon-reload
|
||
ok "systemd 已 reload"
|
||
fi
|
||
if [ "$RESTART" -eq 1 ] && [ -f "$NEW_UNIT" ]; then
|
||
systemctl enable --now "${NEW_NAME}.service"
|
||
ok "${NEW_NAME}.service 已启动"
|
||
else
|
||
skip "未重启服务(需要时加 --restart)"
|
||
fi
|
||
|
||
echo
|
||
echo "迁移完成。旧布局原样保留,回滚:"
|
||
echo " sudo $0 --rollback --apply"
|
||
echo
|
||
echo "确认无误后再手工清理(本脚本不会删):"
|
||
echo " systemctl disable --now ${OLD_NAME}.service 2>/dev/null || true"
|
||
echo " rm -f $OLD_UNIT"
|
||
echo " rm -rf $OLD_BIN $OLD_ETC $OLD_SHARE"
|
||
else
|
||
echo
|
||
echo "以上为预演。确认后执行:"
|
||
echo " sudo $0 --apply"
|
||
fi
|