2015-01-23 6 views
25

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

- include: ... 
    when: condition 

Но анзибль документов утверждают, что:

«Все задачи получить оценку, но условно применяются к каждому и каждой задаче» - 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 

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

+0

Я потратил немного времени, работая над этим и, кажется, вы правы, это, конечно, не может, даже если 'when' условие ложный. – tedder42

ответ

8

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

Мой исходный код, кажется, работает в настоящее время, за исключением дополнительного файла, который я смотрел был в моем локальная машина, поэтому мне пришлось запустить stat через local_action и установить become: no для этих конкретных задач, поэтому ansible не попытался бы выполнить 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 
+0

Можно ли сделать что-то подобное для ролей: «включить» роль только в том случае, если она существует? Я попытался с pre_tast проверить основной файл для существования роли, сохранить переменную, а затем использовать эту переменную при включении роли, но не удалось выполнить «роль» debian_stock_config «не найдена». спасибо –

+0

Привет, Игорь, это выходит за рамки этого вопроса, вы можете начать свой собственный, чтобы больше внимания уделять вашей конкретной проблеме. – Leito

1

Если я не ошибаюсь, вы хотите продолжить игру, даже если утверждение 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 

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

+2

Спасибо, кажется, вы понимаете вопрос, но это не сработает. ignore_errors не будет игнорировать тот факт, что файл отсутствует. Я думаю, что http://docs.ansible.com/playbooks_error_handling.html#ignoring-failed-commands смутно говорит об этом, когда говорит: «Обратите внимание, что вышеупомянутая система управляет только отказом конкретной задачи, поэтому, если у вас есть неопределенный используемая переменная, она все равно вызовет ошибку, которую пользователи должны будут решить ». Эта ошибка является одной из тех, которые остановят пользователя. – Leito

1

Самый лучший вариант, я придумал до сих пор это:

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

Это не совсем «если существует», но это дает пользователям вашей роли тот же результат. Создайте несколько переменных внутри вашей роли и пустой файл по умолчанию. Фильтры Jinja «default» и «lookup» заботятся о возврате в пустой файл, если переменная не была установлена.

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

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

Это ТОЛЬКО работает для Ansible v1.9 и ниже. Ansible v2.0 и up должны использовать 'when: include_file_variable defined', предложенный @olluch –

+0

Спасибо! Я использовал '{{playbook_dir}}' в своем реальном коде, я просто оставил его из примера для простоты. – Leito

2

Я мог бы провести здесь время с положениями обработок ошибок 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 добавил, чтобы избежать хост получать исключены из дальнейших задач, если файл не существует.

+0

Это замечательный способ сделать это. Благодарю. Я использовал test -d для проверки каталогов, а позже понял значение флага fail_when. Еще раз спасибо – minocha

5

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

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

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

+0

Спасибо, похоже, что когда будет работать без опций 'optional_file.stat.exists '. Я все еще пытаюсь определить, что такое изменение. – Leito

19

with_first_found cond itional может выполнить это без 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 
+0

Попытка этого и я вижу это: ОШИБКА! 'with_first_found' не является допустимым атрибутом для PlaybookInclude –

+0

У меня был оператор 'include' как задача не на уровне игровой панели.Он работает таким образом как задача. Включенный файл содержит только задачи. Если вам нужно включить отдельные хост-ориентированные обучающие программы, вам придется ставить файл локально, а затем использовать этот результат в качестве условного. –

1

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

- 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 не существует, и схема игры выполняется (как сборник пьес, то есть она начинается с hosts: линии и т.д.)

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

0

Там также возможность использовать фильтр jinja2 для этого:

- set_fact: optional_file="/home/user/optional/file.yml" 

- include: .... 
    when: optional_file|exists 
Смежные вопросы