在游戏结束时运行特定任务

时间:2020-03-24 05:46:46

标签: ansible

当剧本的所有其他任务完成后,我如何运行特定任务?问题在于这需要在每个剧本中完成。仅添加到每本剧本并不是一个好主意,我需要使它对每个人都通用。每本剧本都有一个共同的角色,但一开始就起作用。是否可以添加从头开始的任务?或执行其他操作的方式,这样始终可以在最后完成而无需编辑每个剧本。

1 个答案:

答案 0 :(得分:0)

您可以通过编写回调插件来实现。这是python代码,当(ansible-internal)事件发生时执行预定义的函数。 您可能会感兴趣的是v2_playbook_on_stats方法,它是最后执行的步骤之一。

为此,请查看Ansible的基本开发人员指南页面: https://docs.ansible.com/ansible/latest/dev_guide/index.html

但更重要的是,《插件指南》: https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html

文档中概述的基本结构是:

from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    pass

他们甚至提供了执行v2_playbook_on_stats方法的正确示例:

# Make coding more python3-ish, this is required for contributions to Ansible
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

# not only visible to ansible-doc, it also 'declares' the options the plugin requires and how to configure them.
DOCUMENTATION = '''
  callback: timer
  callback_type: aggregate
  requirements:
    - whitelist in configuration
  short_description: Adds time to play stats
  version_added: "2.0"
  description:
      - This callback just adds total play duration to the play stats.
  options:
    format_string:
      description: format of the string shown to user at play end
      ini:
        - section: callback_timer
          key: format_string
      env:
        - name: ANSIBLE_CALLBACK_TIMER_FORMAT
      default: "Playbook run took %s days, %s hours, %s minutes, %s seconds"
'''
from datetime import datetime

from ansible.plugins.callback import CallbackBase


class CallbackModule(CallbackBase):
    """
    This callback module tells you how long your plays ran for.
    """
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'aggregate'
    CALLBACK_NAME = 'namespace.collection_name.timer'

    # only needed if you ship it and don't want to enable by default
    CALLBACK_NEEDS_WHITELIST = True

    def __init__(self):

        # make sure the expected objects are present, calling the base's __init__
        super(CallbackModule, self).__init__()

        # start the timer when the plugin is loaded, the first play should start a few milliseconds after.
        self.start_time = datetime.now()

    def _days_hours_minutes_seconds(self, runtime):
        ''' internal helper method for this callback '''
        minutes = (runtime.seconds // 60) % 60
        r_seconds = runtime.seconds - (minutes * 60)
        return runtime.days, runtime.seconds // 3600, minutes, r_seconds

    # this is only event we care about for display, when the play shows its summary stats; the rest are ignored by the base class
    def v2_playbook_on_stats(self, stats):
        end_time = datetime.now()
        runtime = end_time - self.start_time

        # Shows the usage of a config option declared in the DOCUMENTATION variable. Ansible will have set it when it loads the plugin.
        # Also note the use of the display object to print to screen. This is available to all callbacks, and you should use this over printing yourself
        self._display.display(self._plugin_options['format_string'] % (self._days_hours_minutes_seconds(runtime)))

我还要强调DOCUMENTATION字符串的重要性。我首先想到的是,这仅用于生成Doc帮助页面。但不是。查看此示例:

options:
    format_string:
      description: format of the string shown to user at play end
      ini:
        - section: callback_timer
          key: format_string
      env:
        - name: ANSIBLE_CALLBACK_TIMER_FORMAT
      default: "Playbook run took %s days, %s hours, %s minutes, %s seconds"

在其中有ini,env和default部分,它们实际上是用于使用self._plugin_options['format_string']或使用self.get_option("format_string")将选项插入到Callback插件中的,这些列表可以被覆盖的所有回调方法,请参阅https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/callback/init.py

对于您来说,以v2_开头的方法很有趣,因为它们适用于Ansible 2 +。

结帐https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/callback了解更多示例。 但似乎他们目前正在清理很多东西。

因此,我想说的是,请签出Version Tag,例如: https://github.com/ansible/ansible/tree/v2.9.6/lib/ansible/plugins/callback

希望这会有所帮助。