Подтвердить что ты не робот

Ansible включает задачу только в том случае, если файл существует

Я пытаюсь включить файл только в том случае, если он существует. Это позволяет настраивать "задачи/роли" между существующими "задачами/ролями", если это необходимо пользователю моей роли. Я нашел это:

- include: ...
  when: condition

Но в Ansible docs указано, что:

"Все задачи оцениваются, но условное применяется к каждой задаче" - http://docs.ansible.com/playbooks_conditionals.html#applying-when-to-roles-and-includes

Итак,

- stat: path=/home/user/optional/file.yml
  register: optional_file
- include: /home/user/optional/file.yml
  when: optional_file.stat.exists

Ошибка, если включенный файл не существует. Я предполагаю, что может быть еще один механизм, позволяющий пользователю добавлять задачи к существующему рецепту. Я не могу позволить пользователю добавлять роль после моего, потому что они не будут контролировать порядок: их роль будет выполнена после моего.

4b9b3361

Ответ 1

Спасибо всем за вашу помощь! Я отвечаю на свой вопрос после того, как, наконец, попытаюсь ответить на все ответы и мой собственный код вопроса сегодня. Ansible: ansible 2.0.1.0

Теперь мой исходный код работает, за исключением того, что дополнительный файл, который я искал, был на моем локальном компьютере, поэтому мне пришлось запустить stat через local_action и установить become: no для этих конкретных задач, поэтому он не попытался бы сделать это sudo на моей локальной машине и ошибка с: "sudo: требуется пароль \n"

- local_action: stat path=/home/user/optional/file.yml
  register: optional_file
  become: no
- include: /home/user/optional/file.yml
  when: optional_file.stat.exists

Ответ 2

Условие with_first_found может выполнить это без stat или local_action. Это условие будет проходить через список локальных файлов и выполнить задачу с item, установленной в путь к первому существующему файлу. Включение skip: true в параметры with_first_round предотвратит его отказ, если ни один из файлов не существует

Пример:

- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - include: "{{ item }}"
      with_first_found:
        - files:
            - /home/user/optional/file.yml
          skip: true

Ответ 3

Я использую что-то похожее, но для файлового модуля, и для чего трюк для меня - проверить определение переменной, попробуйте что-то вроде:

when: optional_file.stat.exists is defined and optional_file.stat.exists

задача будет выполняться только тогда, когда существует переменная.

Ответ 4

Я мог бы потратить здесь время на bash возможные действия по обработке ошибок, но, короче говоря, вы правы, и вы не можете использовать модуль stat для этой цели по указанным причинам.

Самое простое решение для большинства проблем - это сделать это вне возможности. Например.

- shell: test -f /home/user/optional/file.yml     # or use -r if you're too particular.
  register: optional_file
  failed_when: False
- include: /home/user/optional/file.yml
  when: optional_file.rc == 0
- debug: msg="/home/user/optional/file.yml did not exist and was not included"
  when: optional_file.rc != 0

* failed_when, чтобы избежать исключения хоста из дальнейших задач, когда файл не существует.

Ответ 5

Если я не ошибаюсь, вы хотите продолжить воспроизведение, даже если инструкция false?

Если да, добавьте эту строку после when:

ignore_errors: True

Итак, ваши задачи будут выглядеть так:

- stat: path=/home/user/optional/file.yml
  register: optional_file
- include: /home/user/optional/file.yml
  when: optional_file.stat.exists
  ignore_errors: True

Пожалуйста, дайте мне знать, если я правильно понял ваш вопрос или могу помочь. Благодаря

Ответ 6

Лучший вариант, который я придумал, заключается в следующем:

- include: "{{ hook_variable | default(lookup('pipe', 'pwd') ~ '/hooks/empty.yml') }}"

Это не совсем "if-exists", но дает пользователям вашей роли тот же результат. Создайте несколько переменных внутри вашей роли и пустой файл по умолчанию. Фильтры Jinja "по умолчанию" и "lookup" заботятся о возврате в пустой файл, если переменная не была установлена.

Для удобства пользователь может использовать переменную {{ playbook_dir }} для установки путей:

hook_variable: "{{ playbook_dir }}/hooks/tasks-file.yml" 

Ответ 7

Используя ansible-2.1.0, я могу использовать такие фрагменты в моей книге:

- hosts: all
  gather_facts: false
  tasks:
    - name: Determine if local playbook exists
      local_action: stat path=local.yml
      register: st

- include: local.yml
  when: st.stat.exists

Я не получаю ошибок/сбоев, когда local.yml не существует, а playbook исполняется (в качестве учебника, то есть начинается с строки hosts: и т.д.)

Вы можете сделать то же самое на уровне задачи вместо этого с похожим кодом. Использование stat будет работать правильно.