Дублирование линейного файла с использованием inserttafter - PullRequest
0 голосов
/ 18 ноября 2018

Я пытаюсь добавить запись в мой /etc/hosts файл, используя ansibles lineinfile. Я хочу, чтобы логика была такой, если она находит запись 127.0.0.1 mysite.local и ничего не делает, иначе вставляет ее после строки 127.0.1.1

127.0.0.1   localhost
127.0.1.1   mypc
127.0.0.1      mysite.local

У меня вставка после обработки детали, но, похоже, что в процессе поиска регулярных выражений не удается найти существующую запись, поэтому я продолжаю получать дубликаты вставки 127.0.0.1 mysite.local

В документах сказано:

При изменении строки регулярное выражение обычно должно соответствовать как начальному состоянию строки, так и ее состоянию после замены на строку, чтобы обеспечить идемпотентность.

Но я не уверен, как это относится к моему регулярному выражению. В настоящее время моя игра является;

- name: Add the site to hosts
  lineinfile:
    path: /etc/hosts
    # Escape special chars
    regex: "^{{ domain|regex_escape() }}"
    line: "127.0.0.1      {{ domain }}"
    insertafter: '127\.0\.1\.1'
    firstmatch: yes
  become: yes

, где domain равно mysite.local.

Я смотрел на этот ответ, но я почти уверен, что не могу использовать backrefs, так как состояние документа;

Этот флаг немного меняет работу модуля; insertbefore и inserttafter будут игнорироваться, и если регулярное выражение не совпадает нигде в файле, файл будет оставлен без изменений.

Я пытался;

regex: '127\.0\.0\.1\s+?{{ domain|regex_escape() }}'

Без удачи либо

Ответы [ 3 ]

0 голосов
/ 26 декабря 2018

Согласно этой ссылке , lineinfile сканирует файл и применяет регулярное выражение по одной строке за раз, что означает, что вы не можете использовать регулярное выражение, просматривающее весь файл. Я не знаком с инструментом lineinfile, но если вы можете использовать инструмент "replace", использованный в приведенной выше ссылке, тогда вы можете использовать следующее регулярное выражение Python для соответствия, как вам нужно:

\A((?:(?!127\.0\.0\.1\s)[\s\S])*?)(?:\Z|127\.0\.0\.1\s+(?!{{ domain|regex_escape() }})\S+\n|(127\.0\.1\.1\s+\S+(?![\s\S]*\n127\.0\.0\.1\s)\n))

С заменой: "\ 1 \ 2127.0.0.1 {{domain}} \ n"

Группа без захвата обрабатывает три различных случая:

  1. Случай 1 : 127.0.1.1 и 127.0.0.1 не существуют, поэтому вставьте в конце
  2. Случай 2 : 127.0.0.1 существует с другим хостом, поэтому замените запись
  3. Случай 3 : 127.0.1.1 существует, поэтому вставьте после него

Это второй случай, когда рассматривается идемпотентность, избегая сопоставления записи для "127.0.0.1", если она уже существует.

0 голосов
/ 26 декабря 2018

Кажется, что firstmatch: yes ломал вещи.Это работает для меня со следующей задачей (я заменил пробел на вкладку для причудливого вида, но пробелы также работают):

  - name: Add the site to hosts
    lineinfile:
      path: /etc/hosts
      # Escape special chars
      regexp: "{{ domain|regex_escape() }}"
      line: "127.0.0.1{{ '\t' }}{{ domain }}"
      insertafter: '127\.0\.1\.1'
0 голосов
/ 18 ноября 2018

документ говорит:

inserttafter: ... Если регулярные выражения передаются как в regexp, так и в inserttafter, inserttafter учитывается только в том случае, если не найдено соответствия для регулярного выражения.

Регулярное выражение в задаче расширяется до

regex: ^mysite\.local

Это регулярное выражение не найдено, потому что нет строки, начинающейся с "mysite.local". Следовательно, inserttafter учитывается, и после строки 127.0.1.1 .

вставляется "строка".
...