# SETUP ################################################################################ - name: Install dependencies (Linux) ansible.builtin.package: name: e2fsprogs state: present when: ansible_system == 'Linux' - name: Install dependencies (FreeBSD) ansible.builtin.package: name: bash state: present - name: Register facts on Linux ansible.builtin.set_fact: shell_executable: /bin/bash ephemeral_device_a: /tmp/myfs_A.img ephemeral_device_b: /tmp/myfs_B.img ephemeral_fstype: ext3 ephemeral_fstab: /etc/fstab when: ansible_system == 'Linux' - name: Register facts on Solaris/SunOS ansible.builtin.set_fact: shell_executable: /usr/bin/bash ephemeral_device_a: /dev/lofi/1 ephemeral_device_b: /dev/lofi/2 ephemeral_create_loop_dev_cmd: >- lofiadm -a /tmp/myfs_A.img /dev/lofi/1 && lofiadm -a /tmp/myfs_B.img /dev/lofi/2 ephemeral_remove_loop_dev_cmd: >- lofiadm -d /dev/lofi/1 && lofiadm -d /dev/lofi/2 || true ephemeral_fstype: ufs ephemeral_fstab: /etc/vfstab when: ansible_system == 'SunOS' - name: Register facts on FreeBSD ansible.builtin.set_fact: shell_executable: /usr/local/bin/bash ephemeral_device_a: /dev/md1 ephemeral_device_b: /dev/md2 ephemeral_create_loop_dev_cmd: >- mdconfig -a -t vnode -f /tmp/myfs_A.img -u /dev/md1 && mdconfig -a -t vnode -f /tmp/myfs_B.img -u /dev/md2 ephemeral_remove_loop_dev_cmd: >- mdconfig -d -u /dev/md1 && mdconfig -d -u /dev/md2 ephemeral_fstype: ufs ephemeral_fstab: /etc/fstab when: ansible_system == 'FreeBSD' - name: Register facts on NetBSD ansible.builtin.set_fact: shell_executable: /usr/local/bin/bash ephemeral_device_a: /dev/vnd1 ephemeral_device_b: /dev/vnd2 ephemeral_create_loop_dev_cmd: >- vnconfig /dev/vnd1 /tmp/myfs_A.img && vnconfig /dev/vnd2 /tmp/myfs_B.img ephemeral_remove_loop_dev_cmd: >- vnconfig -u /dev/vnd1 && vnconfig -u /dev/vnd2 ephemeral_fstype: ufs ephemeral_fstab: /etc/fstab when: ansible_system == 'NetBSD' - name: Register format fs command on Non-Linux and Non-OpenBSD ansible.builtin.set_fact: ephemeral_format_fs_cmd: >- newfs {{ ephemeral_device_a }} && newfs {{ ephemeral_device_b }} when: ansible_system in ('SunOS', 'FreeBSD', 'NetBSD') - name: Register facts on OpenBSD ansible.builtin.set_fact: shell_executable: /usr/local/bin/bash ephemeral_device_a: /dev/vnd1c ephemeral_device_b: /dev/vnd2c ephemeral_create_loop_dev_cmd: >- vnconfig vnd1 /tmp/myfs_A.img && vnconfig vnd2 /tmp/myfs_B.img ephemeral_remove_loop_dev_cmd: >- vnconfig -u vnd1 && vnconfig -u vnd2 ephemeral_format_fs_cmd: >- newfs /dev/rvnd1c && newfs /dev/rvnd2c ephemeral_fstype: ffs ephemeral_fstab: /etc/fstab when: ansible_system == 'OpenBSD' - name: Create the mount point ansible.builtin.file: state: directory path: '{{ output_dir }}/mount_dest' mode: '0755' - name: Create a directory to bind mount ansible.builtin.file: state: directory path: '{{ output_dir }}/mount_source' mode: '0755' - name: Put something in the directory so we see that it worked ansible.builtin.copy: content: 'Testing ' dest: '{{ output_dir }}/mount_source/test_file' mode: '0644' register: orig_info # BIND MOUNT ################################################################################ # bind mount check mode - name: Bind mount a filesystem (Linux) (check mode) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: None opts: bind when: ansible_system == 'Linux' register: bind_result_linux_dry_run check_mode: true - name: Bind mount a filesystem (FreeBSD) (check mode) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: nullfs when: ansible_system == 'FreeBSD' register: bind_result_freebsd_dry_run check_mode: true - name: Attempt to stat bind mounted file ansible.builtin.stat: path: '{{ output_dir }}/mount_dest/test_file' when: ansible_system in ('FreeBSD', 'Linux') register: dest_stat - name: Assert the bind mount did not take place ansible.builtin.assert: that: - not dest_stat['stat']['exists'] when: ansible_system in ('FreeBSD', 'Linux') # bind mount - name: Bind mount a filesystem (Linux) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: None opts: bind when: ansible_system == 'Linux' register: bind_result_linux - name: Bind mount a filesystem (FreeBSD) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: nullfs when: ansible_system == 'FreeBSD' register: bind_result_freebsd - name: Get checksum for bind mounted file ansible.builtin.stat: path: '{{ output_dir }}/mount_dest/test_file' when: ansible_system in ('FreeBSD', 'Linux') register: dest_stat - name: Assert the bind mount was successful ansible.builtin.assert: that: - (ansible_system == 'Linux' and bind_result_linux['changed']) or (ansible_system == 'FreeBSD' and bind_result_freebsd['changed']) - dest_stat['stat']['exists'] - orig_info['checksum'] == dest_stat['stat']['checksum'] when: ansible_system in ('FreeBSD', 'Linux') - name: Bind mount a filesystem (Linux) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: None opts: bind when: ansible_system == 'Linux' register: bind_result_linux - name: Bind mount a filesystem (FreeBSD) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: nullfs when: ansible_system == 'FreeBSD' register: bind_result_freebsd - name: Make sure we didn't mount a second time ansible.builtin.assert: that: - (ansible_system == 'Linux' and not bind_result_linux['changed']) or (ansible_system == 'FreeBSD' and not bind_result_freebsd['changed']) when: ansible_system in ('FreeBSD', 'Linux') # remount check mode - name: Remount filesystem with different opts (Linux) (check mode) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: None opts: bind,ro when: ansible_system == 'Linux' register: bind_result_linux check_mode: true - name: Remount filesystem with different opts (FreeBSD) (check mode) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: nullfs opts: ro when: ansible_system == 'FreeBSD' register: bind_result_freebsd check_mode: true - name: Get mount options ansible.builtin.shell: cmd: set -o pipefail && mount | grep mount_dest | grep -c -E -w '(ro|read-only)' executable: "{{ shell_executable }}" changed_when: false failed_when: false register: new_options_count - name: Make sure the filesystem does not have the new opts ansible.builtin.assert: that: - linux_and_changed or freebsd_and_changed - new_options_count.stdout | int == 0 vars: linux_and_changed: "{{ ansible_system == 'Linux' and bind_result_linux_dry_run['changed'] }}" freebsd_and_changed: "{{ ansible_system == 'FreeBSD' and bind_result_freebsd['changed'] }}" when: ansible_system in ('FreeBSD', 'Linux') # remount - name: Remount filesystem with different opts (Linux) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: None opts: bind,ro when: ansible_system == 'Linux' register: bind_result_linux - name: Remount filesystem with different opts (FreeBSD) ansible.posix.mount: src: '{{ output_dir }}/mount_source' name: '{{ output_dir }}/mount_dest' state: mounted fstype: nullfs opts: ro when: ansible_system == 'FreeBSD' register: bind_result_freebsd - name: Get mount options ansible.builtin.shell: cmd: set -o pipefail && mount | grep mount_dest | grep -E -w '(ro|read-only)' | wc -l executable: "{{ shell_executable }}" changed_when: false register: remount_options - name: Make sure the filesystem now has the new opts ansible.builtin.assert: that: - (ansible_system == 'Linux' and bind_result_linux['changed']) or (ansible_system == 'FreeBSD' and bind_result_freebsd['changed']) - '''1'' in remount_options.stdout' - 1 == remount_options.stdout_lines | length when: ansible_system in ('FreeBSD', 'Linux') # unmount check mode - name: Unmount the bind mount (check mode) ansible.posix.mount: name: '{{ output_dir }}/mount_dest' state: absent when: ansible_system in ('Linux', 'FreeBSD') register: unmount_result check_mode: true - name: Make sure the file still exists in dest ansible.builtin.stat: path: '{{ output_dir }}/mount_dest/test_file' when: ansible_system in ('FreeBSD', 'Linux') register: dest_stat - name: Check that we did not unmount ansible.builtin.assert: that: - unmount_result['changed'] - dest_stat['stat']['exists'] when: ansible_system in ('FreeBSD', 'Linux') # unmount - name: Unmount the bind mount ansible.posix.mount: name: '{{ output_dir }}/mount_dest' state: absent when: ansible_system in ('Linux', 'FreeBSD') register: unmount_result - name: Make sure the file no longer exists in dest ansible.builtin.stat: path: '{{ output_dir }}/mount_dest/test_file' when: ansible_system in ('FreeBSD', 'Linux') register: dest_stat - name: Check that we unmounted ansible.builtin.assert: that: - unmount_result['changed'] - not dest_stat['stat']['exists'] when: ansible_system in ('FreeBSD', 'Linux') # SWAP ############################################################# - name: Swap when: ansible_system in ('Linux') block: # mount swap check mode - name: Stat /etc/fstab ansible.builtin.stat: path: /etc/fstab register: stat_fstab_before - name: Create fstab record for the first swap file (check mode) ansible.posix.mount: name: none src: /tmp/swap1 opts: sw fstype: swap state: present check_mode: true - name: Stat /etc/fstab ansible.builtin.stat: path: /etc/fstab register: stat_fstab_after - name: Assert that fstab checksum did not change ansible.builtin.assert: that: - stat_fstab_before.stat.checksum == stat_fstab_after.stat.checksum # mount swap1 - name: Create fstab record for the first swap file ansible.posix.mount: name: none src: /tmp/swap1 opts: sw fstype: swap state: present register: swap1_created - name: Try to create fstab record for the first swap file again ansible.posix.mount: name: none src: /tmp/swap1 opts: sw fstype: swap state: present register: swap1_created_again - name: Check that we created the swap1 record ansible.builtin.assert: that: - swap1_created['changed'] - not swap1_created_again['changed'] # mount swap2 - name: Create fstab record for the second swap file ansible.posix.mount: name: none src: /tmp/swap2 opts: sw fstype: swap state: present register: swap2_created - name: Try to create fstab record for the second swap file again ansible.posix.mount: name: none src: /tmp/swap2 opts: sw fstype: swap state: present register: swap2_created_again - name: Check that we created the swap2 record ansible.builtin.assert: that: - swap2_created['changed'] - not swap2_created_again['changed'] # remove swap check mode - name: Stat /etc/fstab ansible.builtin.stat: path: /etc/fstab register: stat_fstab_before - name: Remove the fstab record for the first swap file (check mode) ansible.posix.mount: name: none src: /tmp/swap1 state: absent check_mode: true - name: Stat /etc/fstab ansible.builtin.stat: path: /etc/fstab register: stat_fstab_after - name: Assert that fstab checksum did not change ansible.builtin.assert: that: - stat_fstab_before.stat.checksum == stat_fstab_after.stat.checksum # remove swap1 - name: Remove the fstab record for the first swap file ansible.posix.mount: name: none src: /tmp/swap1 state: absent register: swap1_removed - name: Try to remove the fstab record for the first swap file again ansible.posix.mount: name: none src: /tmp/swap1 state: absent register: swap1_removed_again - name: Check that we removed the swap1 record ansible.builtin.assert: that: - swap1_removed['changed'] - not swap1_removed_again['changed'] # remove swap2 - name: Remove the fstab record for the second swap file ansible.posix.mount: name: none src: /tmp/swap2 state: absent register: swap2_removed - name: Try to remove the fstab record for the second swap file again ansible.posix.mount: name: none src: /tmp/swap2 state: absent register: swap2_removed_again - name: Check that we removed the swap2 record ansible.builtin.assert: that: - swap2_removed['changed'] - not swap2_removed_again['changed'] # FIXUP ############################################################# - name: Fix incomplete entry already present in fstab when: ansible_system == 'Linux' block: - name: Create fstab record with missing last two fields ansible.builtin.copy: dest: /etc/fstab content: '//nas/photo /home/jik/pictures cifs defaults,credentials=/etc/security/nas.creds,uid=jik,gid=users,forceuid,forcegid,noserverino,_netdev ' mode: "0644" - name: Try to change the fstab record with the missing last two fields ansible.posix.mount: src: //nas/photo path: /home/jik/pictures fstype: cifs opts: defaults,credentials=/etc/security/nas.creds,uid=jik,gid=users,forceuid,forcegid,noserverino,_netdev,x-systemd.mount-timeout=0 state: present register: optional_fields_update - name: Get the content of the fstab file ansible.builtin.command: cat /etc/fstab changed_when: false register: optional_fields_content - name: Check if the line containing the missing last two fields was changed ansible.builtin.assert: that: - optional_fields_update['changed'] - ''' 0 0'' in optional_fields_content.stdout' - 1 == optional_fields_content.stdout_lines | length # REMOUNTED ############################################################# - name: Block to test remounted option when: ansible_system in ('Linux') block: # setup - name: Create empty file community.general.filesize: path: /tmp/myfs.img size: 20M - name: Format FS community.general.filesystem: fstype: ext3 dev: /tmp/myfs.img - name: Mount the FS for the first time ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext2 state: mounted - name: Get the last write time ansible.builtin.shell: cmd: >- set -o pipefail && dumpe2fs /tmp/myfs.img 2>/dev/null | grep -i "last write time:" | cut -d: -f2- executable: "{{ shell_executable }}" changed_when: false register: last_write_time - name: Wait 2 second ansible.builtin.pause: seconds: 2 # remount check mode - name: Remount (check mode) ansible.posix.mount: path: /tmp/myfs state: remounted - name: Get again the last write time ansible.builtin.shell: cmd: >- set -o pipefail && dumpe2fs /tmp/myfs.img 2>/dev/null | grep -i "last write time:" |cut -d: -f2- executable: "{{ shell_executable }}" changed_when: false register: last_write_time_check - name: Fail if they are different ansible.builtin.fail: msg: Filesytem was remounted, testing of the module failed! when: last_write_time.stdout != last_write_time_check.stdout # remount - name: Test if the FS is remounted ansible.posix.mount: path: /tmp/myfs state: remounted - name: Get again the last write time ansible.builtin.shell: cmd: >- set -o pipefail && dumpe2fs /tmp/myfs.img 2>/dev/null | grep -i "last write time:" |cut -d: -f2- executable: "{{ shell_executable }}" changed_when: false register: last_write_time2 - name: Fail if they are the same ansible.builtin.fail: msg: Filesytem was not remounted, testing of the module failed! when: last_write is defined and last_write_time2 is defined and last_write_time.stdout == last_write_time2.stdout # remount different options check mode - name: Remount filesystem with different opts using remounted option (Linux only) ansible.posix.mount: path: /tmp/myfs state: remounted opts: rw,noexec check_mode: true - name: Get remounted options (Linux only) ansible.builtin.shell: cmd: set -o pipefail && mount | grep myfs | grep -E -w 'noexec' | wc -l executable: "{{ shell_executable }}" failed_when: false changed_when: false register: remounted_options - name: Make sure the filesystem now has the new opts after using remounted (Linux only) ansible.builtin.assert: that: - "'0' in remounted_options.stdout" - "1 == remounted_options.stdout_lines | length" # remount different options - name: Remount filesystem with different opts using remounted option (Linux only) ansible.posix.mount: path: /tmp/myfs state: remounted opts: rw,noexec - name: Get remounted options (Linux only) ansible.builtin.shell: cmd: set -o pipefail && mount | grep myfs | grep -E -w 'noexec' | wc -l executable: "{{ shell_executable }}" changed_when: false register: remounted_options - name: Make sure the filesystem now has the new opts after using remounted (Linux only) ansible.builtin.assert: that: - "'1' in remounted_options.stdout" - "1 == remounted_options.stdout_lines | length" # backup - name: Mount the FS again to test backup ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext2 state: mounted backup: true register: mount_backup_out - name: Ensure backup_file in returned output ansible.builtin.assert: that: - "'backup_file' in mount_backup_out" always: - name: Umount the test FS ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img opts: loop state: absent - name: Remove the test FS ansible.builtin.file: path: '{{ item }}' state: absent loop: - /tmp/myfs.img - /tmp/myfs # BOOT ############################################################# - name: Block to test boot option for Linux when: ansible_system in ('Linux') block: # setup - name: Create empty file community.general.filesize: path: /tmp/myfs.img size: 20M - name: Format FS community.general.filesystem: fstype: ext3 dev: /tmp/myfs.img # noauto - name: Mount the FS with noauto option ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext3 state: mounted boot: false opts: rw,user,async register: mount_info - name: Assert the mount without noauto was successful ansible.builtin.assert: that: - mount_info['opts'] == 'rw,user,async,noauto' - name: Unmount FS ansible.posix.mount: path: /tmp/myfs state: absent # noauto + defaults - name: Mount the FS with noauto option and defaults ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext3 state: mounted boot: false register: mount_info - name: Assert the mount without noauto was successful ansible.builtin.assert: that: - "'noauto' in mount_info['opts'].split(',')" - name: Unmount FS ansible.posix.mount: path: /tmp/myfs state: absent - name: Remove the test FS ansible.builtin.file: path: '{{ item }}' state: absent loop: - /tmp/myfs.img - /tmp/myfs # NEWLINE END OF FILE ############################################ - name: Block to test missing newline at the EOF of fstab when: ansible_system in ('Linux') block: - name: Create empty file community.general.filesize: path: /tmp/myfs1.img size: 20M - name: Format FS community.general.filesystem: fstype: ext3 dev: /tmp/myfs1.img - name: Create custom fstab file without newline ansible.builtin.copy: content: '#TEST COMMENT WITHOUT NEWLINE' dest: /tmp/test_fstab mode: "0644" - name: Mount the FS using the custom fstab ansible.posix.mount: path: /tmp/myfs1 src: /tmp/myfs1.img fstype: ext3 state: mounted opts: defaults fstab: /tmp/test_fstab - name: Unmount the mount point in the custom fstab ansible.posix.mount: path: /tmp/myfs1 state: absent fstab: /tmp/test_fstab - name: Remove the test FS and the custom fstab ansible.builtin.file: path: '{{ item }}' state: absent loop: - /tmp/myfs1.img - /tmp/myfs1 - /tmp/test_fstab # EPHEMERAL ################################################ - name: Block to test ephemeral option environment: PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin when: ansible_system in ('Linux', 'SunOS', 'FreeBSD', 'NetBSD', 'OpenBSD') block: - name: Create empty file A community.general.filesize: path: /tmp/myfs_A.img size: 20M - name: Create empty file B community.general.filesize: path: /tmp/myfs_B.img size: 20M ##### FORMAT FS ON LINUX - name: Block to format FS on Linux when: ansible_system == 'Linux' block: - name: Format FS A on Linux community.general.filesystem: fstype: ext3 dev: /tmp/myfs_A.img - name: Format FS B on Linux community.general.filesystem: fstype: ext3 dev: /tmp/myfs_B.img ##### FORMAT FS ON SOLARIS AND BSD - name: Create loop devices on Solaris and BSD ansible.builtin.shell: cmd: "set -o pipefail && {{ ephemeral_create_loop_dev_cmd }}" executable: "{{ shell_executable }}" changed_when: true when: ephemeral_create_loop_dev_cmd is defined - name: Format FS A and B on Solaris and BSD ansible.builtin.shell: cmd: "set -o pipefail && {{ ephemeral_format_fs_cmd }}" executable: "{{ shell_executable }}" changed_when: true when: ephemeral_format_fs_cmd is defined - name: Create fstab if it does not exist ansible.builtin.file: path: "{{ ephemeral_fstab }}" state: touch mode: '0644' # normal ephemeral mount check mode - name: Get checksum of /etc/fstab before mounting anything ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_before_mount - name: Mount the FS A with ephemeral state (check mode) ansible.posix.mount: path: /tmp/myfs src: '{{ ephemeral_device_a }}' fstype: '{{ ephemeral_fstype }}' opts: rw state: ephemeral register: ephemeral_mount_info check_mode: true - name: Get checksum of /etc/fstab after an ephemeral mount ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_after_mount - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: check_mountinfo failed_when: false changed_when: false - name: Assert the mount occured and the fstab is unchanged ansible.builtin.assert: that: - check_mountinfo.stdout|int == 0 - ephemeral_mount_info['changed'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum'] # normal ephemeral mount - name: Get checksum of /etc/fstab before mounting anything ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_before_mount - name: Mount the FS A with ephemeral state ansible.posix.mount: path: /tmp/myfs src: '{{ ephemeral_device_a }}' fstype: '{{ ephemeral_fstype }}' opts: rw state: ephemeral register: ephemeral_mount_info - name: Put something in the directory so we can do additional checks later on ansible.builtin.copy: content: 'Testing' dest: /tmp/myfs/test_file mode: '0644' - name: Get checksum of /etc/fstab after an ephemeral mount ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_after_mount - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: check_mountinfo failed_when: false changed_when: false - name: Assert the mount occured and the fstab is unchanged ansible.builtin.assert: that: - check_mountinfo.stdout|int == 1 - ephemeral_mount_info['changed'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum'] # remount different options check mode - name: Get first mount record ansible.builtin.shell: cmd: grep '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: ephemeral_mount_record_1 changed_when: false - name: Try to mount FS A where FS A is already mounted (should trigger remount and changed) ansible.posix.mount: path: /tmp/myfs src: '{{ ephemeral_device_a }}' fstype: '{{ ephemeral_fstype }}' opts: ro state: ephemeral register: ephemeral_mount_info check_mode: true - name: Get second mount record (should be different than the first) ansible.builtin.shell: cmd: grep '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: ephemeral_mount_record_2 changed_when: false - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" failed_when: false register: check_mountinfo changed_when: false - name: Assert the FS A is still mounted, the options unchanged and the fstab unchanged ansible.builtin.assert: that: - check_mountinfo.stdout|int == 1 - ephemeral_mount_record_1.stdout == ephemeral_mount_record_2.stdout - ephemeral_mount_info['changed'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum'] # remount different options - name: Get first mount record ansible.builtin.shell: cmd: grep '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: ephemeral_mount_record_1 changed_when: false - name: Try to mount FS A where FS A is already mounted (should trigger remount and changed) ansible.posix.mount: path: /tmp/myfs src: '{{ ephemeral_device_a }}' fstype: '{{ ephemeral_fstype }}' opts: ro state: ephemeral register: ephemeral_mount_info - name: Get second mount record (should be different than the first) ansible.builtin.shell: cmd: grep '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: ephemeral_mount_record_2 changed_when: false - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" failed_when: false register: check_mountinfo changed_when: false - name: Assert the FS A is still mounted, the options changed and the fstab unchanged ansible.builtin.assert: that: - check_mountinfo.stdout|int == 1 - ephemeral_mount_record_1.stdout != ephemeral_mount_record_2.stdout - ephemeral_mount_info['changed'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum'] # conflicting mount - name: Try to mount file B on file A mountpoint (should fail) ansible.posix.mount: path: /tmp/myfs src: '{{ ephemeral_device_b }}' fstype: '{{ ephemeral_fstype }}' state: ephemeral register: ephemeral_mount_b_info ignore_errors: true - name: Get third mount record (should be the same than the second) ansible.builtin.shell: cmd: grep '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: ephemeral_mount_record_3 changed_when: false - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" failed_when: false register: check_mountinfo changed_when: false - name: Try to stat our test file ansible.builtin.stat: path: /tmp/myfs/test_file register: test_file_stat - name: Assert that mounting FS B over FS A failed ansible.builtin.assert: that: - check_mountinfo.stdout|int == 1 - ephemeral_mount_record_2.stdout == ephemeral_mount_record_3.stdout - test_file_stat['stat']['exists'] - ephemeral_mount_b_info is failed # unmount check mode - name: Unmount FS with state = unmounted ansible.posix.mount: path: /tmp/myfs state: unmounted check_mode: true - name: Get fstab checksum after unmounting an ephemeral mount with state = unmounted ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_after_unmount - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: check_mountinfo failed_when: false changed_when: false - name: Try to stat our test file ansible.builtin.stat: path: /tmp/myfs/test_file register: test_file_stat - name: Assert that unmount did not take place and fstab unchanged ansible.builtin.assert: that: - check_mountinfo.stdout|int == 1 - test_file_stat['stat']['exists'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_unmount['stat']['checksum'] # unmount - name: Unmount FS with state = unmounted ansible.posix.mount: path: /tmp/myfs state: unmounted - name: Get fstab checksum after unmounting an ephemeral mount with state = unmounted ansible.builtin.stat: path: '{{ ephemeral_fstab }}' register: fstab_stat_after_unmount - name: Get mountinfo ansible.builtin.shell: cmd: grep -c '/tmp/myfs' <(mount -v) executable: "{{ shell_executable }}" register: check_mountinfo failed_when: false changed_when: false - name: Try to stat our test file ansible.builtin.stat: path: /tmp/myfs/test_file register: test_file_stat - name: Assert that fstab is unchanged after unmounting an ephemeral mount with state = unmounted ansible.builtin.assert: that: - check_mountinfo.stdout|int == 0 - not test_file_stat['stat']['exists'] - fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_unmount['stat']['checksum'] always: - name: Unmount potential failure relicas ansible.posix.mount: path: /tmp/myfs state: unmounted - name: Remove loop devices on Solaris and BSD ansible.builtin.shell: cmd: "set -o pipefail && {{ ephemeral_remove_loop_dev_cmd }}" executable: "{{ shell_executable }}" changed_when: true when: ephemeral_remove_loop_dev_cmd is defined - name: Remove the test FS ansible.builtin.file: path: '{{ item }}' state: absent loop: - /tmp/myfs_A.img - /tmp/myfs_B.img - /tmp/myfs # OPTS_NO_LOG ###################################### - name: Block to test opts_no_log option when: ansible_system == 'Linux' block: - name: Create an empty file community.general.filesize: path: /tmp/myfs.img size: 1M - name: Format FS community.general.filesystem: fstype: ext4 dev: /tmp/myfs.img - name: Mount the FS with opts_no_log option true ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext4 state: mounted opts: rw opts_no_log: true register: mount_info - name: Assert opts_no_log option true ansible.builtin.assert: that: - mount_info.opts == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' - name: Remount the FS with opts_no_log option false ansible.posix.mount: path: /tmp/myfs src: /tmp/myfs.img fstype: ext4 state: remounted opts: rw,user opts_no_log: false register: mount_info - name: Assert opts_no_log option false ansible.builtin.assert: that: - mount_info.opts == 'rw,user' always: - name: Unmount FS ansible.posix.mount: path: /tmp/myfs state: absent - name: Remove the test FS ansible.builtin.file: path: '{{ item }}' state: absent loop: - /tmp/myfs.img - /tmp/myfs