diff --git a/changelogs/fragments/lineinfile-insertbefore-index-out-of-range.yaml b/changelogs/fragments/lineinfile-insertbefore-index-out-of-range.yaml new file mode 100644 index 00000000000..52d4565feab --- /dev/null +++ b/changelogs/fragments/lineinfile-insertbefore-index-out-of-range.yaml @@ -0,0 +1,2 @@ +bugfixes: + - lineinfile - fix index out of range error when using insertbefore on a file with only one line (https://github.com/ansible/ansible/issues/46043) diff --git a/lib/ansible/modules/files/lineinfile.py b/lib/ansible/modules/files/lineinfile.py index 0e330cb186e..a8359636a0d 100644 --- a/lib/ansible/modules/files/lineinfile.py +++ b/lib/ansible/modules/files/lineinfile.py @@ -328,7 +328,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, elif insertbefore and insertbefore != 'BOF': # If the line to insert before is at the beginning of the file # use the appropriate index value. - if index[1] == 0: + if index[1] <= 0: if b_lines[index[1]].rstrip(b('\r\n')) != b_line: b_lines.insert(index[1], b_line + b_linesep) msg = 'line replaced' diff --git a/test/integration/targets/lineinfile/tasks/main.yml b/test/integration/targets/lineinfile/tasks/main.yml index e9c76c4aef7..680394f4267 100644 --- a/test/integration/targets/lineinfile/tasks/main.yml +++ b/test/integration/targets/lineinfile/tasks/main.yml @@ -718,6 +718,37 @@ that: - result.stat.checksum == 'eca8d8ea089d4ea57a3b87d4091599ca8b60dfd2' +- name: Copy empty file to test with insertbefore + copy: + src: testempty.txt + dest: "{{ output_dir }}/testempty.txt" + +- name: Add a line to empty file with insertbefore + lineinfile: + path: "{{ output_dir }}/testempty.txt" + line: top + insertbefore: '^not in the file$' + register: oneline_insbefore_test1 + +- name: Add a line to file with only one line using insertbefore + lineinfile: + path: "{{ output_dir }}/testempty.txt" + line: top + insertbefore: '^not in the file$' + register: oneline_insbefore_test2 + +- name: Stat the file + stat: + path: "{{ output_dir }}/testempty.txt" + register: oneline_insbefore_file + +- name: Assert that insertebefore worked properly with a one line file + assert: + that: + - oneline_insbefore_test1 is changed + - oneline_insbefore_test2 is not changed + - oneline_insbefore_file.stat.checksum == '4dca56d05a21f0d018cd311f43e134e4501cf6d9' + ################################################################### # Issue 29443 # When using an empty regexp, replace the last line (since it matches every line)