繁体   English   中英

如何让 Ansible 检查在剧本中只运行一次?

[英]How to get an Ansible check to run only once in a playbook?

为了防止使用过时的剧本,我想确保在 Ansible 被允许修改服务器上的任何内容之前,我有一个更新的 git checkout 副本。

这就是我尝试这样做的方式。 此操作位于所有剧本都包含的文件中:

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

问题是这个命令为 Ansible 连接的每个节点运行一次,而不是每个 playbook 运行只运行一次。 我怎样才能避免这种情况?

更新

当我开始写我的答案 (2014-02-27) 时,Ansible 没有内置支持每个剧本运行一次任务,而不是每个运行剧本的受影响主机一次。 然而,正如tlo 所写,在 Ansible 1.7.0 版(2014 年 8 月 6 日发布)中通过run_once: true引入了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 任务而不管所涉及的主机数量如何的一般问题,但它确保不执行过时的剧本,并且它处理了您提到的关于我的基于别名的建议的问题.

从 Ansible 1.7 版开始,您可以使用run_once: true 仅在一台主机上运行一次任务

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM