diff options
author | Sam Doran <sdoran@redhat.com> | 2019-11-11 20:29:02 -0500 |
---|---|---|
committer | Matt Davis <nitzmahone@users.noreply.github.com> | 2019-11-11 17:29:02 -0800 |
commit | cbe69adf37d02e45f6180f307b36c2b55bf0cef6 (patch) | |
tree | 03c40a54cbc9c25485d3269840add06593a78e3a | |
parent | d3a9bbc9d171156130fd96a0d9f821fd38a5938c (diff) | |
download | ansible-cbe69adf37d02e45f6180f307b36c2b55bf0cef6.tar.gz |
[stable-2.8] lineinfile - properly insert line when line exists and backrefs are enabled (#63763) (#63791)
Use a separate variable for the boolean test rather than having the same variable sometimes be a boolean and sometimes be a regular expression match object
Add integration tests to cover this scenario
(cherry picked from commit 29d4d318a5)
Co-authored-by: Sam Doran <sdoran@redhat.com>
-rw-r--r-- | changelogs/fragments/lineinfile-backrefs-match-object-type.yaml | 2 | ||||
-rw-r--r-- | lib/ansible/modules/files/lineinfile.py | 18 | ||||
-rw-r--r-- | test/integration/targets/lineinfile/tasks/main.yml | 35 |
3 files changed, 34 insertions, 21 deletions
diff --git a/changelogs/fragments/lineinfile-backrefs-match-object-type.yaml b/changelogs/fragments/lineinfile-backrefs-match-object-type.yaml new file mode 100644 index 0000000000..55d532b356 --- /dev/null +++ b/changelogs/fragments/lineinfile-backrefs-match-object-type.yaml @@ -0,0 +1,2 @@ +bugfixes: + - lineinfile - properly handle inserting a line when backrefs are enabled and the line already exists in the file (https://github.com/ansible/ansible/issues/63756) diff --git a/lib/ansible/modules/files/lineinfile.py b/lib/ansible/modules/files/lineinfile.py index 26603326b8..dbe2b00084 100644 --- a/lib/ansible/modules/files/lineinfile.py +++ b/lib/ansible/modules/files/lineinfile.py @@ -286,7 +286,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, # index[0] is the line num where regexp has been found # index[1] is the line num where insertafter/insertbefore has been found index = [-1, -1] - m = None + match = None + exact_line_match = False b_line = to_bytes(line, errors='surrogate_or_strict') # The module's doc says @@ -303,18 +304,17 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, match_found = bre_m.search(b_cur_line) if match_found: index[0] = lineno - m = match_found + match = match_found if firstmatch: break # 2. When no match found on the previous step, # parse for searching insertafter/insertbefore: - if not m: + if not match: for lineno, b_cur_line in enumerate(b_lines): - match_found = b_line == b_cur_line.rstrip(b'\r\n') - if match_found: + if b_line == b_cur_line.rstrip(b'\r\n'): index[0] = lineno - m = match_found + exact_line_match = True elif bre_ins is not None and bre_ins.search(b_cur_line): if insertafter: @@ -334,8 +334,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, b_linesep = to_bytes(os.linesep, errors='surrogate_or_strict') # Exact line or Regexp matched a line in the file if index[0] != -1: - if backrefs: - b_new_line = m.expand(b_line) + if backrefs and match: + b_new_line = match.expand(b_line) else: # Don't do backref expansion if not asked. b_new_line = b_line @@ -345,7 +345,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, # If no regexp was given and no line match is found anywhere in the file, # insert the line appropriately if using insertbefore or insertafter - if regexp is None and m is None: + if regexp is None and match is None and not exact_line_match: # Insert lines if insertafter and insertafter != 'EOF': diff --git a/test/integration/targets/lineinfile/tasks/main.yml b/test/integration/targets/lineinfile/tasks/main.yml index 3ede5ded6b..ec6e59e264 100644 --- a/test/integration/targets/lineinfile/tasks/main.yml +++ b/test/integration/targets/lineinfile/tasks/main.yml @@ -126,7 +126,7 @@ lineinfile: dest: "{{ output_dir }}/test.txt" state: present - line: "New line after line 5" + line: "New line before line 5" insertbefore: "^This is line 5$" register: result @@ -144,22 +144,33 @@ - name: assert test checksum matches after the insert before the last line assert: that: - - "result.stat.checksum == 'e1cae425403507feea4b55bb30a74decfdd4a23e'" + - "result.stat.checksum == '2e9e460ff68929e4453eb765761fd99814f6e286'" -- name: replace a line with backrefs +- name: Replace a line with backrefs lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "This is line 3" backrefs: yes regexp: "^(REF) .* \\1$" - register: result + register: backrefs_result1 + +- name: Replace a line with backrefs again + lineinfile: + dest: "{{ output_dir }}/test.txt" + state: present + line: "This is line 3" + backrefs: yes + regexp: "^(REF) .* \\1$" + register: backrefs_result2 +- command: cat {{ output_dir }}/test.txt - name: assert that the line with backrefs was changed assert: that: - - result is changed - - "result.msg == 'line replaced'" + - backrefs_result1 is changed + - backrefs_result2 is not changed + - "backrefs_result1.msg == 'line replaced'" - name: stat the test after the backref line was replaced stat: @@ -169,7 +180,7 @@ - name: assert test checksum matches after backref line was replaced assert: that: - - "result.stat.checksum == '2ccdf45d20298f9eaece73b713648e5489a52444'" + - "result.stat.checksum == '72f60239a735ae06e769d823f5c2b4232c634d9c'" - name: remove the middle line lineinfile: @@ -192,7 +203,7 @@ - name: assert test checksum matches after the middle line was removed assert: that: - - "result.stat.checksum == 'a6ba6865547c19d4c203c38a35e728d6d1942c75'" + - "result.stat.checksum == 'd4eeb07bdebab2d1cdb3ec4a3635afa2618ad4ea'" - name: run a validation script that succeeds lineinfile: @@ -216,7 +227,7 @@ - name: assert test checksum matches after the validation succeeded assert: that: - - "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'" + - "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'" - name: run a validation script that fails lineinfile: @@ -240,7 +251,7 @@ - name: assert test checksum matches the previous after the validation failed assert: that: - - "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'" + - "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'" - name: use create=yes lineinfile: @@ -351,7 +362,7 @@ - name: assert test checksum matches after inserting multiple lines assert: that: - - "result.stat.checksum == 'bf5b711f8f0509355aaeb9d0d61e3e82337c1365'" + - "result.stat.checksum == 'fde683229429a4f05d670e6c10afc875e1d5c489'" - name: replace a line with backrefs included in the line lineinfile: @@ -376,7 +387,7 @@ - name: assert test checksum matches after backref line was replaced assert: that: - - "result.stat.checksum == '04b7a54d0fb233a4e26c9e625325bb4874841b3c'" + - "result.stat.checksum == '981ad35c4b30b03bc3a1beedce0d1e72c491898e'" ################################################################### # issue 8535 |