请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

在ansible ad-hoc api中定义了两个任务,为什么callback只返回了最后一个任务的结果

老师,您好!
我在ansible中定义了两个任务
图片描述
执行了脚本后,发现两个任务都执行了,但是callback只返回了最后一个任务的结果,这是为什么呢?该如何解决?

from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase

#DataLoader()用于加载和解析yaml或json格式的文件,sources传递一个列表(表示从哪读取文件)
#InventoryManager类
loader = DataLoader()
inventory = InventoryManager(loader=loader,sources=['imoocc_hosts'])

#VariableManager类
variable_manager = VariableManager(loader=loader,inventory=inventory)

#Options 执行选项
Options = namedtuple('Options',
                     ['connection',
                      'remote_user',
                      'ask_sudo_pass',
                      'verbosity',
                      'ack_pass',
                      'module_path',
                      'forks',
                      'become',
                      'become_method',
                      'become_user',
                      'check',
                      'listhosts',
                      'listtasks',
                      'listtags',
                      'syntax',
                      'sudo_user',
                      'sudo',
                      'diff'])
options = Options(connection='smart',
                       remote_user=None,
                       ack_pass=None,
                       sudo_user=None,
                       forks=5,
                       sudo=None,
                       ask_sudo_pass=False,
                       verbosity=5,
                       module_path=None,
                       become=None,
                       become_method=None,
                       become_user=None,
                       check=False,
                       diff=False,
                       listhosts=None,
                       listtasks=None,
                       listtags=None,
                       syntax=None)
#Play 执行对象和模块
play_source =  dict(
        name = "Ansible Play ad-hoc test",
        hosts = '192.168.44.129',
        gather_facts = 'no',
        tasks = [
            dict(action=dict(module='shell', args='touch /tmp/ad_hoc_test1')),
            dict(action=dict(module='shell', args='touch /tmp/ad_hoc_test2')),
            # dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
         ]
    )
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

class ModelResultsCollector(CallbackBase):
    def __init__(self, *args, **kwargs):
        #super().__init__(*args, **kwargs)
        super(ModelResultsCollector,self).__init__(*args, **kwargs)
        self.host_ok = {}
    def v2_runner_on_ok(self, result):
    #def v2_runner_item_on_ok(self, result):
        self.host_ok[result._host.get_name()] = result

callback = ModelResultsCollector()

passwords = dict()
tqm = TaskQueueManager(
          inventory=inventory,
          variable_manager=variable_manager,
          loader=loader,
          options=options,
          passwords=passwords,
          stdout_callback=callback,
      )
result = tqm.run(play)

result_raw = {'success':{},'failed':{},'unreachable':{}}
for host,result in callback.host_ok.items():
    result_raw['success'][host] = result._result

print(result_raw)

结果输出

{
	'success': {
		'192.168.44.129': {
			'changed': True,
			'end': '2019-10-22 03:08:04.834335',
			'stdout': '',
			'cmd': 'touch /tmp/ad_hoc_test2',
			'rc': 0,
			'start': '2019-10-22 03:08:04.829248',
			'stderr': '',
			'delta': '0:00:00.005087',
			'invocation': {
				'module_args': {
					'warn': True,
					'executable': None,
					'_uses_shell': True,
					'_raw_params': 'touch /tmp/ad_hoc_test2',
					'removes': None,
					'creates': None,
					'chdir': None,
					'stdin': None
				}
			},
			'warnings': ['Consider using file module with state=touch rather than running touch'],
			'_ansible_parsed': True,
			'stdout_lines': [],
			'stderr_lines': [],
			'_ansible_no_log': False,
			'failed': False
		}
	},
	'failed': {},
	'unreachable': {}
}

正在回答 回答被采纳积分+3

2回答

提问者 404_ 2019-10-23 17:40:57


https://img1.sycdn.imooc.com/szimg/5db01f87096bf07a06400072.jpg

https://img1.sycdn.imooc.com//szimg/5db01fd9092b80b118830777.jpg

result_raw的输出是:

{

'success': {

'192.168.44.131': {

'changed': True,

'end': '2019-10-23 10:30:04.057512',

'stdout': '',

'cmd': 'touch /tmp/ad_hoc_test2',

'rc': 0,

'start': '2019-10-23 10:30:04.053824',

'stderr': '',

'delta': '0:00:00.003688',

'invocation': {

'module_args': {

'warn': True,

'executable': None,

'_uses_shell': True,

'_raw_params': 'touch /tmp/ad_hoc_test2',

'removes': None,

'creates': None,

'chdir': None,

'stdin': None

}

},

'warnings': ['Consider using file module with state=touch rather than running touch'],

'_ansible_parsed': True,

'stdout_lines': [],

'stderr_lines': [],

'_ansible_no_log': False,

'failed': False

}

},

'failed': {},

'unreachable': {}

}


0 回复 有任何疑惑可以回复我~
Jeson 2019-10-23 09:40:39

1、把这个self.host_ok[result._host.get_name()]内容打印出来看看

2、这个逻辑只记录了执行成功的,是不是可能另外一条命令执行没有成功。

0 回复 有任何疑惑可以回复我~
  • 提问者 404_ #1
    第一:
    self.host_ok[result._host.get_name()]打印了两遍,内容是
    self.host_ok[result._host.get_name()]: <ansible.executor.task_result.TaskResult object at 0x7f802e9f9940>
    self.host_ok[result._host.get_name()]: <ansible.executor.task_result.TaskResult object at 0x7f802e785f60>
    但是result_raw只有一条记录,说touch /tmp/ad_hoc_test2
    
    第二:在目标机器上两个文件都已经创建了,说明两条命令都成功了
    
    我把具体截图放到了添加回答里面
    回复 有任何疑惑可以回复我~ 2019-10-23 17:36:51
  • Jeson 回复 提问者 404_ #2
    执行成功,但日志中打印success的记录没出来。
    再看看callback.host_ok.items()是不是有?如果没有往上一级找下。
    for host,result in callback.host_ok.items():
        result_raw['success'][host] = result._result
    回复 有任何疑惑可以回复我~ 2019-10-25 11:31:23
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信