Ansible-处理自定义模块中的意外标准输出

Ansible-处理自定义模块中的意外标准输出,ansible,stdout,ansible-module,Ansible,Stdout,Ansible Module,我编写了一个自定义模块来包装Python库。我对结果的定义如下: result = dict( changed=False, original_message='Running DBSCONTROL', message='' ) 在后面的代码中,我将对库的调用包装为try/except,如下所示: try: dbsc = DbsControl( module.params.get('user'), module.params.ge

我编写了一个自定义模块来包装Python库。我对结果的定义如下:

result = dict(
    changed=False,
    original_message='Running DBSCONTROL',
    message=''
)
在后面的代码中,我将对库的调用包装为
try/except
,如下所示:

try:
    dbsc = DbsControl(
        module.params.get('user'),
        module.params.get('host'),
        module.params.get('script')
    )
    dbsc.runme()
    result['message'] = 'DBSCONTROL_SUCCESSFULL'
    module.exit_json(**result)
except Exception as ex:
    result['message'] = str(ex)
    module.fail_json(msg='Failed DBSCONTROL execution', **result)
我在模块中的任何位置都没有一个
print
语句,我的lib输出记录到一个文件中

最后,我把这个角色称为Ansible

- name: Run dbscontrol utility
  dbscontrol:
    user: "{{ hostvars[groups['dbs_server'][0]]['ansible_user'] }}"
    host: "{{ groups['dbs_server'][0] }}"
    script: "dbscontrol_config.yml"
  register: result
- debug:
    msg: "{{ result }}"
从lib中的最后一条日志消息中,我可以清楚地看到运行已成功完成,但我的模块最终失败,日志消息以

MSG:

MODULE FAILURE
See stdout/stderr for the exact error
奇怪的是,我看到
result
嵌入到输出的MODULE\u STDOUT部分。事实上,这是模块启动前的最后一部分

MODULE_STDOUT和MODULE_STDERR都由来自lib的相同日志消息组成,唯一的区别是
result
相关行:

2020-01-23 13:40:52,070 - ttautils.dbscontrol - INFO - DBS control run is complete, exiting

{"changed": false, "original_message": "Running DBSCONTROL", "message": "DBSCONTROL_SUCCESSFULL", 
    "invocation": {"module_args": {"user": "root", "host": "fiesta1.td.teradata.com", "script": 
    "dbscontrol_config.yml", "dbc_user": "dbc", "dbc_pwd": "dbc", "logfile": "dbscntl_2020-01-23-13-38-15.log",  
    "loglevel": "DEBUG", "validate": "False", "config": "user_config/common", "locale": "TPG_6700C", 
    "timeout": "7200", "disable_local_overrides": false, "params": "user_config/user.yml"}}, 
    "warnings": ["The value False (type bool) in a string field was converted to 'False' (type string). 
        If this does not look like what you expect, quote the entire value to ensure it does not change."]}
问题是模块总是以“失败”结束,即使我知道代码运行成功,playbook也会终止

2天后

好的,我现在知道问题了。这是由于我正在将输出写入STDOUT/STDERR的库,因为它在内部使用子进程。Ansible尝试解析标准输出时失败,因为标准输出中有所有额外的非JSON输出。 如何处理这种情况?我怎样才能保证我的自定义模块有一个只有JSON格式输出的原始标准输出?我试图执行
sys.stdout.flush()
,但没有效果


这实际上使得编写自定义模块变得毫无用处。请回答大师,有什么提示吗?

所以这个问题的答案很简单:当您调用
exit\u json
fail\u json
时,您不能使用任何类型的输出。原因也很简单:在运行代码后,结果由处理。它解析res.get('stdout',u'),如果有任何解析错误,那么您将得到我在问题中提到的大量stdout转储

解决办法并不是那么简单。在调用模块退出方法之前,我尝试了各种各样的方法来清空STDOUT,但没有真正起作用。因此,由于我可以完全控制调用的内容,我只需将日志记录更改为基于我调用的库中的临时文件,并做了一些其他事情来确保我没有以任何方式使用
sys.stdout
。这真的很愚蠢,我希望有人能给我一个更好的方法