deploy: accept exact OCI index or config identity from offline image

This commit is contained in:
weiyuqing committed 2026-10-17 14:42:56 +08:00
1 parent c076bbc0d6
commit 1c05825b6a
3 files changed
+7 -4

No files matched your search

+2 -1
View File
@@ -9,7 +9,8 @@ backend, web, worker = items
assert backend['Config']['Image'] == web['Config']['Image'] == IMAGE
assert worker['Config']['Image'] == 'local/mi-fitness-nas:20261017-audit3'
if len(sys.argv) > 1:
assert backend['Image'] == web['Image'] == sys.argv[1]
# 引擎可能报告OCI索引或配置digest;两者都来自已校验的同一镜像tar。
assert backend['Image'] == web['Image'] and backend['Image'] in set(sys.argv[1:])
assert backend['HostConfig']['ReadonlyRootfs'] and web['HostConfig']['ReadonlyRootfs']
assert any(m['Destination'] == '/state' for m in backend['Mounts'])
assert any(m['Destination'] == '/run/secrets/keyring_master' and not m['RW'] for m in backend['Mounts'])
+4 -2
View File
@@ -23,7 +23,9 @@ docker inspect --format '{{.Config.Image}} {{.Image}}' mi-fitness-health-backend
# 不清理旧镜像;覆盖配置和镜像ID均保留以便回退。
docker load -i "$package/health-summary8.tar"
expected=$(cat "$package/image-id.txt")
[ "$(docker image inspect --format '{{.Id}}' local/mi-fitness-nas:20261017-summary8)" = "$expected" ] || { echo '导入镜像ID不符。'; exit 1; }
config_id=$(cat "$package/image-config-id.txt")
actual=$(docker image inspect --format '{{.Id}}' local/mi-fitness-nas:20261017-summary8)
[ "$actual" = "$expected" ] || [ "$actual" = "$config_id" ] || { echo '导入镜像ID不符。'; exit 1; }
docker compose --project-name mi-fitness-health --env-file .env -f compose.yml -f "$package/compose.override.yml" config --quiet
complete=0
recover() {
@@ -40,7 +42,7 @@ cp "$package/compose.override.yml" compose.override.yml
chown 1000:1001 compose.override.yml
chmod 600 compose.override.yml
compose up -d --no-deps --no-build --pull never --wait --wait-timeout 90 backend web
python3 "$package/check-ready.py" "$expected"
python3 "$package/check-ready.py" "$expected" "$config_id"
[ "$before" = "$(snapshot)" ] || { echo 'worker或其他健康服务发生变化,停止验收。'; exit 1; }
complete=1
trap - EXIT
+1 -1
View File
@@ -57,6 +57,6 @@ node --test qa/*.test.cjs
离线构建使用 `deploy/query-summary/Dockerfile`,上下文只复制当前 `src/mi_fitness_mcp/` 源码(排除pycache),不把仓库运行文件送入构建。基础镜像须核对为audit3 `sha256:f4cbe187a98e3d3223e28e79b6edd115446ba62a78931f54f3bb0a6991a9395d`,构建选 `--network none --pull=false`;同时覆盖源码目录与installed purelib,保持audit3运行入口,无联网安装。
本机离线发布目录为 `artifacts/query-summary/release/`:镜像tar、image-id、基础镜像id、覆盖配置、就绪/更新脚本、预期当前配置哈希及manifest.sha256。摘要和镜像包不提交Git。`Update-Nas.ps1`不带Deploy仅校验;正式执行必须先取得仅更新backend/web的明确确认,由用户交互输入sudo密码。更新脚本核对manifest和现有覆盖配置SHA256、保留旧覆盖与镜像、不变更.env,使用 `up -d --no-deps --no-build --pull never backend web`,比较其余健康服务容器id/镜像。失败恢复旧覆盖并尝试回退这两个服务。
本机离线发布目录为 `artifacts/query-summary/release/`:镜像tar、image-id及同包配置digest、基础镜像id、覆盖配置、就绪/更新脚本、预期当前配置哈希及manifest.sha256。Docker引擎身份核对只接受本包确切的索引/配置digest,先校验整个tar;NAS引擎尚未实际导入验证。摘要和镜像包不提交Git。`Update-Nas.ps1`不带Deploy仅校验;正式执行必须先取得仅更新backend/web的明确确认,由用户交互输入sudo密码。更新脚本核对manifest和现有覆盖配置SHA256、保留旧覆盖与镜像、不变更.env,使用 `up -d --no-deps --no-build --pull never backend web`,比较其余健康服务容器id/镜像。失败恢复旧覆盖并尝试回退这两个服务。
当前NAS覆盖配置防覆盖哈希由controller在部署前只读取得:`3cdbdc882b169f5785d6d1c3c46ceb159e209c567d6e28ceb31b15d4280fcdd8`。实际正式更新时脚本再次验证;若有漂移即停止。此记录不是部署确认。NAS就绪脚本只访问资源/代理状态、匿名认证、日历和无效日期路由,不进行健康导出、合成/压力测试。