本卡屬 FR-167(母卡 CM-3241),卡 P3-2c,階段 P3 更新中心、批 4。只改 BE(主 repo,Repo 欄空著)。依賴:P3-2a、P1-1。
更新中心按「立即」或「排程」後主系統不自己動 docker,而是寫一張更新單到主機目錄;主機上的 systemd 看到檔案就跑 guidantai upgrade --from-order,排程用 systemd-run 到點。執行前重驗包。30 分與 5 分前提醒所有使用者。
D26 的本體:主系統只寫檔、主機只信單;主系統對該目錄只有寫權
extend:端點進 P3-2a 的 service;主機側填 lib/upgrade_order.sh 與 lib/systemd_units.sh;提醒 reuse 既有公告或 toast 機制(先 grep 公告模組)
repo:~/Projects/Billows/Audit-Manager/compliance-manager-be
改既有:app/product_update/service/product_update_app_service.py
改既有:api/product_update/routes/product_update_route.py
改既有:scripts/installer/lib/upgrade_order.sh(P1-1 空殼)
改既有:scripts/installer/lib/systemd_units.sh(P1-1 空殼)
新開:scripts/installer/systemd/guidant-upgrade-order.path
新開:scripts/installer/systemd/guidant-upgrade-order.service
細節在 design.md §5 對應段(~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-167-2610-online-update-channel/design.md,開 design.html 看導覽);本段只列本卡要做到的點:
apply(mode, at, user)/cancel/retry/diag:寫 <GUIDANT_UPGRADE_DIR>/orders/<job_id>.json(schema 照 design §5.5),寫 product_update_jobs;取消=刪單(服務停掉後不給取消,看進度檔步數)。lib/upgrade_order.sh:讀單→重驗包與簽章(過期或被刪→進度檔 skipped+通知)→ 立即呼叫 runner;not_before 有值→systemd-run --on-calendar。lib/systemd_units.sh:裝 guidant-upgrade-order.path(PathChanged=)與 .service;orders/ 目錄 chown root:guidant chmod 730。scheduled_at。systemd-analyze verify。DEV 8003:四個端點寫/刪 upgrade/orders/*.json,schema 照 design §5.5;排程單帶 not_before;upgrade_order.sh --dry-run <單> 讀單、重驗包(假包改一位元組 → 拒)、對照序列;systemd 單元檔用 systemd-analyze verify(在本機 docker ubuntu 容器內跑)綠;提醒走既有公告機制(寫哪支、回寫列);shellcheck 綠
測試期(不是你做):這張卡在 190 的真實情境是「190:按立即→5 秒內 path 單元觸發;選排程到點才跑;取消→單刪除;單上包驗不過→不跑並通知;容器對 upgrade/orders/ 只有寫權」,由首腦在測試期操作、決策者看畫面。你只要確保上面的本機驗收全過、程式對這個情境沒有寫死假設。
對照雛形:~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-167-2610-online-update-channel/prototype/index.html(上方「跟著走」)。