首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让Ansible check在攻略中只运行一次?

如何让Ansible check在攻略中只运行一次?
EN

Stack Overflow用户
提问于 2014-02-27 21:37:26
回答 2查看 53.4K关注 0票数 30

为了防止使用过时的攻略,我想确保在Ansible被允许修改服务器上的任何东西之前,我有一个更新的git结帐副本。

这就是我尝试做的事情。此操作位于所有实战手册包含的文件中:

代码语言:javascript
复制
- 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运行一次。我该如何避免这种情况呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-28 04:17:28

已更新

当我第一次写我的答案时(2014-02-27),Ansible没有内置的支持,每个playbook只运行一次任务,而不是运行playbook的每个受影响的主机一次。然而,作为tlo writesrun_once: true在Ansible版本1.7.0 (发布于2014-08-06)中引入了对此的支持。使用此功能,问题中的示例任务定义应更改为

代码语言:javascript
复制
- 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运行playbook的任务之前更新本地git分支。

我写了下面的Ansible回调插件,如果当前的git分支与远程分支不同步(落后或已经分叉),它将避免playbook执行。要使用它,请将以下代码放在顶级Ansible playbook目录中的callback_plugins/require_updated_git_branch.py文件中:

代码语言:javascript
复制
#! /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会提前暂停,并显示以下输出:

代码语言:javascript
复制
 __________________________________________________________
/ 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 |
                ||     ||

而且,正如cow所建议的那样,要关闭此检查,您可以运行以下命令:

代码语言:javascript
复制
$ IGNORE_OUTDATED_GIT_BRANCH=yes ansible-playbook site.yml

此解决方案不能解决常规问题,即无论涉及多少主机,都要避免多次运行任何Ansible任务,但它确保不会执行过时的剧本,并且它处理了您提到的关于my alias-based suggestion的问题。

票数 35
EN

Stack Overflow用户

发布于 2015-12-30 17:14:33

从Ansible的1.7版本开始,您可以使用run_once: true to only run a task one time and only on one host

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22070232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档