Ansible-处理自定义模块中的意外STDOUT

问题描述 投票:0回答:1

我写了一个包装Python库的自定义模块。我将result字典定义如下:

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 }}"

从我库中的最后一个记录器消息中,我可以清楚地看到运行成功完成,但是我的模块最终由于记录器消息的大量输出而失败,并以]开头]

MSG:

MODULE FAILURE
See stdout/stderr for the exact error

奇怪的是,我看到result嵌入到输出的MODULE_STDOUT部分中。实际上,这是MODULE_STDERR开始之前的最后一部分

[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."]}

问题是,模块总是以“失败”结尾,并且即使我知道我的代码成功运行,剧本也会终止。

[2天后

好,我现在知道了问题。这是由于我正在将输出包装到STDOUT / STDERR的库的缘故,因为它在内部使用子进程。当Ansible尝试解析STDOUT时,由于STDOUT中所有额外的非JSON输出,它会失败in this method。如何处理这种情况?如何保证我的自定义模块具有仅包含JSON格式输出的原始STDOUT?我试图做sys.stdout.flush()无济于事。

这实际上使编写自定义模块无效。请Ansible专家,有什么提示吗?

我写了一个包装Python库的自定义模块。我将结果dict定义如下:result = dict(change = False,original_message ='Running DBSCONTROL',message ='')稍后在代码I ...

ansible stdout ansible-module
1个回答
0
投票

因此,此问题的答案很简单:当您调用exit_jsonfail_json时,您将无法获得带有任何类型输出的sys.stdout。原因也很简单:运行代码后,结果由this Ansible code处理。哪个会解析res.get('stdout', u''),并且如果有任何解析错误,那么您最终会遇到我在问题中提到的海量STDOUT转储。

© www.soinside.com 2019 - 2024. All rights reserved.