2014-02-27 35 views
9

爲了防止使用過時的劇本,我希望確保我有一個更新的git checkout副本,然後Ansible被允許修改服務器上的任何內容。如何獲得Ansible支票只能在劇本中運行一次?

這就是我試圖去做的。這個動作位於所有遊戲書包含的文件:

- name: Ensure local git repository is up-to-date 
    local_action: git pull 
    register: command_result 
    failed_when: "'Updating' in command_result.stdout" 

的問題是,該命令在Ansible連接到每個節點運行一次,而不是僅一次爲每個劇本運行。我怎樣才能避免這種情況?

回答

12

更新

當我的拳頭寫我的答案(2014年2月27日),Ansible沒有內置支持運行任務只有一次每劇本,%的受影響主機的一次是,劇本運行。但是,作爲tlo writes,在Ansible版本1.7.0(2014-08-06發佈)中引入了對run_once: true的支持。使用此功能,問題的示例任務定義應更改爲

- name: Ensure local git repository is up-to-date 
    local_action: git pull 
    run_once: true 
    register: command_result 
    failed_when "'Updating' in command_result.stdout" 

完成要求的內容。

原來的答案

[以下答案我對確保Ansible運行劇本的任務之前,當地的Git分支更新的具體問題建議的解決方案。]

我寫的下面的Ansible回調插件可以避免當前的git分支與遠程分支不同步(或者在後面或者已經發散)時避免手冊執行。要使用它,將下面的代碼在您的頂級Ansible劇本目錄像callback_plugins/require_updated_git_branch.py文件:

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import os 
import re 
import subprocess 
import sys 

from ansible.callbacks import display, banner 


class CallbackModule(object): 
    """Makes Ansible require that the current git branch is up to date. 
    """ 
    env_var_name = 'IGNORE_OUTDATED_GIT_BRANCH' 

    msg = 'OUTDATED GIT BRANCH: Your git branch is out of sync with the ' \ 
      'remote branch. Please update your branch (git pull) before ' \ 
      'continuing, or skip this test by setting the environment ' \ 
      'variable {0}=yes.'.format(env_var_name) 

    out_of_sync_re = re.compile(r'Your branch (is behind|and .* have diverged)', 
           re.MULTILINE) 

    def __init__(self, *args, **kwargs): 
     if os.getenv(self.env_var_name, 'no') == 'yes': 
      self.disabled = True 

    def playbook_on_start(self): 
     subprocess.call(['git', 'fetch']) 

     if self.out_of_sync_re.search(subprocess.check_output([ 
      'git', 'status', '--untracked-files=no'])): 
      display(banner(self.msg), color='bright purple') 
      sys.exit(1) 

例如,當本地分支機構的遠程分支,命令後面ansible-playbook site.yml暫停年初以下輸出:

__________________________________________________________ 
/OUTDATED GIT BRANCH: Your git branch is out of sync with \ 
| the remote branch. Please update your branch (git pull) | 
| before continuing, or skip this test by setting the  | 
\ environment variable IGNORE_OUTDATED_GIT_BRANCH=yes. /
---------------------------------------------------------- 
     \ ^__^ 
     \ (oo)\_______ 
      (__)\  )\/\ 
       ||----w | 
       ||  || 

而且,隨着牛建議,關閉這個檢查,你可以像運行命令:

$ IGNORE_OUTDATED_GIT_BRANCH=yes ansible-playbook site.yml 

釷解決方案並不能解決避免一次性運行任何Ansible任務而不考慮主機數量的一般問題,但它可以確保過時的操作手冊不會被執行,並且它處理您提到的關於我的alias-based suggestion的問題。