web-dev-qa-db-fra.com

Ansible: insérer une ligne s'il n'existe pas

J'essaie d'insérer une ligne dans un fichier de propriétés en utilisant ansible. Je veux ajouter une propriété si elle n'existe pas, mais pas la remplacer si une telle propriété existe déjà dans le fichier.

J'ajoute à mon rôle ansible

- name: add couchbase Host to properties
  lineinfile: dest=/database.properties regexp="^couchbase.Host"  line="couchbase.Host=127.0.0.1"

Mais cela remplace la valeur de la propriété à 127.0.0.1 si elle existe déjà dans le fichier.

Qu'est-ce que je fais mal?

22
Pavel Bernshtam

Le module lineinfile fait ce qu'il est censé faire: il s'assure que la ligne définie dans line est présente dans le fichier et la ligne est identifiée par votre regexp. Donc, quelle que soit la valeur de votre paramètre, il sera remplacé par votre nouveau line.

Si vous ne voulez pas remplacer la ligne, vous devez d'abord tester le contenu, puis appliquer cette condition au module lineinfile. Il n'y a pas de module pour tester le contenu d'un fichier, vous devez donc probablement exécuter grep avec une commande Shell et vérifier le .stdout pour le contenu. Quelque chose comme ça (non testé):

- name: Test for line
  Shell: grep "^couchbase.Host" /database.properties
  register: test_grep

Et puis appliquez la condition à votre tâche lineinfile:

- name: add couchbase Host to properties
  lineinfile:
    dest: /database.properties
    line: couchbase.Host=127.0.0.1
  when: test_grep.stdout != ""

Le regexp peut alors être supprimé car vous vous êtes déjà assuré que la ligne n'existe pas pour qu'elle ne corresponde jamais.

Mais peut-être que vous faites les choses à l'envers. D'où vient cette ligne dans le fichier? Lorsque vous gérez votre système avec Ansible, aucun autre mécanisme ne devrait interférer avec les mêmes fichiers de configuration. Vous pouvez peut-être contourner ce problème en ajoutant une valeur default à votre rôle?

26
udondan

C'est la seule façon dont j'ai pu faire fonctionner cela.

- name: checking for Host
  Shell: cat /database.properties | grep couchbase.Host | wc -l
  register: test_grep

- debug: msg="{{test_grep.stdout}}"

- name: adding license server
  lineinfile: dest=/database.properties line="couchbase.Host=127.0.0.1"
  when: test_grep.stdout == "0"
6
kmjackson788

Par un long chemin des "Essais et erreurs" j'arrive à ceci:

- name: check existence of line in the target file
  command: grep -Fxq "ip addr add {{ item }}/32 dev lo label lo:{{ app | default('app') }}" /etc/rc.local
  changed_when: false
  failed_when: false
  register: ip_test
  with_items:
    - "{{ list_of_ips }}"

- name: add autostart command
  lineinfile: dest=/etc/rc.local 
              line="ip addr add {{ item.item }}/32 dev lo label lo:{{ app | default('app') }}"
              insertbefore="exit 0"
              state=present
  when: item.rc == 1
  with_items:
    - "{{ ip_test.results }}"
3
user2658174

Même idée que celle présentée ici: https://stackoverflow.com/a/40890850/7231194

Les étapes sont les suivantes:

  • Essayez de remplacer la ligne.
  • Si remplacer le mod le changer, restaurer
  • Si remplacer le mod ne change pas, ajoutez la ligne

Exemple

# Vars
- name: Set parameters
  set_fact:
    ipAddress    : "127.0.0.1"
    lineSearched : "couchbase.Host={{ ipAddress }}"
    lineModified : "couchbase.Host={{ ipAddress }} hello"

# Tasks
- name: Try to replace the line
  replace:
    dest    : /dir/file
    replace : '{{ lineModified }} '
    regexp  : '{{ lineSearched }}$'
    backup  : yes
 register  : checkIfLineIsHere

# If the line not is here, I add it
- name: Add line
  lineinfile:
  state   : present
  dest    : /dir/file
  line    : '{{ lineSearched }}'
  regexp  : ''
  insertafter: EOF
when: checkIfLineIsHere.changed == false

# If the line is here, I still want this line in the file, Then restore it
- name: Restore the searched line.
  lineinfile:
    state   : present
    dest    : /dir/file
    line    : '{{ lineSearched }}'
    regexp  : '{{ lineModified }}$'
  when: checkIfLineIsHere.changed
1
Je.Go

Ok, voici ma solution naïve ... probablement pas une Ansible multiplateforme et native (je viens de commencer à utiliser cet outil et je l'apprends toujours), mais certainement plus courte:

- name: Update /path/to/some/file
  Shell: grep -q 'regex' /path/to/some/file && echo exists || echo 'text-to-append' >> /path/to/some/file
  register: result
  changed_when: result.stdout.find('exists') == -1
0
zaufi