Joshua Grigonis
Joshua Grigonis

Reputation: 768

Using ansible lineinefile with colon in line

I am trying to make sure that a particular line is commented out in a source file.

The line is like this:

    CFUNCTYPE(c_int)(lambda: None)

If it exists, I want to comment it out:

    # CFUNCTYPE(c_int)(lambda: None)

If it doesn't exist, just ignore it.

If it exists and is already commented out, do nothing.

This is the playbook I wrote, but it doesn't work.

tasks:
  - name: fix ctypes file
    lineinfile: dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp="^#?CFUNCTYPE(c_int)(lambda: None)" line='# CFUNCTYPE(c_int)(lambda: None)'

The error says:

This one looks easy to fix. There seems to be an extra unquoted colon in the line and this is confusing the parser. It was only expecting to find one free colon. The solution is just add some quotes around the colon, or quote the entire line after the first colon.

However, it is not easy to fix, and I've tried quoting it in every way I can think of, to no avail.

Upvotes: 0

Views: 803

Answers (2)

HitScan
HitScan

Reputation: 8749

It's a YAML limitation; the parser likely wants to either see a name, colon, and name=value pairs with no more colons on the line, or just name, colon, and 1 quoted string value.

The lineinfile doc has an example for sudoers mentioning this (and another one further down that doesn't work...) and it references YAML as the problem. This means any time you need to have a colon in a value you may as well quote the entire string of arguments just to save yourself the debugging hassle.

Upvotes: 1

Joshua Grigonis
Joshua Grigonis

Reputation: 768

I made it work with this quoting:

lineinfile: "dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp='^#?CFUNCTYPE(c_int)(lambda: None)' line='# CFUNCTYPE(c_int)(lambda: None)'"

In order to ignore a file that doesn't exist, I used this code:

- stat: path=/usr/local/lib/python2.7/ctypes/__init__.py
  register: init
- name: fix ctypes file
  replace: "dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp='^(    CFUNCTYPE.c_int..lambda: None.)' replace='    # CFUNCTYPE(c_int)(lambda: None)'"
  when: init.stat.exists == True
  sudo: yes

I also had to change lineinfile to replace, because the line is prefixed with 4 spaces, and I couldn't get it to match correctly.

Upvotes: 0

Related Questions