Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use bytes rather than native string for empty result in blockinfile #46281

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/blockinfile-bytes-fix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- blockinfile - use bytes rather than a native string to prevent a stacktrace in Python 3 when writing to the file (https://github.com/ansible/ansible/issues/46237)
2 changes: 1 addition & 1 deletion lib/ansible/modules/files/blockinfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def main():
if original is None or original.endswith(b('\n')):
result += b('\n')
else:
result = ''
result = b''

if module._diff:
diff['after'] = result
Expand Down
93 changes: 70 additions & 23 deletions test/integration/targets/blockinfile/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,99 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

- set_fact: output_dir_test={{output_dir}}/test_blockinfile
- set_fact:
output_dir_test: "{{ output_dir }}/test_blockinfile"

- name: make sure our testing sub-directory does not exist
file: path="{{ output_dir_test }}" state=absent
file:
path: "{{ output_dir_test }}"
state: absent

- name: create our testing sub-directory
file: path="{{ output_dir_test }}" state=directory
file:
path: "{{ output_dir_test }}"
state: directory

##
## blockinfile
##

- name: copy the sshd_config to the test dir
copy:
src: sshd_config
dest: "{{ output_dir_test }}"
src: sshd_config
dest: "{{ output_dir_test }}"

- name: insert/update "Match User" configuration block in sshd_config
blockinfile:
path: "{{ output_dir_test }}/sshd_config"
block: |
Match User ansible-agent
PasswordAuthentication no
path: "{{ output_dir_test }}/sshd_config"
block: |
Match User ansible-agent
PasswordAuthentication no
register: blockinfile_test0

- name: check content
shell: 'grep -e "Match User ansible-agent" -e "PasswordAuthentication no" {{ output_dir_test }}/sshd_config'
register: blockinfile_test0_grep
- debug: var=blockinfile_test0
- debug: var=blockinfile_test0_grep

- debug:
var: blockinfile_test0
verbosity: 1

- debug:
var: blockinfile_test0_grep
verbosity: 1

- name: validate first example results
assert:
that:
- 'blockinfile_test0.changed is defined'
- 'blockinfile_test0.msg is defined'
- 'blockinfile_test0.changed'
- 'blockinfile_test0.msg == "Block inserted"'
- 'blockinfile_test0_grep.stdout_lines | length == 2'
that:
- 'blockinfile_test0.changed is defined'
- 'blockinfile_test0.msg is defined'
- 'blockinfile_test0.changed'
- 'blockinfile_test0.msg == "Block inserted"'
- 'blockinfile_test0_grep.stdout_lines | length == 2'

- name: check idemptotence
blockinfile:
path: "{{ output_dir_test }}/sshd_config"
block: |
Match User ansible-agent
PasswordAuthentication no
path: "{{ output_dir_test }}/sshd_config"
block: |
Match User ansible-agent
PasswordAuthentication no
register: blockinfile_test1

- name: validate idempotence results
assert:
that:
- 'not blockinfile_test1.changed'
that:
- 'not blockinfile_test1.changed'

- name: Create a file with blockinfile
blockinfile:
path: "{{ output_dir_test }}/empty.txt"
block: |
Hey
there
state: present
create: yes
register: empty_test_1

- name: Run a task that results in an empty file
blockinfile:
path: "{{ output_dir_test }}/empty.txt"
block: |
Hey
there
state: absent
create: yes
register: empty_test_2

- stat:
path: "{{ output_dir_test }}/empty.txt"
register: empty_test_stat

- name: Ensure empty file was created
assert:
that:
- empty_test_1 is changed
- "'File created' in empty_test_1.msg"
- empty_test_2 is changed
- "'Block removed' in empty_test_2.msg"
- empty_test_stat.stat.size == 0