lineinfile - append at end of line ?

10,355 views
Skip to first unread message

Alex Rodenberg

unread,
Sep 30, 2013, 10:17:35 AM9/30/13
to ansible...@googlegroups.com
can lineinfile append at the end of a line ?

I have a kernel line in my grub.conf i would like to append "pcie_aspm=off" to if it's not there.

To my understanding backrefs would possibly be able to do that ?

I don't wanna template up grub.conf just for that small addition, but do not want to replace the whole kernel line either as it might not be 100% the same on all my systems.

James Cammarata

unread,
Sep 30, 2013, 11:25:34 AM9/30/13
to ansible...@googlegroups.com
Yes, you should be able to do that by specifying EOF as the insertafter= argument.


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--

James Cammarata <jcamm...@ansibleworks.com>
Sr. Software Engineer, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Michael DeHaan

unread,
Sep 30, 2013, 3:32:48 PM9/30/13
to ansible...@googlegroups.com
James,

EOF is end of file, he wants to add to the end of the line.

The module is not that smart right now, at least according to docs.

--Michael


Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Philippe Eveque

unread,
Sep 30, 2013, 3:59:35 PM9/30/13
to ansible...@googlegroups.com
Yes this is possible with backrefs - aka capturing groups- and not just at the end of the line.
one possibility is to leverage negative lookahead regexp [1]
then one call to lineinfile is enough.
 
warning, the regexp can be quite complex
 
here is a simplified l example of a configuration file that has a line
starting with something like
OPTIONS="-a option1 -b another:option -x  -z athird.option"
 
the point is to check if -x is NOT there and add it as the first option (could have been added at the end by swapping -x and \\1)
 
 
  lineinfile: dest=${target_file}
              backrefs=True
              state=present
              regexp='^OPTIONS="(([^-]*(-(?!x).)+[^-]*)*)"'
              line='OPTIONS="-x \\1"'
 
works well since ansible 1.1
requires the line you have to match has a well specified format
in your case it is :
 
kernel <kernelpath> <options>
 
you are looking for options not being pcie_aspm=off
 
 
 
 
 
good luck


2013/9/30 Michael DeHaan <mic...@ansibleworks.com>

Kavin Kankeshwar

unread,
Sep 30, 2013, 4:23:01 PM9/30/13
to ansible...@googlegroups.com
Thanks for this example! , Lineinfile is very powerful, but documentation and regex does not explain it explicitly. Like how to use backrefs and more detailed examples for these would be great! (Like how to add stuff to end of line, start of the line, before/after the regex, replace line and EOF/BOF)

Regards,
--
Kavin.Kankeshwar

Michael DeHaan

unread,
Sep 30, 2013, 8:33:51 PM9/30/13
to ansible...@googlegroups.com
Docs are open source so we do take patches.

See the lineinfile source code for what builds the inline docs.


Alex Rodenberg

unread,
Oct 1, 2013, 10:20:01 AM10/1/13
to ansible...@googlegroups.com
Thanks, that confirmed what I feared :) strange regex options to do something somewhat simple.

I hope someone will be able to document this better in the future, or make a simpler way to do this. Then again I have no clue if anyone other than me would find this useful.
Until then I will stick to a sed command to not pull my already grey hair completely away :)

Philippe Eveque

unread,
Oct 1, 2013, 12:01:48 PM10/1/13
to ansible...@googlegroups.com
I understand the hair concern ... ;-)

Needed that in some of the playbooks we have.
More generally needed when in "remediation contexts" to insure other
changes made by sysadmin are not removed (after original deployment)

This is pure regex thing (python or sed or ...), not an ansible issue.
the lineinfile module doc already specified this is Python regexp

Agree that some well documented examples will help,
but it will be more about explaining regexp compexity than anything else


Phil


2013/10/1 Alex Rodenberg <al...@axlrod.dk>

Michael DeHaan

unread,
Oct 1, 2013, 12:05:28 PM10/1/13
to ansible...@googlegroups.com
I should say it's almost always better to just template the file unless you think the user is going to alter it.

In any event, I'll remind everyone the examples and documentation are open source.  The source to the module contains the docstring that gets rendered, so additional examples (as well as patches) are welcome, and easily added!

It's hard for me to tell what the best way to explain something to someone else is sometimes, so it's usually best for those who figure things out to submit something.  In some cases we may edit/polish things up a bit or have some comments or suggestions of things to add.

Thanks!


Philippe Eveque

unread,
Oct 2, 2013, 9:59:07 AM10/2/13
to ansible...@googlegroups.com
Agree with Michael on the template option
 
Regarding the request/question from Alex Rodenberg
Below is an example tested with ansible version 1.3.2 whith some hopefully understandable comments about the implementation
 
 
HTH
 
-- code extract ----

  # Regexp implementation note:

  #  - the line to match follows the following pattern:

  #     - <startofline>: matched by ^

  #     - A number of white spaces/tabs: matched by \s+

  #     - the "kernel" string: matched by kernel

  #     - A list of: <spaces|tab><string> -> this is all the options passed to the kernel

  #     - possible spaces and tabs at the end : matched by the latest \s*

  #     - the <end of line>: matched by $

  #  - the list of: <spaces|tab><string1> described above

  #    e.g:  /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/mapper/VolGroup00-root_vol … rd_LVM_LV=VolGroup00/root_vol SYSFONT=latarcyrheb-sun16 rd_NO_DM

  #    is matched by: (\s+(?!pcie_aspm=off)[\w=/\-\.]+)*

  #    The (?!pcie_aspm=off) is to direct the regexp engine to check that the string 'pcie_aspm=off'

is not present

  #       anywhere in the in the <string1> part. This is called negative lookahead.

  #       This is just a check, no characters are "consumed". The following [\w=/\-\.]+

  #       is ther to consume aka match any strings made of alphanumeric characters,the '/', the '-', the '.' 

  #  - if the 'pcie_aspm=off' string is present, there is no match

  #  - the capturing group 1 referred as to \1 in the line= statement

  #    will capture the whole line but the trailing <withe spaces> and <end of line>

 

   

  - name: Activate a lacking kernel option 'pcie_aspm=off' in {{ targetgrub }}

    lineinfile: dest={{ targetgrub }}

              backup=True

              backrefs=True

              state=present

              regexp='(^\s+kernel(\s+(?!pcie_aspm=off)[\w=/\-\.]+)*)\s*$'

              line='\1 pcie_aspm=off'

 

-- end of code extract ----

 



2013/10/1 Michael DeHaan <mic...@ansibleworks.com>

Alex Rodenberg

unread,
Oct 2, 2013, 10:29:00 AM10/2/13
to ansible...@googlegroups.com
At least for grub configs I'm not happy with templating, if i fx. do a kernel upgrade it will not point at the right stuff anymore.. but that can be templated as well i know :)

Thanks for the regexp Phillipe!
Reply all
Reply to author
Forward
0 new messages