From 33b9782a1d53d2f41e34f35d24020da4652ddec5 Mon Sep 17 00:00:00 2001 From: JustMe Date: Wed, 7 Oct 2026 13:00:35 +0800 Subject: [PATCH] ci: tolerate legacy Backend release webhook [CI] --- ci/publish-release-offer.sh | 17 ++++++++++++++--- docs/deployment.md | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/ci/publish-release-offer.sh b/ci/publish-release-offer.sh index 7255f8b..4ede65e 100644 --- a/ci/publish-release-offer.sh +++ b/ci/publish-release-offer.sh @@ -8,7 +8,18 @@ bash "$root/ci/release-manifest.sh" "$component" "$repository" "$digest" "$tag" if [[ -n "${RELEASE_API_URL:-}" && -n "${RELEASE_API_TOKEN:-}" ]]; then python3 -c 'import json,sys; print(json.dumps({"manifest": open(sys.argv[1]).read(), "signature": open(sys.argv[2]).read()}))' \ "$outdir/manifest.json" "$outdir/manifest.sig" > "$outdir/payload.json" - curl --fail-with-body --silent --show-error --retry 3 -X POST "${RELEASE_API_URL%/}/api/admin/releases" \ - -H "Authorization: Bearer $RELEASE_API_TOKEN" -H 'Content-Type: application/json' --data-binary "@$outdir/payload.json" >/dev/null - echo "registered the signed $component release with the panel ($channel)" + response="$outdir/response.json" + status="$(curl --silent --show-error --retry 3 -o "$response" -w '%{http_code}' -X POST "${RELEASE_API_URL%/}/api/admin/releases" \ + -H "Authorization: Bearer $RELEASE_API_TOKEN" -H 'Content-Type: application/json' --data-binary "@$outdir/payload.json")" + if [[ "$status" != 2* ]]; then + if [[ "$component" == backend && "$status" == 400 ]] && grep -Fq 'manifest needs a known component' "$response"; then + echo "the panel does not support Backend update offers yet; bootstrap it once before future Backend offers" + else + echo "release offer registration failed (HTTP $status)" >&2 + cat "$response" >&2 + exit 1 + fi + else + echo "registered the signed $component release with the panel ($channel)" + fi fi diff --git a/docs/deployment.md b/docs/deployment.md index c261829..0c61639 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -264,3 +264,22 @@ sh packaging/update/install-updater.sh agent --user \ 更新器依赖 Linux、systemd、OpenSSL、util-linux/flock 和所选引擎。用户部署把配置、公钥和镜像引用放在 `~/.config/moshiro/`、版本记录放在 `~/.local/state/moshiro-update/`;系统部署使用 `/etc/moshiro-update/` 和 `/var/lib/moshiro-update/`。私有仓库的 `--authfile` 对 Podman 使用其认证文件,对 Docker 使用标准 `config.json`,不改写全局 Docker 配置。旧 `--data-dir` 安装方式保留兼容,但新部署统一使用 `--volume`。 发布私钥只放在 Woodpecker 的 `release_signing_key` secret;发布公钥位于 `packaging/update/release-key.pub.pem`。CI 的 `release_api_token` 只有发布登记权限,`RELEASE_API_URL` 指向面板。面板保存并转发签名清单,Agent/Probe 将它与更新请求写进配置 volume;更新器验签后才调用容器引擎和 systemd。管理端仍能看到可更新、更新中、已回滚和无效清单状态。纯二进制更新器尚未实现。 + +## Backend 签名更新 + +Backend 也会收到 CI 发布的签名清单,但只提示管理端,不会自动重启。管理员确认精确的清单序号后,宿主更新器才会备份 Backend 数据 volume、按清单 digest 拉取镜像、重启服务并检查 `/healthz`;失败时恢复旧镜像和数据库备份。确认和发布通过同一个锁串行处理,避免确认过期版本。 + +`MOSHIRO_UPDATE_CHANNEL=auto` 时,`MOSHIRO_IMAGE_NAMESPACE=moshiro-dev` 选择 `dev`,`moshiro` 选择 `release`。CI 发布流水线使用对应 channel 签名并登记到 Backend webhook。旧版 Backend 不识别 Backend 清单,因此首次升级需按常规部署流程引导一次;该期间 CI 对这类旧版面板的明确“不认识 backend 组件”响应会提示引导信息,其他 webhook 错误仍会令发布失败。 + +更新器以手动策略运行,并通过独立状态 volume 将状态只读挂载回 Backend: + +```sh +sudo packaging/update/install-updater.sh backend --engine podman \ + --volume moshiro-backend-data --status-volume moshiro-backend-status \ + --helper-image registry.oeo.one/moshiro-dev/moshiro-backend: \ + --image-repo registry.oeo.one/moshiro-dev/moshiro-backend \ + --unit moshiro-backend.service --policy manual --channel dev \ + --health-url http://127.0.0.1:29181/healthz +``` + +Backend 服务需要将 `moshiro-backend-status` 挂载到 `/data/update-status:ro`,并将镜像引用文件 `/etc/moshiro-update/backend.image` 作为 `IMAGE_FILE` 提供给 systemd 单元。release 实例使用 `--channel release` 及 `registry.oeo.one/moshiro` 仓库。更新请求由管理端确认后写入状态接口,不要启用全局 Podman 自动更新 timer。