FR-172 · 定版交付
現況:主系統 1.28.3、Agent 1.5.5(內部測試包,測試章簽);正式版跟 FR-173 出 1.29
主系統與 Agent 是兩個安裝包、兩條版本線、各自升級。Agent 不連外網,包一律經主系統轉手;主系統更新中心、Agent 主控台、離線上傳三種方式都能發動 Agent 更新,進度當下回報。給 PM 的問答看 for-pm-qa.md;每一步跑哪支程式看 upgrade-flow-guide.md。
主系統與 Agent 分開出包、分開上更新站、分開升級。按「更新到 X」不必先預先下載:主系統手上沒有最新包就自己先下載再推。Agent 升級中自動進入維護模式,主控台整頁鎖住只顯示進度,完成自動恢復。
| 項目 | 主系統 | Agent |
|---|---|---|
版號(pyproject.toml) |
1.28.3 | 1.5.5 |
| 安裝包 | guidant-ai-<版>.tar.gz(約 3.5 GB,不含 agent/)+ops 小檔 |
guidant-agent-compose-<版>.tar.gz(約 1.7 GB) |
| 更新站版本線 | product=host,R2 v1/<版>/ |
product=agent,R2 agent/v1/<版>/ |
| 發布清單的章型別 | release_manifest |
agent_release_manifest |
| 最低相容 | min_agent_version(主系統要求 Agent 至少幾版) |
min_host_version(Agent 要求主系統至少幾版,目前 1.28.0) |
| 更新站上(測試章) | 1.28.1、1.28.2、1.28.3 | 1.5.1~1.5.5 |
| 190 測試機 | 1.28.3 | 1.5.5 |
| 189 POC | 1.27.x(未升) | 1.4.x(未升) |
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
autonumber
participant P as 管理員(更新中心)
participant M as 主系統 api/worker
participant U as 更新站+R2
participant H as 主機 systemd
P->>M: 立即檢查(另有每日排程)
M->>U: /v1/check product=host
U-->>M: 新版、簽好的清單、三段說明
P->>M: 更新到 X
Note over P: 全頁遮罩,只顯示進度
M->>U: /v1/download-url(15 分鐘預簽網址)
M->>U: 下載包與 ops 小檔(背景工作、可續傳)
M->>M: 用本機公鑰驗章、比對雜湊
M->>H: 寫更新單 upgrade/orders/<job>.json
H->>H: guidant-upgrade-order.path 撿單 → 重驗包與章
H->>H: 0 換維運指令 → 1 預檢 → 2 等工作做完 → 3 複製資料庫
H->>H: 4 在複本套新版 → 5 健康檢查 → 6 換成新版 → 7 清理
Note over H: 2~6 前門顯示維護頁;任一步失敗自動退回
H-->>M: 進度檔每步更新
M-->>P: 八步進度;完成後回更新中心
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
autonumber
participant P as 管理員(更新中心 Agent 區)
participant M as 主系統
participant U as 更新站+R2
participant A as Agent 容器
participant H as Agent 主機 systemd
P->>M: 勾選 N 台,更新選取的 N 台到 X
alt 手上的包不是最新(沒有包,或比更新站查到的舊)
M->>U: 下載 Agent X(背景工作,畫面有進度、可取消)
M->>M: 驗 agent_release_manifest 章、雜湊,存 agent-bundles/X/
Note over M: 下載中再有人按,併入待推清單
end
M->>M: 建推送列:先 1 台,成功再推其餘
M->>A: 直推 POST /update {版號, sha256, 大小}(mTLS+60 秒 JWT)
Note over A: 進入維護模式:停收新工作
A->>M: GET /agents/update/bundle 下載包(可續傳)
A-->>M: 事件 update_download
A->>A: 核大小與雜湊,寫升級單 agent-upgrade-order.json
H->>H: guidant-agent-upgrade-order.path 撿單
H->>H: 用舊版 Agent 驗新版程式樹的章 → 跑升級步驟
A-->>M: 事件 update_step(每步)
H->>H: 換新容器、健康檢查
A-->>M: 事件 update_result+上傳升級紀錄
M-->>P: 每台八步進度與結果;成功清用不到的包
Agent 當時離線,主系統會在它下次心跳回來時補推一次。心跳本身不帶任何指令。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
autonumber
participant O as 操作者(Agent 主控台 8444)
participant A as Agent
participant M as 主系統
participant U as 更新站
O->>A: 立即檢查
A->>M: POST /agents/update/check(通行證+DPoP)
M->>U: 查 Agent 線(全機 5 分鐘節流)
A->>M: GET /agents/update/available
M-->>A: 有新版 X(手上沒包也照報)
O->>A: 更新到 X
Note over O: 按下當下整頁鎖住
A->>M: POST /agents/update/request(操作者名稱)
M->>M: 手上不是最新 → 排下載,記「agent-console:操作者」
M->>A: 下載完直推 POST /update(之後同圖 2 第 7 步起)
Agent 主控台「離線上傳更新包」:上傳 .offline.tar.gz,Agent 依序驗章(用現行版的公鑰,不用包裡的)、雜湊、版本、磁碟,過了就寫升級單,主機照圖 2 第 11 步起跑。主系統斷線時主控台只提供這條路。
| 狀態 | 怎麼判 | 影響 |
|---|---|---|
| 升級中(維護模式) | Agent 在下載主系統推來的包、在等進行中的工作做完、或升級單已寫好主機還在跑 | 停收新工作;主控台狀態回 in_progress |
| 主控台鎖畫面 | 主控台問狀態時拿到 in_progress |
整頁鎖住,每 3 秒更新進度 |
| 解鎖 | in_progress 消失 |
版本換了就整頁重新載入回原頁;沒換(失敗退回)就解鎖顯示結果 |
主控台平常每 30 秒問一次狀態,所以由主系統發動時開著的主控台最慢 30 秒才鎖;在主控台自己按的當下就鎖。
已是最新版時,把目前這一版照正式流程重跑一次。只給測試機用,正式環境沒有這兩個鍵就不會出現按鈕。
| 開關 | 放哪 | 誰讀 |
|---|---|---|
PRODUCT_UPDATE_ALLOW_SAME_VERSION=1 |
/srv/guidant-ai/guidant.env |
主系統 api(出按鈕、驗章放行同版)、主機升級腳本 upgrade_order.sh(放行同版單) |
AGENT_UPDATE_ALLOW_SAME_VERSION=1 |
Agent 安裝目錄 .env(compose 轉進容器) |
Agent 容器(接同版推送、離線上傳同版)、Agent 主機升級腳本 upgrade_order.sh(放行同版單) |
| 按鈕 | 在哪 | 需要哪個開關 |
|---|---|---|
| 重新套用目前版本 | 主系統更新中心 | 主系統 |
| 重新套用目前 Agent 版本 | 更新中心 Agent 區 | 主系統+Agent |
| 重新套用 X | Agent 主控台更新頁 | 主系統+Agent |
改完開關要讓容器重讀:主系統 sudo guidantai start、Agent sudo guidant-agent-compose start(restart 不會重讀設定)。降版、跨主版號不論開關一律擋。目前只開在 190。
compliance-manager-be)| 用途 | 檔案 |
|---|---|
| 更新中心 API 路由 | api/product_update/__init__.py、routes/product_update_route.py |
| 更新中心總入口 | app/product_update/service/product_update_app_service.py |
| 主系統自己升級(檢查、下載、寫單) | product_update_flow.py、update_site_client.py、package_downloader.py、package_verifier.py、upgrade_order.py |
| Agent 版本線(檢查、下載、判斷手上是否最新) | agent_release_service.py |
| Agent 推送(分批、暫停、重推、同版重套) | agent_rollout_service.py、agent_rollout_views.py |
| Agent 升級事件 | agent_update_event_handlers.py |
| 同版重套 | same_version.py |
直推 /update 給 Agent |
core/plugins/_agent_commands.py(push_update_soon) |
| Agent 下載包端點 | core/plugins/_agent_update.py、api/remote_agent/routes/agent_update_bundle_route.py |
| Agent 主控台請主系統查、報、更新 | core/plugins/_agent_console_update.py、api/remote_agent/routes/agent_update_request_route.py |
| Agent 事件與升級紀錄上傳 | api/remote_agent/routes/agent_events_route.py、agent_update_log_route.py |
| 主機升級腳本 | scripts/installer/lib/upgrade_order.sh(撿單)、upgrade_runner.sh(跑八步)、upgrade_preflight.sh、upgrade_drain.sh、upgrade_db_copy.sh、upgrade_apply_on_copy.sh、upgrade_health.sh、upgrade_switch.sh、upgrade_cleanup.sh、upgrade_rollback.sh;systemd 單元 scripts/installer/systemd/guidant-upgrade-order.path/.service |
| 出包 | scripts/build/build_all.sh、build_bundle.sh、sbom.sh、release_json.sh、smoke_auto.sh |
evidence-agent)| 用途 | 檔案 |
|---|---|
收 /update 指令 |
guidant_agent/sync/api/cmd_update.py |
| 下載包、寫升級單、判斷升級中、同版開關 | guidant_agent/sync/app/update_sync.py |
| 升級事件、升級紀錄上傳 | guidant_agent/sync/app/update_events.py、update_log_upload.py |
| 主控台更新頁 API | guidant_agent/console/api/update_routes.py、console/app/update_console.py |
| 主控台 8444 伺服器(白名單、TLS 握手) | guidant_agent/identity/app/allow_cidr.py |
| 主機升級腳本(隨 Agent 映像出貨,主機每次從映像讀出來跑) | scripts/install/lib/upgrade_order.sh、upgrade_runner.sh、upgrade_guard.sh、progress.sh;systemd 單元 scripts/install/lib/systemd/ |
主機維運指令 guidant-agent-compose |
deploy/install.sh 安裝 |
| compose 與開關轉傳 | deploy/docker-compose.yml |
| 出包 | scripts/build/build_all.sh、build_agent_release.sh、build_agent_bundle.sh、build_compose_bundle.sh |
版本說明(出包時讀進 notes.json) |
RELEASE_NOTES.md |
compliance-manager-fe)| 用途 | 檔案 |
|---|---|
| 主系統更新中心 | src/views/product-update/UpdateCenter.vue、UpdateConfirmDialog.vue、UpdateHistory.vue、productUpdateState.js;src/composables/useProductUpdate.js |
| 更新中心 Agent 區 | src/views/product-update/AgentRolloutPanel.vue、agentRolloutState.js;src/composables/useAgentRollout.js |
| Agent 主控台更新頁 | console/views/Update.vue、console/update.js、console/updateApi.js、console/useUpdateStatus.js(輪詢與鎖定)、console/components/UpdateLockMask.vue、OfflineUpdateUpload.vue |
update-center)| 用途 | 檔案 |
|---|---|
| 兩條版本線、R2 路徑 | src/releases.ts(r2Key() 是 R2 路徑唯一拼法) |
| 客戶端三支端點、後台 | src/routes/client.ts、src/routes/admin.ts |
| 正式發布 CLI | cli/guidant-release.ts |
| 優化 | 效果 |
|---|---|
| Agent 區一步更新 | 不必先按「預先下載」;手上沒有或只有舊包都會自動下載最新版再推 |
| 升級中維護模式 | 升級時不再收新工作;主控台鎖畫面、換容器後不必重新登入 |
| 主控台立即檢查真的查 | 新版發布後主控台立刻看得到 |
| 更新包自動清理 | 整批推完清 Agent 舊包;主系統升級成功只留清單,各省約 1.7~3.5 GB |
| SeaweedFS 殭屍行程 | 不再每 3 小時要重啟 |
| 8444 強制重新整理不再掉 CSS | 一條卡住的連線不影響其他連線 |
| 同版重套 | 測試機重看升級流程不必再出一版 |
| 出包:測試包略過 SBOM+弱點掃描 | Agent 包 19 分 30 秒 → 15 分 52 秒;主系統約省 5 分 |
| 出包:主系統封包多核壓縮 | 預估省約 4 分(188 有 24 核) |
| 出包:釘版第三方 image 匯出檔快取 | 主系統 5 顆(約 3 GB)、Agent 1 顆不再每版重匯 |
主系統完整出包約 51 分鐘:Nuitka 編譯約 19 分、封包壓縮約 13 分、SBOM+弱點掃描約 9 分、其他約 10 分。Nuitka 在 188 本來就沒開 LTO,--lto=no 不會更快。
| 事 | 白話說明 | 誰接 |
|---|---|---|
| 正式版出版 | 目前上站的都是測試章簽的內部測試包;正式章/Vault 簽的第一版是 1.29 | FR-173 |
| 189 POC 升級 | 仍 1.27.x;升 1.28.x 時 Agent 要手動升一次(1.4.x 沒有 /update) |
待決策者裁時機 |
| release note 1.27.x~1.28.x | 還沒寫 | 待決策者裁 |
| 主控台背景輪詢寫稽核 | 主控台每次問更新狀態都記一筆「看過更新頁」,數量不實 | 未開卡 |
| 主系統發動時主控台最慢 30 秒才鎖 | 平常輪詢間隔 | 決策者裁先這樣 |
| 只改主機腳本也得出版 | 主機每次從現行 Agent 映像讀升級腳本,不能只換 .sh |
未開卡,另議 |
| 守衛測試 8 條紅 | 乾淨 HEAD 一樣紅,非本案造成 | 未開卡 |
| 你想知道 | 看哪份 |
|---|---|
| 現在長什麼樣、程式在哪 | 本頁 |
| PM 常問的問題 | for-pm-qa.md |
| 每一步誰在跑、跑哪支(循序圖+逐步表) | upgrade-flow-guide.md;FR-175 機制問答 · 線上升級執行流程 |
| 為什麼這樣設計 | design.md(v1.0)→ design-v1.1.md(190 實測後的異動) |
| 190 實測回饋原文 | handoff/190-test-feedback.md |
| 哪一棒做了什麼 | handoff/FR-172-LOG.md |
| 怎麼手動出版 | FR-167 release-runbook.md |