Remove last three lines from file using ansible - ansible

I want to remove last three lines of file using ansible. I tried using lineinfile but it removed all the lines from file. I have posted below my file and ansible-playbook. I want to remove nfs_config, nfs_share and mount_path using lines using ansible.Thanks in advance.
file.txt
[images]
[tickets]
[unix sockets]
[nfs_config]
nfs_share=
mount_path=
Ansible-playbook
- name: Remove mount path from daemon.conf for clean-daemon
linefile:
path: /etc/ovirt-imageio-daemon/daemon.conf
regexp: "[nfs_config]"
state: absent

Use ini_file. The task below will remove the nfs_config section from the configuration file
- ini_file:
path: /etc/ovirt-imageio-daemon/daemon.conf
section: nfs_config
state: absent

regexp: "[nfs_config]" is not doing what you want, you need to use "[nfs_config]", otherwise you are matching any character that is between the []. This is why it's removing multiple lines.
https://docs.python.org/2/library/re.html
Also, just make 3 lineinfile command to match nfs_config, nfs_share and mount_path
You could use onee lineinifile with a complex regex to match them all, but it will be easier to read/maintain with 3 that are clear.

Related

I want to replace a word which is associated with a particular pattern/line

Say a file (socket.cfg) has the following
socket1:a:1.2.3.4:wso,ws1,ws2
socket2:b:2.5.6.7:ws3,ws5,ws7
Now I want to change only the IP where "socket1" contains in the line and the rest should remain the same. The data given to me would be only socket1 and IP to be changed.
I did try lineinfile and replace module but the whole pattern changes. Kindly help me out.
It is similar to the sed command like this sed /socket1/<Ip_pattern>/<replacing_IP> So this goes to socket1 line picks the IP and replaces only that. I want something like this.
Here is what you need,
- name: replace the ip address
lineinfile:
path: /path/to/socket.cfg
regexp: ^(socket1)(.*)(\d+.\d+.\d+.\d+)(.*)
line: \g<1>\g<2>{{ inventory_hostname }}\g<4>
backrefs: yes
Note: I have used regex groups while replacing the contents.
I have replaced the IP with the inventory_hostname which is localhost in my case, you can update it to whatever you want.
Input:
socket1:b:1.2.3.4:ws3,ws5,ws7
socket2:b:2.5.6.7:ws3,ws5,ws7
Output:
socket1:b:localhost:ws3,ws5,ws7
socket2:b:2.5.6.7:ws3,ws5,ws7

Ansible lineinfile adding ^M to end of lines?

I am using ansible's lineinfile to update a file.
Once I've updated the file - which works - the file has ^M chars at the end of every line.
This behaviour is undesirable - how do I turn it off? It seems counter intuitive that I would then need to dos2unix in order to rectify?
- name: Update database.php - username
lineinfile:
dest: /var/www/html/database.php
regexp: '^\$username.*$'
line: "$username = '{{ mariadb_rc_user }}';"
backrefs: yes
edit note
Template and copy are possible but difficult to use in this situation for reasons I wont go into, but suffice to say: I'd use them if it made sense.
I found the answer and it was the opposite of what I expected. Neither lineinfile nor replace (see the duplicate link for a suggested solution) were the issue. In fact, they were doing their respective jobs - and ending lines with a line feed.
The problem arises because before that the file only has CLRF terminators, which are invisible when they exist exclusively.
When an LF is introduced, the CRLF (^M) is printed in vim to distinguish that there are now two types of line terminations.

Ansible: repeated lines exists but update only specific occurrence

I have to change
`<!--<parameter name=\"HostnameVerifier\">DefaultAndLocalhost</parameter>-->`
to
<!--<parameter name=\"HostnameVerifier\">AllowAll</parameter>--> in APIM_HOME/repository/conf/axis2/axis2.xml.
I am using
- name: "Modify HostnameVerifier"
lineinfile:
dest: "/home/ec2-user/ansible-test/wso2am-2.0.0/repository/conf/axis2/axis2.xml"
state: "present"
line: "\t\t<parameter name=\"HostnameVerifier\">AllowAll</parameter>"
regexp: "<!--<parameter name=\"HostnameVerifier\">DefaultAndLocalhost</parameter>-->"
This is only replacing the 3rd occurrence of the regexp. I want it to replace only 2nd occurrence. How do I do that?
You can't do this with lineinfile. From the docs:
...only the last line found will be replaced...
And lineinfile iterates line-by-line – you can't add more context to it.
You should use replace module and add more context to the regexp to match exatly that part of file you want to modify. You can use multiline patterns here.

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.
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.
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.

Remove a line from a file using ansible?

I have a file called authorized_keys. I need to delete a particular line using an Ansible script.
The problem is when I try to remove a line that includes a '+' character. Ansible is not able to remove this line.
e.g authorized_keys file is:
.....
abhi foo+bar saken
......(EOF)
I want to remove the abhi foo+bar saken line but Ansible is not removing this line because of the + character.
I am able to remove lines that do not contain a + character .
Task:
- name: Delete keys in sysadmin/.ssh/authoriezd_keys
lineinfile: dest=/home/{{name}}/.ssh/authorized_keys
state=absent
regexp='^{{key}}$'
PS: I am using Ansible's lineinfile module
The problem probably is that + has a meaning in a regular expression.
You should be able to fix it by escaping the +. If you can't do that from the source where {{ key }} is defined, you can escape it with the replace Jinja filter:
- name: Delete keys in sysadmin/.ssh/authoriezd_keys
lineinfile: dest=/home/{{name}}/.ssh/authorized_keys
state=absent
regexp='^{{ key | replace("+", "\+") }}$'
You might run into more problems if {{ key }} contains other characters which have a meaning in regular expressions. If that's the case I think the safe way would be to create your own filter plugin where you simply return the input passed through re.escape.

Resources