首页 > 解决方案 > Ansible,无法将标准输出保存为变量

问题描述

具有以下用于检索 ceph 池配置、页数的 ansible playbook。存储在 JSON 中的输出,我无法仅存储/检索标准输出值的问题。想法是将标准输出值用于另一个循环,该循环创建具有完全相同页数的池

- name: retrieve number of pg for all metric pools
    shell: ceph osd pool get {{ item.poolname }} pgp_num -f json
    loop: "{{ metricspools }}"
    register: poolpg

  - name: output poolpg
    set_fact:
      pgout: "{{ poolpg.stdout | from_json }}"
  - debug: var=pgout

给我错误

FAILED! => {"msg": "Unexpected templating type error occurred on ({{ poolpg.stdout | from_json }}): expected string or buffer"}

但是,如果我更改为以下

- name: output poolpg
  set_fact:
      pgout: "{{ poolpg }}"
- debug: var=pgout

然后将打印包含所有字符串(包括所需的标准输出值)的整个 JSON 整个 JSON 输出:

ok: [es-si-ce-dev-998.admin] => {
    "poolpg": {
        "changed": true, 
        "msg": "All items completed", 
        "results": [
            {
                "_ansible_ignore_errors": true, 
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "changed": true, 
                "cmd": "ceph osd pool get staniX pgp_num -f json", 
                "delta": "0:00:00.251288", 
                "end": "2019-12-10 16:43:09.160898", 
                "failed": false, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "ceph osd pool get staniX pgp_num -f json", 
                        "_uses_shell": true, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "stdin": null, 
                        "warn": true
                    }
                }, 
                "item": {
                    "poolname": "staniX", 
                    "poolnum": 3174
                }, 
                "rc": 0, 
                "start": "2019-12-10 16:43:08.909610", 
                "stderr": "", 
                "stderr_lines": [], 
                "stdout": "\n{\"pool\":\"staniX\",\"pool_id\":3174,\"pgp_num\":128}", 
                "stdout_lines": [
                    "", 
                    "{\"pool\":\"staniX\",\"pool_id\":3174,\"pgp_num\":128}"
                ]
            }, 
            {
                "_ansible_ignore_errors": true, 
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "changed": true, 
                "cmd": "ceph osd pool get staniY pgp_num -f json", 
                "delta": "0:00:00.252257", 
                "end": "2019-12-10 16:43:10.753515", 
                "failed": false, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "ceph osd pool get staniY pgp_num -f json", 
                        "_uses_shell": true, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "stdin": null, 
                        "warn": true
                    }
                }, 
                "item": {
                    "poolname": "staniY", 
                    "poolnum": 3175
                }, 
                "rc": 0, 
                "start": "2019-12-10 16:43:10.501258", 
                "stderr": "", 
                "stderr_lines": [], 
                "stdout": "\n{\"pool\":\"staniY\",\"pool_id\":3175,\"pgp_num\":64}", 
                "stdout_lines": [
                    "", 
                    "{\"pool\":\"staniY\",\"pool_id\":3175,\"pgp_num\":64}"
                ]
            }
        ]
    }
}

标签: jsonansible

解决方案


您注册poolpg一个有循环的任务。因此poolpg.stdout不存在,但poolpg.results[0].stdout确实存在。你得到的结果和你首先循环的元素一样多。

要从结果中的所有标准输出中列出 json 对象,请使用以下示例:

  1. 提取stdout每个属性poolpg.results
  2. from_json过滤器映射到每个元素
  3. 存储结果pgout并显示结果
---
- name: Parse several results as json strings
  hosts: localhost
  gather_facts: false

  vars:
    # Your data reduced to a single json line.
    # Structured view available in your question
    poolpg: {"changed": true, "msg": "All items completed", "results": [{"_ansible_ignore_errors": true, "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "ceph osd pool get staniX pgp_num -f json", "delta": "0:00:00.251288", "end": "2019-12-10 16:43:09.160898", "failed": false, "invocation": {"module_args": {"_raw_params": "ceph osd pool get staniX pgp_num -f json", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true}}, "item": {"poolname": "staniX", "poolnum": 3174}, "rc": 0, "start": "2019-12-10 16:43:08.909610", "stderr": "", "stderr_lines": [], "stdout": "\n{\"pool\":\"staniX\",\"pool_id\":3174,\"pgp_num\":128}", "stdout_lines": ["", "{\"pool\":\"staniX\",\"pool_id\":3174,\"pgp_num\":128}"]}, {"_ansible_ignore_errors": true, "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "ceph osd pool get staniY pgp_num -f json", "delta": "0:00:00.252257", "end": "2019-12-10 16:43:10.753515", "failed": false, "invocation": {"module_args": {"_raw_params": "ceph osd pool get staniY pgp_num -f json", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true}}, "item": {"poolname": "staniY", "poolnum": 3175}, "rc": 0, "start": "2019-12-10 16:43:10.501258", "stderr": "", "stderr_lines": [], "stdout": "\n{\"pool\":\"staniY\",\"pool_id\":3175,\"pgp_num\":64}", "stdout_lines": ["", "{\"pool\":\"staniY\",\"pool_id\":3175,\"pgp_num\":64}"]}]}

  tasks:
    - name: Read each stdout as json
      set_fact:
        pgout: "{{ poolpg.results | map(attribute='stdout') | map('from_json') | list }}"

    - name: Show result
      debug:
        var: pgout

这使:

PLAY [Parse several results as json strings] ****************************************************************************************************************************************************************************************************************************

TASK [Read each stdout as json] *****************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show result] ******************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "pgout": [
        {
            "pgp_num": 128,
            "pool": "staniX",
            "pool_id": 3174
        },
        {
            "pgp_num": 64,
            "pool": "staniY",
            "pool_id": 3175
        }
    ]
}

PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

推荐阅读