2016-02-03 33 views
0

在滾動更新之前,我想爲我們的監控工具中的每臺主機設置停機時間。我爲此創建了一個自定義模塊。設置停機時間可能會出現問題,這在我們的最終目標中無法修復。在這種情況下,我想讓用戶選擇是否應該放棄部署或繼續部署而不設置停機時間。每個主機「暫停」

所以我們可以說我把我的模塊,像這樣:

- downtime: 
    duration: 5m 
    comment: whatever 
    ignore_errors: true 
    register: downtime 

所以我忽略了錯誤,才能夠繼續。否則,設置停機時間失敗的主機將不會被進一步處理。

在接下來的步驟中,我希望用戶手動確認是否要爲每個沒有設置停機時間的主機進行操作。

- name: Request user confirmation to proceed in case downtime could not be set 
    pause: 
    prompt: 'Downtime could not be set for all hosts. Do you want to proceed? Press return to continue. Press Ctrl+c and then "a" to abort' 
    when: "{{ downtime | failed }}" 

不幸的是,pause模塊(實際上這是一個動作插件)只會暫停已處理的第一個主機。因此,如果第一臺主機出現故障,它會暫停,如果第一臺主機通過,所有其他主機出現故障,它將繼續執行所有主機。

這似乎是預期的行爲。從docs

暫停模塊集成到異步/並行化劇本沒有任何特殊考慮(另請參閱:滾動更新)。在使用serial playbook參數(如滾動更新)中使用暫停時,只會爲當前主機組提示一次。

所以無論怎麼樣,就算我會用serial: 1(這不會在這種情況下是可能的)暫停只會停止第一個主機。

現在我只是暫停而沒有條件,並讓用戶決定是否要繼續或不休息,而不管停機時間任務是否失敗。但由於失敗應該非常罕見,這是我想避免的手動步驟。

任何人都可以看到的解決方案如何可以:

  • 停頓主機(失敗)
  • 暫停一次,萬一任何主機發生故障

回答

1

This bug report了我是一個循環工作的靈感。下面的解決方案要求提供單獨的每個故障主機的確認:

- downtime: 
    duration: 5m 
    comment: whatever 
    ignore_errors: true 
    register: downtime 

- name: Saving downtime state 
    set_fact: 
    downtime_failed: "{{ downtime | failed }}" 

- name: Request user confirmation to proceed in case downtime could not be set 
    pause: 
    prompt: 'Downtime could not be set for {{ item }}. Do you want to proceed? Press return to continue. Press Ctrl+c and then "a" to abort' 
    when: "{{ hostvars[item]['downtime_failed'] }}" 
    with_items: "{{ play_hosts }}" 

由於pause模塊僅在清單中列舉的第一個主機,我們遍歷所有可用的主機(play_hosts)運行。要從所有其他主機訪問狀態,我們首先需要將結果存儲爲事實(set_fact),稍後我們可以通過hostvars訪問該狀態,該文件包含當前播放所有主機的所有事實。

1

要運行一組主機的pause模塊,我做了這一招:

- pause: 
    prompt: "{{ item }} will be restarted. Enter 'YES' to restart" 
    register: input 
    with_items: "{{ play_hosts }}" 

- set_fact: 
    user_input: "{{ item.user_input }}" 
    with_items: "{{ hostvars[play_hosts.0].input.results }}" 
    when: item.item == ansible_hostname|upper 

正如udondan說,pause模塊組的第一個主機上運行。通過這兩項任務,我們爲每個主機提供輸入,併爲所有主機設置新的事實。