Expend the text in the end of a special line in a file

Hi Folks,
I am new here, can someone give me a hand to show me how to add the text/items to the special place in the a file?
Here is the line what I have from /etc/default/grub now:
//////////////////
GRUB_CMDLINE_LINUX=“nofb quiet splash=quiet crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/OS-swap rd.lvm.lv=OS/root rd.lvm.lv=OS/swap rd.lvm.lv=OS/usr audit=1 audit_backlog_limit=8129”
/////////////////
After the ansible code run, I need insert transparent_hugepages=never into the line as following
//////////////////
GRUB_CMDLINE_LINUX=“nofb quiet splash=quiet crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/OS-swap rd.lvm.lv=OS/root rd.lvm.lv=OS/swap rd.lvm.lv=OS/usr audit=1 audit_backlog_limit=8129 transparent_hugepages=never”
//////////////////

Any help appreciated.

Hi,
I’d probably use the lineinfile module with a regexp.


  • name: Disable the transparent hugepages for RHEL9 servers
    hosts: all
    become: true

    tasks:

    • name: grub - disable transparent hugepage
      lineinfile:
      path: /etc/default/grub
      regexp: ‘^audit_backlog_limit=8192 (.*)’
      line: ‘GRUB_CMDLINE_LINE = \1 audit_backlog_limit=8192 transparent_hugepages=never"’
      backrefs: yes
      state: present

And the code is running, but no update done for the grub file.

Sorry, regexp is completely wrong,
this: ^ means beginning of the line, you don’t have any line beginning with audit_backlog_limit…

try this

        regexp: "^(.+audit_backlog_limit=8129)"
        line: \1 transparent_hugepages=never"
1 Like

Since /etc/default/grub is a ini / conf file I’d suggest using the community.general.ini_file module to edit it.

Note that the two Ansible ini file filters can’t be used since they don’t support ini files without section headers, however the community.general.jc filter with the ini parser can be used to read ini files without section headers.

As far as I understand that fits only if GRUB_CMDLINE_LINE value post installation is the same for every machine, but since you could want to install a particular system in a different way resulting in different GRUB_CMD_LINE value, the risk is that you override system specific settings.
Unless there is a way (that tbh I can’t see) with the module you mention to append the string transparent_hugepages=never to the option, instead of overwriting the whole value.

Read the existing value, append what is needed and then write the change is an approach that should work, something like this?

- name: Slurp /etc/default/grub
  ansible.builtin.slurp:
    src: /etc/default/grub
  register: grub_b64encoded

- name: Decode the base64 encoded version of /etc/default/grub and set a variable
  ansible.builtin.set_fact:
    grub_contents: "{{ grub_b64encoded['content'] | b64decode | community.general.jc('ini') }}"

- name: Debug grub_contents.GRUB_CMDLINE_LINUX
  ansible.builtin.debug:
    var: grub_contents.GRUB_CMDLINE_LINUX

- name: Update /etc/default/grub
  community.general.ini_file:
    path: /etc/default/grub
    option: GRUB_CMDLINE_LINUX
    value: "{{ grub_contents.GRUB_CMDLINE_LINUX }} transparent_hugepages=never"
    mode: "0644"
    backup: true
  when: ( "transparent_hugepages=never" not in grub_contents.GRUB_CMDLINE_LINUX | split(' ') )

The above could be improved / made more flexible by doing things like using a list of value pairs to add if not present rather than hard coding the values needed.

1 Like

Well yes, that would involve also checking if the value_to_append is already present.
If there is a module that solves a problem with just one task, I go for it.

Sounds like a bit complicated when you can just

    - name: grub
      ansible.builtin.lineinfile:
        path: /etc/default/grub
        regexp: ^(.+audit_backlog_limit=8129)"$
        line: '\1 transparent_hugepages=never"'
        backrefs: true
        state: present

But I appreciate we can have slightly different approaches to achieve the same result. I just tend to simplify if I can.

1 Like

Thanks you guys reply, I will try the solution you guys suggested and update you.

What I try to implement is we have some special RHEL9 servers need to disable Transparent Hugepages due to the application requirement.

I try to write an ansible playbook to implement this so others if they want to configure it, just run the playbook and get the thing done. There will be the cli to run after the /etc/default/grub updated.

Yes, I agree with you.
As operation team, the simpler, the better.

My suggestion will work if the existing GRUB_CMDLINE_LINE has items in a different order, it doesn’t depend on audit_backlog_limit=8129 appearing at the end of the line, this might, or might not matter to you :person_shrugging: (it doesn’t matter to Grub!).

@chris Yes, agree with your comments.

Just try to do as simpler as possible.

@matteoclc BTW, the code you suggested need to be updated; otherwise, after we run the code, the output will be: 1 transparent_hugepages=never" instead of what I want: GRUB_CMDLINE_LINUX=“nofb quiet splash=quiet crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/OS-swap rd.lvm.lv=OS/root rd.lvm.lv=OS/swap rd.lvm.lv=OS/usr audit=1 audit_backlog_limit=8192 transparent_bugepage=never”.

Strange, doesn’t happen on my system, try omitting the quotes:

    - name: grub
      ansible.builtin.lineinfile:
        path: /etc/default/grub
        regexp: ^(.+audit_backlog_limit=8129)"$
        line: \1 transparent_hugepages=never"
        backrefs: true
        state: present```

@matteoclc It works now. it is the quotes annoyed the playbook.
Thanks a lot for the help!!!

1 Like

@chris I do not have the community.general.ini_file loaded in my ansible server, will see if I have the time to load the module and test your solution.
Thanks for your guide

1 Like

You might have a old version of the community.general collection that doesn’t have it?

You would also need to have jc installed on the Ansible controller to use the community.general.jc filter.

@chris Thanks a lot! Will check it out.