blockinfile - Preserve line endings (#66461)

Fixes #64966
* Fix "TypeError: splitlines() takes no keyword arguments" on Python2.7
* Add changelog fragment
* Don't use `grep -P` for BSD/macOS compatibility
* Fix sanity checks complaining about test fixtures with mixed line endings
* Update changelogs/fragments/66461-blockinfile_preserve_line_endings.yaml
pull/69732/head
Riyad Preukschas 5 years ago committed by GitHub
parent 8b6c02fc69
commit e5cc12a64f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- blockinfile - preserve line endings on update (https://github.com/ansible/ansible/issues/64966)

@ -237,7 +237,7 @@ def main():
f = open(path, 'rb') f = open(path, 'rb')
original = f.read() original = f.read()
f.close() f.close()
lines = original.splitlines() lines = original.splitlines(True)
diff = {'before': '', diff = {'before': '',
'after': '', 'after': '',
@ -266,13 +266,13 @@ def main():
else: else:
insertre = None insertre = None
marker0 = re.sub(b(r'{mark}'), b(params['marker_begin']), marker) marker0 = re.sub(b(r'{mark}'), b(params['marker_begin']), marker) + b(os.linesep)
marker1 = re.sub(b(r'{mark}'), b(params['marker_end']), marker) marker1 = re.sub(b(r'{mark}'), b(params['marker_end']), marker) + b(os.linesep)
if present and block: if present and block:
# Escape sequences like '\n' need to be handled in Ansible 1.x # Escape sequences like '\n' need to be handled in Ansible 1.x
if module.ansible_version.startswith('1.'): if module.ansible_version.startswith('1.'):
block = re.sub('', block, '') block = re.sub('', block, '')
blocklines = [marker0] + block.splitlines() + [marker1] blocklines = [marker0] + block.splitlines(True) + [marker1]
else: else:
blocklines = [] blocklines = []
@ -306,9 +306,7 @@ def main():
lines[n0:n0] = blocklines lines[n0:n0] = blocklines
if lines: if lines:
result = b('\n').join(lines) result = b''.join(lines)
if original is None or original.endswith(b('\n')):
result += b('\n')
else: else:
result = b'' result = b''

@ -47,7 +47,7 @@
register: blockinfile_test0 register: blockinfile_test0
- name: check content - name: check content
shell: 'grep -e "Match User ansible-agent" -e "PasswordAuthentication no" {{ output_dir_test }}/sshd_config' shell: 'grep -c -e "Match User ansible-agent" -e "PasswordAuthentication no" {{ output_dir_test }}/sshd_config'
register: blockinfile_test0_grep register: blockinfile_test0_grep
- debug: - debug:
@ -65,7 +65,7 @@
- 'blockinfile_test0.msg is defined' - 'blockinfile_test0.msg is defined'
- 'blockinfile_test0.changed' - 'blockinfile_test0.changed'
- 'blockinfile_test0.msg == "Block inserted"' - 'blockinfile_test0.msg == "Block inserted"'
- 'blockinfile_test0_grep.stdout_lines | length == 2' - 'blockinfile_test0_grep.stdout == "2"'
- name: check idemptotence - name: check idemptotence
blockinfile: blockinfile:
@ -112,3 +112,28 @@
- empty_test_2 is changed - empty_test_2 is changed
- "'Block removed' in empty_test_2.msg" - "'Block removed' in empty_test_2.msg"
- empty_test_stat.stat.size == 0 - empty_test_stat.stat.size == 0
- name: create line_endings_test.txt in the test dir
copy:
dest: "{{ output_dir_test }}/line_endings_test.txt"
# generating the content like this instead of copying a fixture file
# prevents sanity checks from warning about mixed line endings
content: "unix\nunix\nunix\n\ndos\r\ndos\r\ndos\r\n\nunix\nunix\n# BEGIN ANSIBLE MANAGED BLOCK\ndos\r\n# END ANSIBLE MANAGED BLOCK\nunix\nunix\nunix\nunix\n"
- name: insert/update "dos" configuration block in line_endings_test.txt
blockinfile:
path: "{{ output_dir_test }}/line_endings_test.txt"
block: "dos\r\ndos\r\ndos\r\n"
register: blockinfile_test2
- name: check content
# using the more precise `grep -Pc "^dos\\r$" ...` fails on BSD/macOS
shell: 'grep -c "^dos.$" {{ output_dir_test }}/line_endings_test.txt'
register: blockinfile_test2_grep
- name: validate line_endings_test.txt results
assert:
that:
- 'blockinfile_test2 is changed'
- 'blockinfile_test2.msg == "Block inserted"'
- 'blockinfile_test2_grep.stdout == "6"'

Loading…
Cancel
Save