当ansible查找失败时如何回退到默认值?

时间:2017-04-04 15:58:27

标签: ansible jinja2

我发现他的一段代码因IOError异常失败而不是默认省略该值而感到有些惊讶。

#!/usr/bin/env ansible-playbook -i localhost,
---
- hosts: localhost
  tasks:
    - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') | default(omit) }}"

如何在不引发异常的情况下加载值?

请注意,查找模块支持默认值参数,但这个参数对我来说没用,因为它只有在可以打开文件时才有效。

我需要一个默认值,即使它无法打开文件也能正常工作。

4 个答案:

答案 0 :(得分:4)

据我所知,不幸的是Jinja2不支持任何try / catch机制。

所以你要么向Ansible团队修补ini查找插件/文件问题,要么使用这个丑陋的解决方法:

    let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest()  // fetch the Item.


    // display it by Sort.

    let priceSort = NSSortDescriptor(key: "price", ascending: true)
    let titleSort = NSSortDescriptor(key: "title", ascending: true)
    let dateSort = NSSortDescriptor(key: "created", ascending: false)


    if segment.selectedSegmentIndex == 0 {
        fetchRequest.sortDescriptors = [dateSort]

    } else if segment.selectedSegmentIndex == 1 {
        fetchRequest.sortDescriptors = [priceSort]

    } else if segment.selectedSegmentIndex == 2 {
        fetchRequest.sortDescriptors =  [titleSort]

    }

在此示例中--- - hosts: localhost gather_facts: no tasks: - debug: msg="{{ lookup('first_found', dict(files=['test-ini.conf'], skip=true)) | ternary(lookup('ini', 'foo section=DEFAULT file=test-ini.conf'), omit) }}" 查找返回文件名(如果文件存在)或否则为空列表。如果文件存在,则first_found过滤器调用ternary查找,否则返回ini占位符。

答案 1 :(得分:0)

为了避免在路径不存在时出错,请在尝试查找之前使用条件检查路径:

---

- hosts: localhost
  tasks:

    - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
      when: missing-file.conf | exists

你也可以在set_fact使用它,然后在需要时省略未定义的var:

- hosts: localhost
  tasks:

    - set_fact:
        foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
      when: missing-file.conf | exists

    - debug:
        var: foo  # undefined
        msg: "{{ foo | default(omit) }}"  # omitted

请注意,查找和Jinja2 tests控制器上运行。如果您需要检查主机上的路径,请使用stat以及slurpfetch模块:

- stat:
    file: missing-remote-file-with-text-i-want
  register: file

- slurp:
    src: missing-remote-file-with-text-i-want
  register: slurp
  when: file.stat.exists

- set_fact:
    foo: "{{ slurp.content | b64decode }}"
  when: file.stat.exists

- fetch:
    src: missing-file.conf
    dest: /tmp/fetched
    fail_on_missing: False

- set_fact:
    bar: "{{ lookup('ini', 'foo section=DEFAULT file=/tmp/fetched/' + inventory_hostname + '/missing-file.conf') }}"
  when: ('/tmp/fetched/' + inventory_hostname + '/missing-file.conf') | exists

第二点,在Ansible v2.5中,使用路径测试的语法已经改变,格式现在是:

- set_fact:
    foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
  when: missing-file.conf is exists

答案 2 :(得分:0)

在使用默认过滤器之前,您还可以使用from_yaml过滤器转换输入文件

- name: "load a yaml file or a default value"
  set_fact:
    myvar: "{{ lookup('file', 'myfile.yml', errors='ignore') | from_yaml | default(mydefaultObject, true) }}"

答案 3 :(得分:0)

您可以按如下方式使用阻止/救援:

- hosts: localhost
  tasks:
    - block:
        - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}"
      rescue:
        - debug: msg="omit"