# Test code for the file module. # (c) 2014, Richard Isaacson # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . - set_fact: output_file={{output_dir}}/foo.txt # same as expanduser & expandvars called on managed host - command: 'echo {{ output_file }}' register: echo - set_fact: remote_file_expanded: '{{ echo.stdout }}' - name: prep with a basic copy copy: src=foo.txt dest={{output_file}} - name: verify that we are checking a file and it is present file: path={{output_file}} state=file register: file_result - name: verify that the file was marked as changed assert: that: - "file_result.changed == false" - "file_result.state == 'file'" - name: verify that we are checking an absent file file: path={{output_dir}}/bar.txt state=absent register: file2_result - name: verify that the file was marked as changed assert: that: - "file2_result.changed == false" - "file2_result.state == 'absent'" - name: verify we can touch a file file: path={{output_dir}}/baz.txt state=touch register: file3_result - name: verify that the file was marked as changed assert: that: - "file3_result.changed == true" - "file3_result.state == 'file'" - "file3_result.mode == '0644'" - name: change file mode file: path={{output_dir}}/baz.txt mode=0600 register: file4_result - name: verify that the file was marked as changed assert: that: - "file4_result.changed == true" - "file4_result.mode == '0600'" - name: change file attribute "A" file: path={{output_dir}}/baz.txt attributes=A register: file_attributes_result ignore_errors: True - name: reapply file attribute "A" file: path={{output_dir}}/baz.txt attributes=A register: file_attributes_result_2 when: file_attributes_result is changed - name: verify that the file was not marked as changed assert: that: - "file_attributes_result_2 is not changed" when: file_attributes_result is changed - name: change ownership and group file: path={{output_dir}}/baz.txt owner=1234 group=1234 - name: setup a tmp-like directory for ownership test file: path=/tmp/worldwritable mode=1777 state=directory - name: Ask to create a file without enough perms to change ownership file: path=/tmp/worldwritable/baz.txt state=touch owner=root become: yes become_user: nobody register: chown_result ignore_errors: True - name: Ask whether the new file exists stat: path=/tmp/worldwritable/baz.txt register: file_exists_result - name: Verify that the file doesn't exist on failure assert: that: - "chown_result.failed == True" - "file_exists_result.stat.exists == False" - name: clean up file: path=/tmp/worldwritable state=absent - name: create soft link to file file: src={{output_file}} dest={{output_dir}}/soft.txt state=link register: file5_result - name: verify that the file was marked as changed assert: that: - "file5_result.changed == true" - name: change soft link to relative file: src={{output_file|basename}} dest={{output_dir}}/soft.txt state=link register: file5a_result - name: verify that the file was marked as changed assert: that: - "file5a_result.changed == true" - "file5a_result.diff.before.src == remote_file_expanded" - "file5a_result.diff.after.src == remote_file_expanded|basename" - name: soft link idempotency check file: src={{output_file|basename}} dest={{output_dir}}/soft.txt state=link register: file5b_result - name: verify that the file was not marked as changed assert: that: - "file5b_result.changed == false" - name: create hard link to file file: src={{output_file}} dest={{output_dir}}/hard.txt state=hard register: file6_result - name: verify that the file was marked as changed assert: that: - "file6_result.changed == true" - name: touch a hard link file: src={{output_file}} dest={{output_dir}}/hard.txt state=touch register: file6_touch_result - name: verify that the hard link was touched assert: that: - "file6_touch_result.changed == true" - name: stat1 stat: path={{output_file}} register: hlstat1 - name: stat2 stat: path={{output_dir}}/hard.txt register: hlstat2 - name: verify that hard link is still the same after timestamp updated assert: that: - "hlstat1.stat.inode == hlstat2.stat.inode" - name: create hard link to file 2 file: src={{output_file}} dest={{output_dir}}/hard.txt state=hard register: hlink_result - name: verify that hard link creation is idempotent assert: that: - "hlink_result.changed == False" - name: Change mode on a hard link file: src={{output_file}} dest={{output_dir}}/hard.txt mode=0701 register: file6_mode_change - name: verify that the hard link was touched assert: that: - "file6_touch_result.changed == true" - name: stat1 stat: path={{output_file}} register: hlstat1 - name: stat2 stat: path={{output_dir}}/hard.txt register: hlstat2 - name: verify that hard link is still the same after timestamp updated assert: that: - "hlstat1.stat.inode == hlstat2.stat.inode" - "hlstat1.stat.mode == '0701'" - name: create a directory file: path={{output_dir}}/foobar state=directory register: file7_result - name: verify that the file was marked as changed assert: that: - "file7_result.changed == true" - "file7_result.state == 'directory'" - name: determine if selinux is installed shell: which getenforce || exit 0 register: selinux_installed - name: determine if selinux is enabled shell: getenforce register: selinux_enabled when: selinux_installed.stdout != "" ignore_errors: true - name: decide to include or not include selinux tests include: selinux_tests.yml when: selinux_installed is defined and selinux_installed.stdout != "" and selinux_enabled.stdout != "Disabled" - name: remote directory foobar file: path={{output_dir}}/foobar state=absent - name: remove file foo.txt file: path={{output_dir}}/foo.txt state=absent - name: remove file bar.txt file: path={{output_dir}}/foo.txt state=absent - name: remove file baz.txt file: path={{output_dir}}/foo.txt state=absent - name: copy directory structure over copy: src=foobar dest={{output_dir}} - name: Change ownership of a directory with recurse=no(default) file: path={{output_dir}}/foobar owner=1234 - name: verify that the permission of the directory was set file: path={{output_dir}}/foobar state=directory register: file8_result - name: assert that the directory has changed to have owner 1234 assert: that: - "file8_result.uid == 1234" - name: verify that the permission of a file under the directory was not set file: path={{output_dir}}/foobar/fileA state=file register: file9_result - name: assert the file owner has not changed to 1234 assert: that: - "file9_result.uid != 1234" - name: change the ownership of a directory with recurse=yes file: path={{output_dir}}/foobar owner=1235 recurse=yes - name: verify that the permission of the directory was set file: path={{output_dir}}/foobar state=directory register: file10_result - name: assert that the directory has changed to have owner 1235 assert: that: - "file10_result.uid == 1235" - name: verify that the permission of a file under the directory was not set file: path={{output_dir}}/foobar/fileA state=file register: file11_result - name: assert that the file has changed to have owner 1235 assert: that: - "file11_result.uid == 1235" - name: fail to create soft link to non existent file file: src=/noneexistent dest={{output_dir}}/soft2.txt state=link force=no register: file12_result ignore_errors: true - name: verify that link was not created assert: that: - "file12_result.failed == true" - name: force creation soft link to non existent file: src=/noneexistent dest={{output_dir}}/soft2.txt state=link force=yes register: file13_result - name: verify that link was created assert: that: - "file13_result.changed == true" - name: Prove idempotence of force creation soft link to non existent file: src=/noneexistent dest={{output_dir}}/soft2.txt state=link force=yes register: file13a_result - name: verify that the link to nonexistent is idempotent assert: that: - "file13a_result.changed == false" - name: remove directory foobar file: path={{output_dir}}/foobar state=absent register: file14_result - name: verify that the directory was removed assert: that: - 'file14_result.changed == true' - 'file14_result.state == "absent"' - name: create a test sub-directory file: dest={{output_dir}}/sub1 state=directory register: file15_result - name: verify that the new directory was created assert: that: - 'file15_result.changed == true' - 'file15_result.state == "directory"' - name: create test files in the sub-directory file: dest={{output_dir}}/sub1/{{item}} state=touch with_items: - file1 - file2 - file3 register: file16_result - name: verify the files were created assert: that: - 'item.changed == true' - 'item.state == "file"' with_items: "{{file16_result.results}}" - name: try to force the sub-directory to a link file: src={{output_dir}}/testing dest={{output_dir}}/sub1 state=link force=yes register: file17_result ignore_errors: true - name: verify the directory was not replaced with a link assert: that: - 'file17_result.failed == true' - 'file17_result.state == "directory"' - name: create soft link to directory using absolute path file: src=/ dest={{output_dir}}/root state=link register: file18_result - name: verify that the result was marked as changed assert: that: - "file18_result.changed == true" - name: create another test sub-directory file: dest={{output_dir}}/sub2 state=directory register: file19_result - name: verify that the new directory was created assert: that: - 'file19_result.changed == true' - 'file19_result.state == "directory"' - name: create soft link to relative file file: src=../sub1/file1 dest={{output_dir}}/sub2/link1 state=link register: file20_result - name: verify that the result was marked as changed assert: that: - "file20_result.changed == true" - name: create soft link to relative directory file: src=sub1 dest={{output_dir}}/sub1-link state=link register: file21_result - name: verify that the result was marked as changed assert: that: - "file21_result.changed == true" - name: test file creation with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=u=rwx,g=rwx,o=rwx register: result - name: assert file mode assert: that: - result.mode == '0777' - name: modify symbolic mode for all file: dest={{output_dir}}/test_symbolic state=touch mode=a=r register: result - name: assert file mode assert: that: - result.mode == '0444' - name: modify symbolic mode for owner file: dest={{output_dir}}/test_symbolic state=touch mode=u+w register: result - name: assert file mode assert: that: - result.mode == '0644' - name: modify symbolic mode for group file: dest={{output_dir}}/test_symbolic state=touch mode=g+w register: result - name: assert file mode assert: that: - result.mode == '0664' - name: modify symbolic mode for world file: dest={{output_dir}}/test_symbolic state=touch mode=o+w register: result - name: assert file mode assert: that: - result.mode == '0666' - name: modify symbolic mode for owner file: dest={{output_dir}}/test_symbolic state=touch mode=u+x register: result - name: assert file mode assert: that: - result.mode == '0766' - name: modify symbolic mode for group file: dest={{output_dir}}/test_symbolic state=touch mode=g+x register: result - name: assert file mode assert: that: - result.mode == '0776' - name: modify symbolic mode for world file: dest={{output_dir}}/test_symbolic state=touch mode=o+x register: result - name: assert file mode assert: that: - result.mode == '0777' - name: remove symbolic mode for world file: dest={{output_dir}}/test_symbolic state=touch mode=o-wx register: result - name: assert file mode assert: that: - result.mode == '0774' - name: remove symbolic mode for group file: dest={{output_dir}}/test_symbolic state=touch mode=g-wx register: result - name: assert file mode assert: that: - result.mode == '0744' - name: remove symbolic mode for owner file: dest={{output_dir}}/test_symbolic state=touch mode=u-wx register: result - name: assert file mode assert: that: - result.mode == '0444' - name: set sticky bit with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=o+t register: result - name: assert file mode assert: that: - result.mode == '01444' - name: remove sticky bit with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=o-t register: result - name: assert file mode assert: that: - result.mode == '0444' - name: add setgid with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=g+s register: result - name: assert file mode assert: that: - result.mode == '02444' - name: remove setgid with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=g-s register: result - name: assert file mode assert: that: - result.mode == '0444' - name: add setuid with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=u+s register: result - name: assert file mode assert: that: - result.mode == '04444' - name: remove setuid with symbolic mode file: dest={{output_dir}}/test_symbolic state=touch mode=u-s register: result - name: assert file mode assert: that: - result.mode == '0444' # test the file module using follow=yes, so that the target of a # symlink is modified, rather than the link itself - name: create a test file copy: dest={{output_dir}}/test_follow content="this is a test file\n" mode=0666 - name: create a symlink to the test file file: path={{output_dir}}/test_follow_link src="./test_follow" state=link - name: modify the permissions on the link using follow=yes file: path={{output_dir}}/test_follow_link mode=0644 follow=yes register: result - name: assert that the chmod worked assert: that: - result.changed - name: stat the link target stat: path={{output_dir}}/test_follow register: result - name: assert that the link target was modified correctly assert: that: - result.stat.mode == '0644' - name: attempt to modify the permissions of the link itself file: path={{output_dir}}/test_follow_link src="./test_follow" state=link mode=0600 follow=no register: result # Whether the link itself changed is platform dependent! (BSD vs Linux?) # Just check that the underlying file was not changed - name: stat the link target stat: path={{output_dir}}/test_follow register: result - name: assert that the link target was unmodified assert: that: - result.stat.mode == '0644' ignore_errors: True # Follow + recursive tests - name: create a toplevel directory file: path={{output_dir}}/test_follow_rec state=directory mode=0755 - name: create a file outside of the toplevel file: path={{output_dir}}/test_follow_rec_target_file state=touch mode=0700 - name: create a directory outside of the toplevel file: path={{output_dir}}/test_follow_rec_target_dir state=directory mode=0700 - name: create a file inside of the link target directory file: path={{output_dir}}/test_follow_rec_target_dir/foo state=touch mode=0700 - name: create a symlink to the file file: path={{output_dir}}/test_follow_rec/test_link state=link src="../test_follow_rec_target_file" - name: create a symlink to the directory file: path={{output_dir}}/test_follow_rec/test_link_dir state=link src="../test_follow_rec_target_dir" - name: create a symlink to a nonexistent file file: path={{output_dir}}/test_follow_rec/nonexistent state=link src=does_not_exist force=True - name: try to change permissions without following symlinks file: path={{output_dir}}/test_follow_rec follow=False mode="a-x" recurse=True - name: stat the link file target stat: path={{output_dir}}/test_follow_rec_target_file register: file_result - name: stat the link dir target stat: path={{output_dir}}/test_follow_rec_target_dir register: dir_result - name: stat the file inside the link dir target stat: path={{output_dir}}/test_follow_rec_target_dir/foo register: file_in_dir_result - debug: var=file_result.stat.mode - debug: var=dir_result.stat.mode - debug: var=file_in_dir_result.stat.mode - name: assert that the link targets were unmodified assert: that: - file_result.stat.mode == '0700' - dir_result.stat.mode == '0700' - file_in_dir_result.stat.mode == '0700' - name: try to change permissions with following symlinks file: path={{output_dir}}/test_follow_rec follow=True mode="a-x" recurse=True - name: stat the link file target stat: path={{output_dir}}/test_follow_rec_target_file register: file_result - name: stat the link dir target stat: path={{output_dir}}/test_follow_rec_target_dir register: dir_result - name: stat the file inside the link dir target stat: path={{output_dir}}/test_follow_rec_target_dir/foo register: file_in_dir_result - debug: var=file_result.stat.mode - debug: var=dir_result.stat.mode - debug: var=file_in_dir_result.stat.mode - name: assert that the link targets were modified assert: that: - file_result.stat.mode == '0600' - dir_result.stat.mode == '0600' - file_in_dir_result.stat.mode == '0600'