Module blockinfile doesn't respect line endings that differ from os.linesep
Summary
When a file on a UNIX system using UNIX LF line endings is updated to have Windows CRLF line endings, blockinfile is no longer idempotent, does not detect the existing block and writes a new block with UNIX LF that does not match the rest of the file.
Issue Type
Bug Report
Component Name
blockinfile
Ansible Version
$ ansible --version
ansible [core 2.18.6]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /root/scripts/cron/ansible/lib64/python3.11/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = bin/ansible
python version = 3.11.11 (main, Dec 12 2024, 09:11:52) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] (/root/scripts/cron/ansible/bin/python3.11)
jinja version = 3.1.3
libyaml = True
Configuration
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
CONFIG_FILE() = None
GALAXY_SERVERS:
OS / Environment
RHEL 8 (AlmaLinux 8)
Steps to Reproduce
ansible -m file -a "path=/tmp/block.test state=touch" localhost
ansible -m blockinfile -a "path=/tmp/block.test block=blocktext" localhost
ansible -m replace -a "path=/tmp/block.test regexp='^(.*)$' replace='\1\r'" localhost
ansible -m blockinfile -a "path=/tmp/block.test block=blocktext" localhost
Expected Results
The second time running blockinfile should detect the existing block and not modify the file, reporting OK - no change.
I would also accept detecting the existing block and modifying the existing block to change the line endings back to UNIX LF if you prefer.
In either case, relying on os.linesep is not sufficiently robust because not all files on an OS use the correct line endings - especially in a multi-user environment. In our case, these files that use blockinfile to manage certain configuration settings are also modified by developers outside our control using windows tools which automatically change the line endings throughout the file. Not ideal I know, but it's the environment we're working with.
The blockinfile module should detect the block using markers no matter what line endings are in use.
Actual Results
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | CHANGED => {
"changed": true,
"msg": "Block inserted"
}
Code of Conduct
- I agree to follow the Ansible Code of Conduct
Source: ansible/ansible