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