From 1bdbb47b52b0f4871582e3639c61e9c4c9cfd803 Mon Sep 17 00:00:00 2001 From: Yuyi-Oak <1722157266@qq.com> Date: Mon, 13 Jul 2026 22:22:20 +0800 Subject: [PATCH] docs: define production sync deployment Fixes #15 --- CHANGELOG.md | 1 + CURRENT_STATUS.md | 4 +- DOCS_INDEX.md | 1 + PROJECT_PLAN.md | 2 +- .../bluearchive-toolkit-official-sync.service | 39 +++ deployments/systemd/official-sync.env.example | 11 + docs/guides/deployment.md | 223 ++++++++++++++---- 7 files changed, 229 insertions(+), 52 deletions(-) create mode 100644 deployments/systemd/bluearchive-toolkit-official-sync.service create mode 100644 deployments/systemd/official-sync.env.example diff --git a/CHANGELOG.md b/CHANGELOG.md index cfaa359..eb6bc92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - 新增 Rust 官方同步 binary,当前正式入口为 `bat`,支持 one-shot、`--watch`、默认 1 小时间隔、人类可读默认输出和 `--json` 结构化 report - 官方同步正式入口统一为 `bat`,新增 `--daemon` 后台模式和基于 `bat.sock` 的 Unix socket JSON-RPC 控制面,管理命令覆盖 `status`、`stop`、`restart`、`reload`、`refresh`、`logs`、`verify`、`repair`、`doctor`、`clean-stable` - 新增 daemon 控制锁 `bat-control.lock`、daemon 与前台同资源目录写入互斥,以及失效/损坏 PID 和锁文件恢复逻辑 +- 新增官方资源同步生产部署模板:release binary symlink 路径、systemd unit、运行用户、日志位置、升级和回滚流程 - 新增官方资源下载校验:官方 URL 拒绝、`.part` 续传、重试、本地 size+BLAKE3、官方 seed `.hash` 校验 - 新增 Addressables 当前真实形态 fixture/golden 测试 - 新增 SQLite Resource Repository 和粗粒度 FFI JSON 接口 diff --git a/CURRENT_STATUS.md b/CURRENT_STATUS.md index 9648013..69d0233 100644 --- a/CURRENT_STATUS.md +++ b/CURRENT_STATUS.md @@ -241,9 +241,9 @@ cargo run -p bat-infrastructure --bin bat -- \ 2. 不要指向已有游戏客户端目录。 3. 不要指向 `/home/wanye/D/BlueArchive` 这类开发或人工维护资源目录。 4. `--auto-discover` 可以下载官方 metadata,并按官方 manifest 临时获取 `resources.assets` 以解析 `GameMainConfig`;旧 ZIP manifest 才会下载临时 game zip。该流程不会安装或启动官方 launcher。 -5. systemd service、容器或 Go 进程可以负责守护 `bat --watch`,也可以用 `bat --daemon` 启动后台模式;`--daemon` 的管理命令优先走 `/tmp/bat-pid/bat.sock` Unix socket JSON-RPC;定时检查逻辑已经在 Rust 内部,正常检查默认 1 小时,失败重试默认 60 秒,每天北京时间(UTC+8)`03:00`、`16:00`、`18:00` 会强制执行一次自动刷新。 +5. 推荐生产形态是 systemd 直接托管前台 `bat --watch`,unit 模板位于 `deployments/systemd/bluearchive-toolkit-official-sync.service`,稳定 binary 路径为 `/opt/bluearchive-toolkit/bin/bat`,资源目录为 `/var/lib/bluearchive-toolkit/official`,日志通过 `journalctl -u bluearchive-toolkit-official-sync.service` 查看;不使用 systemd 时也可用 `bat --daemon` 自托管,daemon 状态和 `bat-daemon.log` 建议放在 `/var/lib/bluearchive-toolkit/daemon-state`。定时检查逻辑已经在 Rust 内部,正常检查默认 1 小时,失败重试默认 60 秒,每天北京时间(UTC+8)`03:00`、`16:00`、`18:00` 会强制执行一次自动刷新。 -详细运行说明见 `docs/guides/official-resource-test-pull.md`。 +详细运行说明见 `docs/guides/deployment.md` 和 `docs/guides/official-resource-test-pull.md`。 --- diff --git a/DOCS_INDEX.md b/DOCS_INDEX.md index 791450b..9ffef72 100644 --- a/DOCS_INDEX.md +++ b/DOCS_INDEX.md @@ -24,6 +24,7 @@ - `docs/api/README.md`:API 设计入口。 - `docs/guides/development.md`:开发指南。 - `docs/guides/deployment.md`:部署指南。 +- `deployments/systemd/`:官方资源同步生产 systemd unit 和环境文件示例。 - `docs/guides/official-resource-test-pull.md`:官方资源拉取与自动更新用户指南。 - `docs/reports/current-stage-prepush.md`:当前阶段说明与推送前核查记录。 - `docs/reports/current-status-handoff.md`:给下一次对话使用的当前进度交接说明。 diff --git a/PROJECT_PLAN.md b/PROJECT_PLAN.md index bb000c4..5ca9e93 100644 --- a/PROJECT_PLAN.md +++ b/PROJECT_PLAN.md @@ -387,7 +387,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付 5. 继续扩展 Addressables parser 的真实 catalog 变体覆盖和错误诊断。 6. 开始 AssetBundle UnityFS header/block/directory 解析。 7. 为 CLI 和 CAS 增加 `doctor cas` 诊断入口。 -8. 为 `bat --watch` / `bat --daemon` 持续补充发布型构建、systemd service 示例和运维检查清单;后台 live control plane 已改为 Unix socket JSON-RPC。 +8. 为 `bat --watch` / `bat --daemon` 持续补充发布型构建、systemd service 示例和运维检查清单;后台 live control plane 已改为 Unix socket JSON-RPC;基础生产部署模板、日志路径、权限用户、升级/回滚流程已补齐。 --- diff --git a/deployments/systemd/bluearchive-toolkit-official-sync.service b/deployments/systemd/bluearchive-toolkit-official-sync.service new file mode 100644 index 0000000..51c214f --- /dev/null +++ b/deployments/systemd/bluearchive-toolkit-official-sync.service @@ -0,0 +1,39 @@ +[Unit] +Description=BlueArchiveToolkit official resource sync +Documentation=https://github.com/Yuyi-Oak/BlueArchiveToolkit +Wants=network-online.target +After=network-online.target + +[Service] +Type=simple +User=bat +Group=bat +WorkingDirectory=/var/lib/bluearchive-toolkit +Environment=BAT_OUTPUT_ROOT=/var/lib/bluearchive-toolkit/official +Environment=BAT_INTERVAL=1h +Environment=BAT_ERROR_RETRY=60s +EnvironmentFile=-/etc/bluearchive-toolkit/official-sync.env +ExecStart=/opt/bluearchive-toolkit/bin/bat --auto-discover --output ${BAT_OUTPUT_ROOT} --watch --interval ${BAT_INTERVAL} --error-retry ${BAT_ERROR_RETRY} --no-banner +Restart=on-failure +RestartSec=30 +TimeoutStopSec=60 +KillSignal=SIGTERM +StandardOutput=journal +StandardError=journal +StateDirectory=bluearchive-toolkit +StateDirectoryMode=0750 +RuntimeDirectory=bluearchive-toolkit +RuntimeDirectoryMode=0750 +LogsDirectory=bluearchive-toolkit +LogsDirectoryMode=0750 +NoNewPrivileges=true +PrivateTmp=true +ProtectHome=true +ProtectSystem=strict +ReadWritePaths=/var/lib/bluearchive-toolkit /run/bluearchive-toolkit /var/log/bluearchive-toolkit +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +LockPersonality=true +MemoryDenyWriteExecute=true + +[Install] +WantedBy=multi-user.target diff --git a/deployments/systemd/official-sync.env.example b/deployments/systemd/official-sync.env.example new file mode 100644 index 0000000..187b2fe --- /dev/null +++ b/deployments/systemd/official-sync.env.example @@ -0,0 +1,11 @@ +# Optional overrides for bluearchive-toolkit-official-sync.service. +# +# Install as: +# sudo install -o root -g root -m 0644 deployments/systemd/official-sync.env.example /etc/bluearchive-toolkit/official-sync.env +# +# Paths are intentionally independent from any official launcher or game client +# install directory. Do not point BAT_OUTPUT_ROOT at an existing game directory. + +BAT_OUTPUT_ROOT=/var/lib/bluearchive-toolkit/official +BAT_INTERVAL=1h +BAT_ERROR_RETRY=60s diff --git a/docs/guides/deployment.md b/docs/guides/deployment.md index 88b0bed..1f8ffb6 100644 --- a/docs/guides/deployment.md +++ b/docs/guides/deployment.md @@ -102,7 +102,7 @@ REDIS_PORT=6379 当前可部署的生产任务是 Rust 官方资源同步 binary。API Server 和 Web 尚未实现,不能按完整服务端产品部署。 -### 构建 +### 构建 release binary ```bash cargo build --release -p bat-infrastructure --bin bat @@ -114,15 +114,64 @@ cargo build --release -p bat-infrastructure --bin bat target/release/bat ``` -### 目录约定 - -推荐生产状态目录: +生产不直接从 Git 工作区运行 binary。推荐把每次发布放进独立 release 目录,再用稳定 symlink 暴露当前版本: ```text -/var/lib/bluearchive-toolkit/official/ +/opt/bluearchive-toolkit/releases//bat +/opt/bluearchive-toolkit/bin/bat -> /opt/bluearchive-toolkit/releases//bat ``` -该目录会保存: +示例安装命令: + +```bash +VERSION="$(git rev-parse --short HEAD)" +sudo install -d -o root -g root -m 0755 \ + /opt/bluearchive-toolkit/releases/"${VERSION}" \ + /opt/bluearchive-toolkit/bin +sudo install -o root -g root -m 0755 \ + target/release/bat \ + /opt/bluearchive-toolkit/releases/"${VERSION}"/bat +sudo ln -sfn \ + /opt/bluearchive-toolkit/releases/"${VERSION}"/bat \ + /opt/bluearchive-toolkit/bin/bat +/opt/bluearchive-toolkit/bin/bat --help +``` + +### 用户和目录 + +生产建议使用固定系统用户运行,不使用 root 长期运行同步进程: + +```bash +getent group bat >/dev/null || sudo groupadd --system bat +id -u bat >/dev/null 2>&1 || sudo useradd --system \ + --gid bat \ + --home-dir /var/lib/bluearchive-toolkit \ + --shell /usr/sbin/nologin \ + bat +``` + +如果用户或组已存在,保留现有对象即可。推荐目录: + +```text +/opt/bluearchive-toolkit/ # root 拥有,存 release binary 和当前 symlink +/etc/bluearchive-toolkit/ # root 拥有,存 service 配置 +/var/lib/bluearchive-toolkit/official/ # bat 拥有,官方资源和同步状态 +/var/lib/bluearchive-toolkit/daemon-state/ # bat 拥有,仅用于 standalone --daemon 持久状态 +/run/bluearchive-toolkit/ # systemd 创建,运行期状态 +/var/log/bluearchive-toolkit/ # systemd 创建,当前推荐用 journald +``` + +创建目录: + +```bash +sudo install -d -o root -g root -m 0755 /etc/bluearchive-toolkit +sudo install -d -o bat -g bat -m 0750 \ + /var/lib/bluearchive-toolkit \ + /var/lib/bluearchive-toolkit/official \ + /var/lib/bluearchive-toolkit/daemon-state +``` + +`/var/lib/bluearchive-toolkit/official/` 会保存: - `official-sync-snapshot.json` - `official-bootstrap-cache.json` @@ -137,79 +186,155 @@ target/release/bat - 开发机现有资源目录,例如 `/home/wanye/D/BlueArchive` - Git 工作区目录 -### 一次性检查 +### 首次 dry-run ```bash -/opt/bluearchive-toolkit/bin/bat \ +sudo -u bat /opt/bluearchive-toolkit/bin/bat \ --auto-discover \ --output /var/lib/bluearchive-toolkit/official \ - --dry-run + --dry-run \ + --no-progress ``` -### 常驻自动更新 +### 推荐模式:systemd 托管 `--watch` + +生产推荐让 systemd 直接托管前台 `--watch` 进程,而不是在 systemd 里再启动 `--daemon`。原因: + +- systemd 能直接追踪主进程、退出码、重启次数和 stop 信号。 +- 日志进入 journald,用 `journalctl` 管理,不依赖 `bat-daemon.log`。 +- Rust 内部已经负责 1 小时间隔、北京时间固定强制刷新和失败快速重试,systemd 不需要 timer。 +- `bat --daemon` 的 Unix socket RPC 适合没有进程管理器的 shell/container 场景;systemd 场景下用 `systemctl`、`journalctl`、`bat verify/doctor` 运维即可。 + +安装 unit 和可选环境文件: ```bash -/opt/bluearchive-toolkit/bin/bat \ - --auto-discover \ - --output /var/lib/bluearchive-toolkit/official \ - --watch +sudo install -o root -g root -m 0644 \ + deployments/systemd/bluearchive-toolkit-official-sync.service \ + /etc/systemd/system/bluearchive-toolkit-official-sync.service +sudo install -o root -g root -m 0644 \ + deployments/systemd/official-sync.env.example \ + /etc/bluearchive-toolkit/official-sync.env +sudo systemctl daemon-reload +sudo systemctl enable --now bluearchive-toolkit-official-sync.service ``` -`--watch` 是 Rust 内部持久检查模式,正常情况下默认每 1 小时执行一次检查,并且每天北京时间(UTC+8)`03:00`、`16:00`、`18:00` 会强制执行一次自动刷新。固定时间刷新会中断普通 interval 的 sleep,该轮注入 `force=true`;如果失败,会按失败重试周期继续重试。远端和本地一致时默认静默;有远端变化或本地文件损坏时自动下载或 repair,并输出人类可读摘要。下载、发现或校验失败时默认 60 秒后重试,可显式加 `--error-retry 60s` 或 `--error-retry-seconds 60` 调整。默认平台是 `Windows,Android`,无需显式传 `--platforms`;需要覆盖时再传。默认资源目录是 `./bat-resources`,生产建议显式传 `--output /var/lib/bluearchive-toolkit/official`。默认 ASCII banner 和进度日志写到 stderr,命令结果写到 stdout;如果由上层服务严格解析结构化输出,可加 `--json --no-progress`,只想关闭横幅可加 `--no-banner`。 - -不使用 systemd 时,也可以直接后台运行: +检查状态和日志: ```bash -/opt/bluearchive-toolkit/bin/bat \ +systemctl status bluearchive-toolkit-official-sync.service +journalctl -u bluearchive-toolkit-official-sync.service -f +sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor \ + --output /var/lib/bluearchive-toolkit/official \ + --state-dir /run/bluearchive-toolkit +``` + +`--watch` 是 Rust 内部持久检查模式,正常情况下默认每 1 小时执行一次检查,并且每天北京时间(UTC+8)`03:00`、`16:00`、`18:00` 会强制执行一次自动刷新。固定时间刷新会中断普通 interval 的 sleep,该轮注入 `force=true`;如果失败,会按失败重试周期继续重试。远端和本地一致时默认静默;有远端变化或本地文件损坏时自动下载或 repair,并输出人类可读摘要。下载、发现或校验失败时默认 60 秒后重试,可显式加 `BAT_ERROR_RETRY=60s` 或调整 service `ExecStart`。默认平台是 `Windows,Android`,无需显式传 `--platforms`;需要覆盖时用 systemd drop-in 重写 `ExecStart`。默认资源目录是 `./bat-resources`,生产 service 显式使用 `/var/lib/bluearchive-toolkit/official`。 + +### 可选模式:CLI 自托管 `--daemon` + +不使用 systemd 时,可以直接后台运行。生产中不要使用默认 `/tmp/bat-pid`,建议使用持久状态目录,这样 `bat-daemon.log` 不会随 reboot 或 tmp 清理丢失: + +```bash +sudo -u bat /opt/bluearchive-toolkit/bin/bat \ --auto-discover \ --output /var/lib/bluearchive-toolkit/official \ - --state-dir /run/bluearchive-toolkit \ + --state-dir /var/lib/bluearchive-toolkit/daemon-state \ --daemon -/opt/bluearchive-toolkit/bin/bat status --state-dir /run/bluearchive-toolkit -/opt/bluearchive-toolkit/bin/bat logs --state-dir /run/bluearchive-toolkit --tail 200 -/opt/bluearchive-toolkit/bin/bat restart --state-dir /run/bluearchive-toolkit -/opt/bluearchive-toolkit/bin/bat reload --state-dir /run/bluearchive-toolkit -/opt/bluearchive-toolkit/bin/bat stop --state-dir /run/bluearchive-toolkit +sudo -u bat /opt/bluearchive-toolkit/bin/bat status --state-dir /var/lib/bluearchive-toolkit/daemon-state +sudo -u bat /opt/bluearchive-toolkit/bin/bat logs --state-dir /var/lib/bluearchive-toolkit/daemon-state --tail 200 +sudo -u bat /opt/bluearchive-toolkit/bin/bat restart --state-dir /var/lib/bluearchive-toolkit/daemon-state +sudo -u bat /opt/bluearchive-toolkit/bin/bat reload --state-dir /var/lib/bluearchive-toolkit/daemon-state +sudo -u bat /opt/bluearchive-toolkit/bin/bat stop --state-dir /var/lib/bluearchive-toolkit/daemon-state ``` `--daemon` 会在 `--state-dir` 下创建 `bat.sock`、`bat.pid`、`bat-status.json`、`bat-daemon.log` 和短生命周期的 `bat-control.lock`。`bat.sock` 是 Unix socket JSON-RPC 控制通道;`status`、`stop`、`logs`、`reload` 和默认形态的 `refresh` 会优先连接 live daemon。PID、状态和日志文件保留为快照、诊断和 socket 不可用时的兼容路径;`bat-control.lock` 串行化控制命令,并能在 stale/corrupt 时由下一次控制命令或 `clean-stable` 恢复。`reload` 默认不会重启进程,而是让 watch 循环重新自动发现并强制刷新:空闲睡眠时立即唤醒,正在同步时排队到当前轮结束后执行;需要替换启动参数或 binary 时用 `restart`。 -生产维护时可以用以下单次命令: +不要同时运行 systemd `--watch` 和 standalone `--daemon` 指向同一个 `--output`。二者都会被资源锁和 live daemon 互斥保护,但生产运维上应保持单一 owner。 + +### 日志和状态路径 + +systemd 模式: + +- 进程日志:`journalctl -u bluearchive-toolkit-official-sync.service` +- 资源状态:`/var/lib/bluearchive-toolkit/official/official-sync-snapshot.json` +- 下载 manifest:`/var/lib/bluearchive-toolkit/official/official-download-manifest.json` +- 资源写锁:`/var/lib/bluearchive-toolkit/official/.official-sync.lock` +- 运行期目录:`/run/bluearchive-toolkit/` + +standalone `--daemon` 模式: + +- 进程日志:`/bat-daemon.log` +- RPC socket:`/bat.sock` +- PID 文件:`/bat.pid` +- daemon 状态:`/bat-status.json` +- 控制锁:`/bat-control.lock` + +### 生产维护命令 ```bash -/opt/bluearchive-toolkit/bin/bat refresh --output /var/lib/bluearchive-toolkit/official -/opt/bluearchive-toolkit/bin/bat refresh --force --output /var/lib/bluearchive-toolkit/official -/opt/bluearchive-toolkit/bin/bat verify --output /var/lib/bluearchive-toolkit/official -/opt/bluearchive-toolkit/bin/bat repair --output /var/lib/bluearchive-toolkit/official -/opt/bluearchive-toolkit/bin/bat doctor --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit -/opt/bluearchive-toolkit/bin/bat clean-stable --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit +sudo -u bat /opt/bluearchive-toolkit/bin/bat refresh --output /var/lib/bluearchive-toolkit/official +sudo -u bat /opt/bluearchive-toolkit/bin/bat refresh --force --output /var/lib/bluearchive-toolkit/official +sudo -u bat /opt/bluearchive-toolkit/bin/bat verify --output /var/lib/bluearchive-toolkit/official +sudo -u bat /opt/bluearchive-toolkit/bin/bat repair --output /var/lib/bluearchive-toolkit/official +sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit +sudo -u bat /opt/bluearchive-toolkit/bin/bat clean-stable --output /var/lib/bluearchive-toolkit/official --state-dir /run/bluearchive-toolkit ``` 如果后台 daemon 正在运行,并且 `refresh` 没有显式指定另一套同步参数,`refresh` / `refresh --force` 会通过 RPC 唤醒或排队后台进程;带 `--output`、server-info、connection-group、app-version、platforms、snapshot、curl 或 unzip 等显式参数时,`refresh` 会作为一次性前台同步运行,但不能写入 live daemon 正在管理的同一资源目录,否则会返回 locked。`verify` 发现远端变化、本地缺失或校验失败时返回非 0;`repair` 会走官方同步链路重新下载必要文件,但同样不能和 live daemon 并行写同一资源目录;`clean-stable` 只清理 `.part`、`.tmp`、失效或损坏的 PID/socket/锁,不删除正式资源。 -### systemd service 示例 +### 升级 -systemd 只负责进程守护,不负责定时逻辑: +升级只替换 `/opt/bluearchive-toolkit/bin/bat` symlink,不直接覆盖旧 binary: -```ini -[Unit] -Description=BlueArchiveToolkit official resource sync -After=network-online.target -Wants=network-online.target +```bash +NEW_VERSION="" +cargo build --release -p bat-infrastructure --bin bat +sudo install -d -o root -g root -m 0755 \ + /opt/bluearchive-toolkit/releases/"${NEW_VERSION}" +sudo install -o root -g root -m 0755 \ + target/release/bat \ + /opt/bluearchive-toolkit/releases/"${NEW_VERSION}"/bat -[Service] -Type=simple -User=bat -Group=bat -ExecStart=/opt/bluearchive-toolkit/bin/bat --auto-discover --output /var/lib/bluearchive-toolkit/official --watch --error-retry 60s -Restart=on-failure -RestartSec=30 -StateDirectory=bluearchive-toolkit -NoNewPrivileges=true +sudo systemctl stop bluearchive-toolkit-official-sync.service +sudo ln -sfn \ + /opt/bluearchive-toolkit/releases/"${NEW_VERSION}"/bat \ + /opt/bluearchive-toolkit/bin/bat +sudo systemctl start bluearchive-toolkit-official-sync.service +systemctl status bluearchive-toolkit-official-sync.service +journalctl -u bluearchive-toolkit-official-sync.service -n 100 --no-pager +``` -[Install] -WantedBy=multi-user.target +升级后执行: + +```bash +sudo -u bat /opt/bluearchive-toolkit/bin/bat doctor \ + --output /var/lib/bluearchive-toolkit/official \ + --state-dir /run/bluearchive-toolkit +``` + +### 回滚 + +回滚同样只切 symlink,不删除资源目录和 manifest: + +```bash +PREVIOUS_VERSION="" +sudo systemctl stop bluearchive-toolkit-official-sync.service +sudo ln -sfn \ + /opt/bluearchive-toolkit/releases/"${PREVIOUS_VERSION}"/bat \ + /opt/bluearchive-toolkit/bin/bat +sudo systemctl start bluearchive-toolkit-official-sync.service +journalctl -u bluearchive-toolkit-official-sync.service -n 100 --no-pager +``` + +当前官方资源同步的本地状态位于 `/var/lib/bluearchive-toolkit/official`。普通 binary 回滚不需要回滚资源目录;如果要测试可能改动 manifest/schema 的版本,先备份资源状态文件: + +```bash +sudo -u bat tar -C /var/lib/bluearchive-toolkit/official \ + -czf /var/lib/bluearchive-toolkit/official-state-backup.tgz \ + official-sync-snapshot.json \ + official-bootstrap-cache.json \ + official-download-manifest.json ``` 如果业务层需要热更新、热重载或发布新资源,应该由上层服务在观察到 `--json` report 或 snapshot 变化后决定。Rust 同步进程只负责拉取、校验和维护本地状态。