Использование тильды в инструкциях ansible «when» для построения имен файлов из переменных

#ansible #ansible-facts

#ansible #ansible-факты

Вопрос:

Поведение ~ в операторах ansible «when» вызывает недоумение. Например, если LIB является фактом, установленным set_fact , со значением «lib64», я бы ожидал, что следующее утверждение будет истинным, если существует / usr / lib64 /cernlib /2006, и ложным в противном случае:

   when: '"/usr/" ~ LIB ~ "/cernlib/2006" is exists'
  

Однако я нахожу, что условие всегда истинно.

Условное выражение ведет себя так, как ожидалось, если я опущу ссылку на LIB и просто напишу:

   when: '"/usr/lib64/cernlib/2006" is exists'
  

Я легко могу представить опечатку, которая приведет к тому, что «когда» выдаст мне результат «false», но я озадачен тем фактом, что это всегда дает мне «true».

Я просто делаю что-то не так?

Ответ №1:

Тестовый синтаксис гласит:

Синтаксис для использования теста jinja следующий:

переменная — это test_name

 - set_fact:
    my_path: "/scratch/{{ LIB }}/cernlib/2006"
- debug:
    msg: "{{ mypath }} exists"
  when: my_path is exists
  

1) Использование строки вместо переменной приводит к ошибке.

 - debug:
    msg: "/scratch/test-83.yml exists"
  when: /scratch/test-83.yml is exists
  

Шоу:

фатальный: [localhost]: СБОЙ! => {«Сообщение об ошибке»: «Не удалось выполнить условную проверку ‘/scratch/test-83.yml is exists’. Ошибка была: ошибка шаблона при создании строки шаблона: неожиданный ‘/’.

2) Заключение строки в кавычки не помогает

 - debug:
    msg: "/scratch/test-83.yml exists"
  when: "/scratch/test-83.yml" is exists
  

Шоу:

 ERROR! Syntax Error while loading YAML.
  did not find expected key
...
The offending line appears to be:

    msg: "/scratch/test-83.yml exists"
  when: "/scratch/test-83.yml" is exists
                               ^ here
This one looks easy to fix.  It seems that there is a value started
with a quote, and the YAML parser is expecting to see the line ended
with the same kind of quote.  For instance:
  when: "ok" in result.stdout
Could be written as:
  when: '"ok" in result.stdout'
Or equivalently:
   when: "'ok' in result.stdout"
  

3) Работает только эта конкретная комбинация одинарных и двойных кавычек

 - debug:
    msg: "/scratch/test-83.yml exists"
  when: "'/scratch/test-83.yml' is exists"
  

Проверено с

 > ansible --version
ansible 2.7.9
python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]
  

Комментарии:

1. Достаточно справедливо. Но мне любопытно: нет ли способа правильно выполнить конкатенацию, которую я пытался? Кроме того, почему «when» возвращает «true», когда я пытаюсь это сделать, а не «false»?

2. Синтаксис «переменная — это test_name» является обязательным. Я обновил ответ. Вероятно, «when» возвращает любое ненулевое значение как «true».

3. > Вероятно, «when» возвращает любое ненулевое значение как «true». Но если я напишу «when» без переменных, например: когда: «‘/ scratch /lib64 /cernlib /2006’ is exists», тест будет работать так, как ожидалось. (Это верно, если путь существует, но false в противном случае.) Может быть, это непреднамеренный остаток от какой-либо более ранней версии ansible?

4. ДА. Эта конкретная комбинация работает. Я обновил ответ.

5. Да, это соответствует тому, что я нашел (это также работает, если вы поменяете местами одинарные и двойные кавычки). Но если я использую тильду в любом месте теста, либо как я сделал выше, либо даже просто как ‘/ usr’ ~», тест всегда возвращает «true», независимо от того, существует ли путь на самом деле.