Skip to content

bug(os-patch-sla): target_group 寫死成 sandbox,staging/prod stage 下 play 選不到主機,patch SLA 從未套用 #177

Closed

Description

@kjelly

問題

playbooks/apply/os-patch-sla-apply.yml 的 play vars 把 target_group 寫死成 sandbox,所以不管 patch_stage 是什麼,這個 play 都只會選 sandbox group 的主機。

以下行號以 main 540f736f 為準:

# os-patch-sla-apply.yml:36-42
- name: OS patch SLA apply (stage={{ patch_stage }}, target={{ target_group | default(patch_stage) }})
  hosts: "{{ target_group | default(patch_stage) }}"
  ...
  vars:
    patch_stage: sandbox
    target_group: sandbox

hosts: 的本意是「沒指定 target_group 時,用 patch_stage 這個 group」。但 target_group 在 play vars 裡已經有值,default(patch_stage) 永遠不會生效。

pilot deploy/pilot reconcile 帶 --stage 時,只會傳 stage= 和 patch_stage=(cmd/pilot/cmd/deploy.go:3231),不會傳 target_group。site.yml:261 匯入這支 playbook 時也沒有帶 vars。

重現

ansible-core 2.19.2,假的 inventory,--list-hosts 不會連到任何主機:

# inv.yml
all:
  vars: {ansible_connection: local}
  children:
    prod: {hosts: {prod1: {}}}
    staging: {hosts: {stg1: {}}}
    sandbox: {hosts: {sbx1: {}}}
指令 play 選到的主機
-e patch_stage=sandbox sandbox → sbx1
-e patch_stage=staging sandbox → sbx1
-e patch_stage=prod sandbox → sbx1
-e patch_stage=prod -e target_group=prod prod → prod1

影響

  • inventory 只有 staging 或 prod 主機時(例如每個環境一個 workspace):pilot deploy --stage prod 的 site.yml 會印出
    PLAY [OS patch SLA apply (stage=prod, target=sandbox)]
    skipping: no hosts matched
    
    run 仍然是成功,所以 staging/prod 主機從來不會套用 patch SLA,也沒有任何錯誤或警告。這是在一次真實的 site-wide prod preview 裡看到的。
  • inventory 同時有 sandbox 主機時:--stage prod 會選到 sandbox 主機,再被「patch_stage must match this host's inventory environment group」這道 gate(:85)擋下,整次 run 失敗。
  • pilot deploy 單一 playbook 模式在精靈裡填了 target_group 時,會用 -e target_group= 覆寫,所以不受影響。

其他 playbook 的 play vars 也有 target_group(docker、reverse-proxy、seaweedfs-s3 等),但寫的是它們自己的角色 group,跟 stage 無關,沒有這個問題。

建議

  1. 把 play vars 裡的 target_group: sandbox 拿掉,讓 hosts: 的 default(patch_stage) 生效。其他 playbook 也有刻意不在 play vars 宣告覆寫用變數的先例(例如 prometheus-apply.yml 的註解)。
  2. 加一個 regression test:對 sandbox/staging/prod 各跑一次 --list-hosts,確認選到的是 patch_stage 對應的 group。也要確認修正前這個測試會失敗。
  3. 可以考慮讓 site.yml 在非 sandbox stage 下,遇到「某個 play 一台主機都沒選到」時發出警告。這次 stage 一改,patch SLA 就整段沒套用,卻沒有任何提示。

注意

修好之後,staging/prod 主機會第一次跑這支 playbook:安裝並啟用 unattended-upgrades、覆寫 /etc/apt/apt.conf.d/50unattended-upgrades。等 #172 也修好之後,就會真的安裝安全性更新。建議跟 #172 的「各 stage 要不要在 apply 時升級」政策一起決定。

相關:#172、#174、#167。

Activity

  1. kjelly commented on Oct 29, 2026

    @kjelly
    OwnerAuthor

    #174 的修正(spec §1 改成純環境 group)會在 docs/verification/os-patch-sla.md 留下一段針對這個 bug 的 workaround 說明,修 #177 時請一起更新:

    1. §1 表下說明:目前寫「staging/prod 必須同時帶 -e target_group=,因為 play vars 的 target_group: sandbox 讓 hosts: 的 default(patch_stage) 永遠不會生效」,並列出 staging/prod 的 vm-target test 指令(含 -e target_group=staging / -e target_group=prod)。拿掉 target_group: sandbox 之後,這段與指令中的 -e target_group= 要刪掉或改寫。
    2. §7 SOP 步驟 2、4:staging/prod 的 ansible-playbook 指令目前帶 -e target_group=staging / -e target_group=prod,同樣要跟著修。
    3. playbooks/apply/os-patch-sla-apply.yml 檔頭的 Usage 註解:staging/prod 範例目前只有 -e patch_stage=…,在今天的 main 上會選到 0 台主機;bug(os-patch-sla): target_group 寫死成 sandbox,staging/prod stage 下 play 選不到主機,patch SLA 從未套用 #177 修好後這些範例就是正確的(不需要另外開 issue)。

    另外,#177 建議的 regression test 若對 sandbox/staging/prod 各跑一次 --list-hosts,可參考 #174 的實跑:在 vm-target 用 --hosts staging / --hosts prod 建 VM,帶 -e patch_stage=… -e target_group=… 時 play 能選到該 VM。

  2. self-assigned this
    on Oct 29, 2026
  3. added a commit that references this issue on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions