Ansible: вставить строку, если она не существует
Я пытаюсь вставить строку в файл свойств с помощью ansible. Я хочу добавить некоторое свойство, если оно не существует, но не заменить его, если такое свойство уже существует в файле.
Я добавляю к своей роли ansible
- name: add couchbase host to properties
lineinfile: dest=/database.properties regexp="^couchbase.host" line="couchbase.host=127.0.0.1"
но это заменяет значение свойства обратно на 127.0.0.1, если он уже существует в файле.
что я делаю не так?
5 ответов
вы не делаете ничего плохого с lineinfile модуль. Он делает то, что должен. Он обеспечивает линию, определенную в line присутствует в файле и строке определяется как regexp. Поэтому независимо от того, какое значение ваша настройка уже имеет, она будет переопределена вашим новым line.
если вы не хотите, чтобы переопределить строки сначала нужно проверить содержимое, а затем применить это условие к lineinfile модуль. Я думаю, что нет модуля для тестирования содержимое файла, поэтому вам, вероятно, нужно запустить grep С shell команда и проверьте .stdout для содержания. Что-то вроде этого (непроверенных):
- name: Test for line
shell: grep "^couchbase.host" /database.properties
register: test_grep
а затем применить условие к lineinfile задачи:
- name: add couchbase host to properties
lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
when: test_grep.stdout != ""
на regexp затем можно удалить, так как вы уже убедились, что строка не существует, поэтому она никогда не будет совпадать.
но, может быть, вы делаете что-то задом наперед. Откуда взялась эта строка в файле? При управлении система с Ansible не должно быть никаких других механизмов, которые мешают тем же файлам конфигурации. Возможно, вы можете обойти это, добавив default значение для вашей роли?
это единственный способ заставить это работать.
- 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"
длинным путем "проб и ошибок" я прихожу к этому:
- 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 }}"
та же идея, что и здесь:https://stackoverflow.com/a/40890850/7231194
действия:
- попробуйте заменить строку.
- если заменить мод изменить его, восстановить
- если replace mod не меняется, добавьте строку
пример
# 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
хорошо, вот мое наивное решение... вероятно, не кросс-платформенный и родной Ansible (я только начал использовать этот инструмент и все еще изучаю его), но определенно короче:
- 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