regex Ansible:在GRUB命令行中插入单词

7kjnsjlb  于 2022-12-05  发布在  其他
关注(0)|答案(5)|浏览(112)

我想使用Ansible的lineinfile或replace模块,以便将单词splash添加到GRUB中的cmdline。
它应该适用于以下所有示例:
例一:

  • 之前:GRUB_CMDLINE_DEFAULT=""
  • 之后:GRUB_CMDLINE_DEFAULT="splash"

例二:

  • 之前:GRUB_CMDLINE_DEFAULT="quiet"
  • 之后:GRUB_CMDLINE_DEFAULT="quiet splash"

例三:

  • 之前:GRUB_CMDLINE_DEFAULT="quiet nomodeset"
  • 之后:GRUB_CMDLINE_DEFAULT="quiet nomodeset splash"

帖子Ansible: insert a single word on an existing line in a file很好地解释了如何在没有引号的情况下完成这个操作。但是,我无法让它在引号中插入这个词。
要将单词splash添加到所示的cmdline,Ansible角色或行动手册中需要什么条目?

hec6srdp

hec6srdp1#

您可以在没有shell输出的情况下使用2个lineinfiles模块完成此操作。
在示例中,您要搜索splash

- name: check if splash is configured in the boot command
  lineinfile:
    backup: true
    path: /etc/default/grub
    regexp: '^GRUB_CMDLINE_LINUX=".*splash'
    state: absent
  check_mode: true
  register: grub_cmdline_check
  changed_when: false

- name: insert splash if missing
  lineinfile:
    backrefs: true
    path: /etc/default/grub
    regexp: "^(GRUB_CMDLINE_LINUX=\".*)\"$"
    line: '\1 splash"'
  when: grub_cmdline_check.found == 0
  notify: update grub

诀窍是如果我们能在某处找到splash,就尝试删除该行,但只检查check_mode: true。如果找到了项(found〉0),那么我们不需要更新该行。如果没有找到,这意味着我们需要插入它。我们将它与backrefs一起附加在末尾。

iih3973s

iih3973s2#

可能的解决方案是定义两个条目,如下所示:

- name: "Checking GRUB cmdline"
  shell: "grep 'GRUB_CMDLINE_LINUX_DEFAULT=.*splash.*' /etc/default/grub"
  register: grub_cfg_grep
  changed_when: false
  failed_when: false

- name: "Configuring GRUB cmdline"
  replace:
    path: '/etc/default/grub'
    regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((\w.?)*)"$'
    replace: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 splash"'
  when: '"splash" not in grub_cfg_grep'

说明:我们首先使用grep检查所需行中是否存在splash关键字。由于grep在未找到字符串时给出负返回代码,因此我们使用failed_when: false隐藏错误。grep的输出保存到grub_cfg_grep变量中。
接下来,我们将replace模块绑定到grep的标准输出中包含关键字splash的条件,正则表达式将旧的内容放在引号中,并在其后添加splash关键字。
注意:如果在执行前为空字符串,则结果为" splash"(前面有一个空格),但它仍然是一个有效的cmdline。

avwztpqn

avwztpqn3#

受Adam答案的启发,我使用下面的答案来启用IOMMU:

- name: Enable IOMMU
  ansible.builtin.lineinfile:
    path: /etc/default/grub
    regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((:?(?!intel_iommu=on).)*?)"$'
    line: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 intel_iommu=on"'
    backup: true
    backrefs: true
  notify: update-grub

请注意,我必须将backrefs设置为true,以便\1引用工作,否则捕获的组不会被替换。
幂等性也能很好地工作。
编辑:请注意,此代码片段仅适用于英特尔CPU,可能需要更新以适应您的平台。

f45qwnt8

f45qwnt84#

难点在于替换模块页面中的这一行:“通过确保相同的模式永远不会匹配所做的任何替换,由用户来维护幂等性。”https://docs.ansible.com/ansible/latest/modules/replace_module.html#id4插入项目很容易,但实际上使其幂等相当棘手,因此每次运行任务时目标文件不会增长。
我找到了一种方法,用替换模块一次完成。你应该能够适应这个。我的任务检查GRUB_CMDLINE_LINUX_DEFAULT行中是否有“vt.default_red”,如果没有,就插入一些颜色代码。
我的方法是复制并粘贴各种接近那里的例子到regex测试网站上,直到它工作为止。我仍然不知道结果,但它在我的https://www.regextester.com/测试中工作,在我的剧本中工作。
我遇到的一个问题是Ansible的regex实现显然不支持条件语句,这给了我一段时间奇怪的错误。

- name: colours | configured grub command
  replace:
    path: /etc/default/grub
    regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((:?(?!vt\.default_red).)*?)"$'
    replace: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 vt.default_red=0xee,..."'

正则表达式匹配开头的文字字符串(“GRUB_CMDLINE_LINUX_DEFAULT=”和一个双引号)和结尾的双引号。

(                            - open capture group #1 (creates backref #1)
 (:?                         - open a non-capturing group (not sure what the question mark is here)
    (?!                      - negative lookahead (ie. don't match if the following string comes next)
       vt\.default_red       - the string to look for, literal dot is escaped
                      )      - close negative lookahead
                       .)    - match a single char (why?) and close the non-capturing group
                         *   - try to match the non-capturing group zero or more times
                          ?  - ... lazily (ie. get the smallest possible match)
                           ) - close capture group #1
ipakzgxi

ipakzgxi5#

What about doing this in Ansible, use perl to address your need.

- name: Change items in the file
  ansible.builtin.command:
    command: perl -i pe 's/DEFAULT="/DEFAULT="splash"/' 

Another way of looking at it. This is an old conversation, but it is still relevant.

相关问题