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?
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?
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"
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 }}"
Même idée que celle présentée ici: https://stackoverflow.com/a/40890850/7231194
Les étapes sont les suivantes:
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
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