summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Doran <sdoran@redhat.com>2019-10-22 10:01:11 -0400
committerToshio Kuratomi <a.badger@gmail.com>2019-10-31 12:50:20 -0700
commitbaf5d3b4f01d90fb7e62723d52755307d70de65f (patch)
tree8e51f5194406f129a9a5c04aa253a0f297e6fddc
parent38607191207a03368073ef9874b2bbfc9bbf6d0a (diff)
downloadansible-baf5d3b4f01d90fb7e62723d52755307d70de65f.tar.gz
[temporary-2.9.1-branch-releng-only] lineinfile - properly insert line when line exists and backrefs are enabled (#63763)
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.yaml2
-rw-r--r--lib/ansible/modules/files/lineinfile.py18
-rw-r--r--test/integration/targets/lineinfile/tasks/main.yml35
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