Qual è l'equivalente di Puppet "a meno che" in Ansible?


9

Background: in Puppet è possibile eseguire un comando a meno che non sia già stato eseguito:

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

Obiettivo: eseguire un comando a meno che non sia già stato eseguito in Ansible

metodi

compiti / main.yml

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

risultati

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

Discussione

Google ha unless ansiblemostrato questo documento suwhen . Sulla base di tale documentazione, è whenstata aggiunta una dichiarazione:

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

l'esecuzione del codice ha comportato:

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. Prima di tutto, immagina che abbia whenavuto successo, quindi il comando non verrà eseguito e quindi sembrerà più simile onlyifa Puppet .
  2. In secondo luogo, se il momento in cui andrebbe a buon fine dovrebbe essere usato un segno di escalation per simulare un a meno?
  3. Uso diregister . Cosa succede se quel file viene perso o il vhost è stato rimosso ad esempio da un essere umano? Puppet unlessesegue sempre i comandi in modo che sia chiaro se il comando deve essere eseguito.

Risposte:


9

Penso che quello che stai cercando di fare sia questo:

- 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"

Ri: # 3 registernon crea un file. Se stai acquisendo l'output di rabbitmqctl list_vhostsvia register, i contenuti saranno validi quanto lo stato corrente del sistema.


3

Il problema è la linea when: rabbitmqctl list_vhosts | grep sensu. Non è possibile utilizzare bash qui.

È necessario inserire rabbitmqctl list_vhosts | grep sensuun'attività separata e registrare il risultato per utilizzarlo nella clausola when. Puoi usare il notfiltro per ottenere unlessun comportamento simile.

Qualcosa del genere dovrebbe funzionare:

- 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

In Get rabbitmq vhosts.questo esempio verrà sempre eseguito. L' add vhost sensuunico se il sensu stringa non è registrato rabbitmq_vhosts.

Consultare la documentazione su condizionali e filtri jinja per ulteriori informazioni.


Il problema persiste:fatal: [IP]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl", "add_vhost", "/sensu"], "delta": "0:00:00.198681", "end": "2016-07-29 13:43:00.870193", "failed": true, "rc": 2, "start": "2016-07-29 13:43:00.671512", "stderr": "Error: vhost_already_exists: /sensu", "stdout": "Creating vhost \"/sensu\" ...", "stdout_lines": ["Creating vhost \"/sensu\" ..."], "warnings": []}
030,

hm, probabilmente è colpa mia. Immagino che mancasse una .stdoutmodifica della mia risposta.
Henrik Pingel,

0

L' whenopzione è l'unica cosa che Ansible ha riguardo alle condizioni. Ma non è possibile definire direttamente un comando lì. whensi aspetta un'espressione di Jinja e inoltre viene valutato sull'host di controllo Ansible. Quindi devi prima eseguire un'attività per recuperare il risultato e registrarlo.

- 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è un array di tutte le righe restituite dall'attività shell. Quindi puoi contare il numero di voci ed eseguire l'attività solo quando sono stati restituiti 0 articoli


2
se il vhost / sensu non esiste, risulta:fatal: [IP]: FAILED! => {"changed": true, "cmd": "rabbitmqctl list_vhosts | grep sensu", "delta": "0:00:00.198769", "end": "2016-07-29 13:45:59.069981", "failed": true, "rc": 1, "start": "2016-07-29 13:45:58.871212", "stderr": "", "stdout": "", "stdout_lines": [], "warnings": []}
030
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.