Qual é o equivalente de Puppet 'a menos que' em Ansible?

8

Background: no Puppet, é possível executar um comando a menos que já tenha sido executado:

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',
}

Objetivo: executar um comando, a menos que já tenha sido executado no Ansible

Métodos

tarefas / main.yml

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu

Resultados

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": []}

Discussão

pesquisando unless ansible mostrou este documento sobre when . Com base nessa documentação, uma instrução when foi adicionada:

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: rabbitmqctl list_vhosts | grep sensu

a execução do código resultou em:

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"}
  1. Antes de tudo, imagine que when foi bem-sucedido, então o comando não será executado e, em seguida, será mais parecido com onlyif no Puppet .
  2. Em segundo lugar, se o quando for bem-sucedido, uma marcação de escala deve ser usada para simular, a menos que?
  3. Uso de register . E se esse arquivo for perdido ou o vhost for removido por, por exemplo, um humano? O unless do Puppet sempre executa os comandos para que fique claro se o comando precisa ser executado.
por 030 29.07.2016 / 15:15

3 respostas

8

Acho que o que você está procurando é isso:

- 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 não cria um arquivo. Se você estiver capturando a saída de rabbitmqctl list_vhosts via register , o conteúdo será tão válido quanto o estado atual do sistema.

    
por 29.07.2016 / 15:31
3

O problema é a linha when: rabbitmqctl list_vhosts | grep sensu . Não é possível usar o bash aqui.

Você precisa colocar o rabbitmqctl list_vhosts | grep sensu em uma tarefa separada e registrar o resultado para usá-lo na cláusula when. Você pode usar o filtro not para obter o comportamento semelhante a unless .

Algo como isso deve funcionar:

- 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

O Get rabbitmq vhosts. neste exemplo será sempre executado. O add vhost sensu somente se a string sensu não estiver no rabbitmq_vhosts registrado.

Consulte a documentação das condicionais e filtros jinja para mais informações.

    
por 29.07.2016 / 15:31
1

A opção when é a única coisa que a Ansible tem em relação às condições. Mas você não pode definir diretamente um comando lá. when espera uma expressão Jinja e, além disso, é avaliado no host de controle Ansible. Então, primeiro você precisa executar uma tarefa para buscar o resultado e registrá-lo.

- 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 é uma matriz de todas as linhas que a tarefa do shell retornou. Então você pode contar o número de entradas e só executar sua tarefa quando 0 itens foram retornados

    
por 29.07.2016 / 15:30

Tags