【问题标题】:Ansible lineinfile duplication using insertafter使用 insertafter 进行 Ansible lineinfile 复制
【发布时间】:2018-12-27 04:10:48
【问题描述】:

我正在尝试使用 ansibles lineinfile 在我的 /etc/hosts 文件中添加一个条目。我希望逻辑是如果它找到条目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

其中domainmysite.local

我查看了this 的答案,但我很确定我不能使用backrefs,因为文档状态;

这个标志稍微改变了模块的操作; insertbefore 和 insertafter 将被忽略,如果正则表达式在文件中的任何位置都不匹配,则文件将保持不变。

我试过了;

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

也没有运气

【问题讨论】:

    标签: regex ansible jinja2


    【解决方案1】:

    似乎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'
    

    【讨论】:

      【解决方案2】:

      根据this link,lineinfile 扫描文件并一次应用正则表达式一行,这意味着您不能使用查看整个文件的正则表达式。我对 lineinfile 工具不熟悉,但是如果您可以使用上面链接中使用的“替换”工具,那么您可以根据需要使用以下 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. Case 1: 127.0.1.1 和 127.0.0.1 不存在,所以在末尾插入
      2. Case 2: 127.0.0.1 存在于不同的主机,所以替换条目
      3. Case 3: 127.0.1.1 存在所以插入它之后

      第二种情况是通过避免匹配“127.0.0.1”的条目(如果已经存在)来解决幂等性问题。

      【讨论】:

        【解决方案3】:

        doc 说:

        insertafter: ... 如果正则表达式同时传递给 regexp 和 insertafter,则只有在找不到 regexp 的匹配项时才会使用 insertafter。

        任务中的正则表达式扩展为

        regex: ^mysite\.local
        

        找不到此正则表达式,因为没有以“mysite.local”开头的行。因此 insertafter 得到尊重,并且在 127.0.1.1 之后插入“行”。

        【讨论】:

        • 所以,简而言之应该是:regex: "{{ domain|regex_escape() }}",对吧?
        • @Poul Bak:你测试过吗?
        • 不,我刚刚得出结论,这就是你的意思,不是吗?
        • 我明白为什么会发生插入(以及因此重复),但我不明白如何在我的情况下解决它。我以为我只需要匹配部分行而不是整个内容?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多