Задний план: в Puppet можно выполнить команду если только он уже выполнен:
exec { '/bin/echo root >> /usr/lib/cron/cron.allow': path => '/usr/bin:/usr/sbin:/bin', unless => 'grep root /usr/lib/cron/cron.allow 2>/dev/null', }
Цель: для выполнения команды, если она еще не была запущена в Ansible
Методы
задачи / main.yml
- name: add vhost sensu
command: rabbitmqctl add_vhost /sensu
Полученные результаты
TASK [ansible-rabbitmq : add vhost sensu] **************************************
fatal: [111.222.333.444]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl",
"add_vhost", "/sensu"], "delta": "0:00:00.210140", "end":
"2016-07-29 12:55:19.384455", "failed": true, "rc": 2, "start":
"2016-07-29 12:55:19.174315", "stderr": "Error: vhost_already_exists: /sensu",
"stdout": "Creating vhost \"/sensu\" ...", "stdout_lines":
["Creating vhost \"/sensu\" ..."], "warnings": []}
Обсуждение
Поиск в Google unless ansible
показал этот документ о when
. На основании этой документации when
заявление было добавлено:
- name: add vhost sensu
command: rabbitmqctl add_vhost /sensu
when: rabbitmqctl list_vhosts | grep sensu
запуск кода привел к:
fatal: [192.168.0.9]: FAILED! => {"failed": true, "msg": "The conditional
check 'rabbitmqctl list_vhosts | grep sensu' failed. The error was: template
error while templating string: expected token 'end of statement block', got
'list_vhosts'. String: {% if rabbitmqctl list_vhosts | grep sensu %} True {%
else %} False {% endif %}\n\nThe error appears to have been in '/etc/ansible
/roles/ansible-rabbitmq/tasks/main.yml': line 10, column 3, but may\nbe
elsewhere in the file depending on the exact syntax problem.\n\nThe
offending line appears to be:\n\n\n- name: add vhost sensu\n ^ here\n"}
when
был успешным, то команда не будет запущена, и тогда это больше похоже на onlyif
в кукольном.register
. Что, если этот файл потерян или виртуальный хост был удален, например, человеком? Куклы unless
всегда выполняет команды, чтобы было ясно, нужно ли выполнить команду.Я думаю, что вы смотрите вот что:
- name: get vhosts
command: rabbitmqctl list_vhosts
register: vhosts
changed_when: false
- name: add vhost sensu
command: rabbitmqctl add_vhost /sensu
when: "'/sensu' not in vhosts.stdout"
Re: # 3 register
не создает файл. Если вы захватываете вывод rabbitmqctl list_vhosts
через register
, содержимое будет таким же, как и текущее состояние системы.
Проблема в линии when: rabbitmqctl list_vhosts | grep sensu
. Здесь невозможно использовать bash.
Вам нужно поставить rabbitmqctl list_vhosts | grep sensu
в отдельной задаче и зарегистрируйте результат, чтобы использовать его в предложении when. Ты можешь использовать not
фильтр, чтобы получить unless
нравится поведение.
Примерно так должно работать:
- name: Get rabbitmq vhosts.
command: rabbitmqctl list_vhosts | grep sensu
register: rabbitmq_vhosts
- name: add vhost sensu
command: rabbitmqctl add_vhost /sensu
when: not 'sensu' in rabbitmq_vhosts.stdout
В Get rabbitmq vhosts.
в этом примере всегда будет выполняться. В add vhost sensu
только если строка sensu отсутствует в зарегистрированном rabbitmq_vhosts
.
См. Документацию по условные и фильтры jinja Чтобы получить больше информации.
В when
вариант - единственное, что есть у Ansible в отношении условий. Но вы не можете напрямую определить команду там. when
ожидает выражения Jinja и, кроме того, оценивается на хосте управления Ansible. Итак, сначала вам нужно запустить задачу, чтобы получить результат и зарегистрировать его.
- shell: rabbitmqctl list_vhosts | grep sensu
register: sensu_vhosts
- name: add vhost sensu
command: rabbitmqctl add_vhost /sensu
when: sensu_vhosts.stdout_lines < 1
stdout_lines
представляет собой массив всех строк, возвращенных задачей оболочки. Таким образом, вы можете подсчитать количество записей и запустить задачу только тогда, когда было возвращено 0 элементов.