From 5ee818ec86771b8523517d0f990094fdf2424601 Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:41:21 +0200 Subject: [PATCH 01/11] Update mount.py In function main(), remove rmdir in case if state == 'absent'. Unmounting a file system should not lead to delete anything that is revealed after unmounting. Also, it leads to an error if a non empty directory is present under the ex-mountpoint after umount : [Errno 39] Directory not empty So umount is successfull but the ansible run is failed. Of course, it is solved on second run. --- plugins/modules/mount.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index fe9faff569..7bc897bbff 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -899,11 +899,6 @@ def main(): module.fail_json( msg="Error unmounting %s: %s" % (name, msg)) - if os.path.exists(name): - try: - os.rmdir(name) - except (OSError, IOError) as e: - module.fail_json(msg="Error rmdir %s: %s" % (name, to_native(e))) elif state == 'unmounted': if ismount(name) or is_bind_mounted(module, linux_mounts, name): if not module.check_mode: From 966df79767deecce410279845df108097367904f Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:36:45 +0200 Subject: [PATCH 02/11] Update mount.py new option keep_mountpoint enables keeping the mountpoint with state=absent --- plugins/modules/mount.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 7bc897bbff..d66e625260 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -73,7 +73,7 @@ point will be created. - If V(unmounted), the device will be unmounted without changing I(fstab). - V(present) only specifies that the device is to be configured in - I(fstab) and does not trigger or require a mount. + I(fstab) and does not trigger or require a mount. TODO check - V(ephemeral) only specifies that the device is to be mounted, without changing I(fstab). If it is already mounted, a remount will be triggered. This will always return RV(ignore:changed=true). If the mount point O(path) @@ -87,7 +87,8 @@ real source. V(absent) does not unmount recursively, and the module will fail if multiple devices are mounted on the same mount point. Using V(absent) with a mount point that is not registered in the I(fstab) has - no effect, use V(unmounted) instead. + no effect, use V(unmounted) instead. You can set O(keep_mountpoint) to + True to keep the mountpoint. - V(remounted) specifies that the device will be remounted for when you want to force a refresh on the mount itself (added in 2.9). This will always return RV(ignore:changed=true). If O(opts) is set, the options will be @@ -132,6 +133,16 @@ the original file back if you somehow clobbered it incorrectly. type: bool default: false + keep_mountpoint: + description: + - Change the default behaviour of state=absent by keeping the mountpoint + - With keep_mountpoint=true, state=absent is like unmounted plus the + fstab update. + - Use it if you care about finding original mountpoint content without failing + and want to remove the entry in fstab. If you have no entry to clean in + fstab you can use state=unmounted + type: bool + default: false notes: - As of Ansible 2.3, the O(name) option has been changed to O(path) as default, but O(name) still works as well. @@ -779,6 +790,7 @@ def main(): src=dict(type='path'), backup=dict(type='bool', default=False), state=dict(type='str', required=True, choices=['absent', 'absent_from_fstab', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']), + keep_mountpoint=dict(type='bool', default=False), ), supports_check_mode=True, required_if=( @@ -899,6 +911,11 @@ def main(): module.fail_json( msg="Error unmounting %s: %s" % (name, msg)) + if os.path.exists(name) and module.params['keep_mountpoint'] is False: + try: + os.rmdir(name) + except (OSError, IOError) as e: + module.fail_json(msg="Error rmdir %s: %s" % (name, to_native(e))) elif state == 'unmounted': if ismount(name) or is_bind_mounted(module, linux_mounts, name): if not module.check_mode: From f7f54f242d1a0d1515cdb3d13f5f3a2d05b91d50 Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:32:42 +0200 Subject: [PATCH 03/11] Update mount.py suppressed erroneous remaining TOTO check --- plugins/modules/mount.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index d66e625260..2bda2c6afe 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -73,7 +73,7 @@ point will be created. - If V(unmounted), the device will be unmounted without changing I(fstab). - V(present) only specifies that the device is to be configured in - I(fstab) and does not trigger or require a mount. TODO check + I(fstab) and does not trigger or require a mount. - V(ephemeral) only specifies that the device is to be mounted, without changing I(fstab). If it is already mounted, a remount will be triggered. This will always return RV(ignore:changed=true). If the mount point O(path) From 284025660c053de08f5607d41550242584bc94aa Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:27:18 +0200 Subject: [PATCH 04/11] delete trailing spaces in mount.py delete trailing spaces in comments in mount.py --- plugins/modules/mount.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 2bda2c6afe..183eb9d3b7 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -73,7 +73,7 @@ point will be created. - If V(unmounted), the device will be unmounted without changing I(fstab). - V(present) only specifies that the device is to be configured in - I(fstab) and does not trigger or require a mount. + I(fstab) and does not trigger or require a mount. - V(ephemeral) only specifies that the device is to be mounted, without changing I(fstab). If it is already mounted, a remount will be triggered. This will always return RV(ignore:changed=true). If the mount point O(path) @@ -87,7 +87,7 @@ real source. V(absent) does not unmount recursively, and the module will fail if multiple devices are mounted on the same mount point. Using V(absent) with a mount point that is not registered in the I(fstab) has - no effect, use V(unmounted) instead. You can set O(keep_mountpoint) to + no effect, use V(unmounted) instead. You can set O(keep_mountpoint) to True to keep the mountpoint. - V(remounted) specifies that the device will be remounted for when you want to force a refresh on the mount itself (added in 2.9). This will @@ -138,7 +138,7 @@ - Change the default behaviour of state=absent by keeping the mountpoint - With keep_mountpoint=true, state=absent is like unmounted plus the fstab update. - - Use it if you care about finding original mountpoint content without failing + - Use it if you care about finding original mountpoint content without failing and want to remove the entry in fstab. If you have no entry to clean in fstab you can use state=unmounted type: bool From 5bc6f636f709553b25e8aa2a048eb9c3878d9234 Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:08:03 +0200 Subject: [PATCH 05/11] Update mount.py still a trailing whitespace --- plugins/modules/mount.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 183eb9d3b7..78ccf390be 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -73,7 +73,7 @@ point will be created. - If V(unmounted), the device will be unmounted without changing I(fstab). - V(present) only specifies that the device is to be configured in - I(fstab) and does not trigger or require a mount. + I(fstab) and does not trigger or require a mount. - V(ephemeral) only specifies that the device is to be mounted, without changing I(fstab). If it is already mounted, a remount will be triggered. This will always return RV(ignore:changed=true). If the mount point O(path) From 841a0f33147715a7431de28b7666c68008c56b5a Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:46:26 +0200 Subject: [PATCH 06/11] modules/mount.py --- plugins/modules/mount.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 78ccf390be..7b357e6be1 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -186,6 +186,23 @@ path: /tmp/mnt-pnt state: remounted +# The following will fail on first run +# if /home/mydir is not empty after unmounting, +# though unmount and remove from fstab are successfull. +# It will be successfull on subsequent runs (already unmounted). +- name: Unmount and remove from fstab, then if unmount was necessary try to remove mountpoint /home/mydir + ansible.posix.mount: + path: /home/mydir + state: absent +# The following will not fail on first run +# if /home/mydir is not empty after unmounting. +# It will leave /home/mydir and its content (if any) after unmounting. +- name: Unmount and remove from fstab, but keep /home/mydir + ansible.posix.mount: + path: /home/mydir + state: absent + keep_mountpoint: true + # The following will not save changes to fstab, and only be temporary until # a reboot, or until calling "state: unmounted" followed by "state: mounted" # on the same "path" From 5a16ef3bea1f1fe5670d42bfb4d001d09109fb6f Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:53:27 +0200 Subject: [PATCH 07/11] Add files via upload --- .../integration/targets/mount/tasks/main.yml | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/tests/integration/targets/mount/tasks/main.yml b/tests/integration/targets/mount/tasks/main.yml index 15c6e897d7..09b315f4d0 100644 --- a/tests/integration/targets/mount/tasks/main.yml +++ b/tests/integration/targets/mount/tasks/main.yml @@ -789,3 +789,85 @@ loop: - /tmp/myfs.img - /tmp/myfs + +- name: Block to test keep_mountpoint option + block: + - name: Create the mount point + ansible.builtin.file: + state: directory + path: '/tmp/myfs' + mode: '0755' + + - name: Create empty file for FS aaa + community.general.filesize: + path: /tmp/myfs.img + size: 20M + + - name: Format FS bbb + community.general.filesystem: + fstype: xfs + dev: /tmp/myfs.img + + - name: Put data in the mount point before mounting + ansible.builtin.copy: + content: 'Testing + This is the data before mounting + ' + dest: '/tmp/myfs/test_file' + mode: '0644' + register: file_before_info + + - name: Mount with fstab + ansible.posix.mount: + path: '/tmp/myfs' + fstype: xfs + state: mounted + src: '/tmp/myfs.img' + + - name: Check data disappears - stat data + ansible.builtin.stat: + path: '/tmp/myfs/test_file' + register: file_stat_after_mount + - name: Check data disappears - file does not exist + ansible.builtin.assert: + that: + - file_stat_after_mount['stat']['exists'] == false + - name: Put data in the mount point after mounting + ansible.builtin.copy: + content: 'Testing + This is the data updated after mounting + ' + dest: '/tmp/myfs/test_file' + mode: '0644' + register: file_after_info + - name: Umount with keep_mountpoint + ansible.posix.mount: + path: '/tmp/myfs' + fstype: xfs + state: absent + keep_mountpoint: true + - name: Check original data reappears - stat data + ansible.builtin.stat: + path: '/tmp/myfs/test_file' + register: file_stat_after_umount + - name: Check original data reappears - compare checksums + ansible.builtin.assert: + that: + - file_stat_after_umount['stat']['checksum'] == file_before_info['checksum'] + always: + - name: Remove the first test file + ansible.builtin.file: + path: /tmp/myfs/test_file + state: absent + - name: Unmount FS + ansible.posix.mount: + path: /tmp/myfs + state: absent + - name: Remove the test FS and the second test file + ansible.builtin.file: + path: '{{ item }}' + state: absent + loop: + - /tmp/myfs/test_file + - /tmp/myfs.img + - /tmp/myfs From 70b838f031964d02f78982241a11bb8257cbe90c Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:54:16 +0200 Subject: [PATCH 08/11] Add files via upload --- changelogs/fragments/569_keep_mountpoint.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelogs/fragments/569_keep_mountpoint.yml diff --git a/changelogs/fragments/569_keep_mountpoint.yml b/changelogs/fragments/569_keep_mountpoint.yml new file mode 100644 index 0000000000..db7c6e203f --- /dev/null +++ b/changelogs/fragments/569_keep_mountpoint.yml @@ -0,0 +1,6 @@ +--- +minor_changes: +- keep_mountpoint - added keep_mountpoint option with default value false. If set to true keep_mountpoint changes the behaviour of state: absent by keeping the mountpoint. + +# vim: ai sw=2 ts=2 et nu + From 2c8aad9f395aa263a7f7770fc4cbbe19fe3c4b73 Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:58:01 +0200 Subject: [PATCH 09/11] Update 569_keep_mountpoint.yml remove empty lines and vim comment --- changelogs/fragments/569_keep_mountpoint.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/changelogs/fragments/569_keep_mountpoint.yml b/changelogs/fragments/569_keep_mountpoint.yml index db7c6e203f..9b77b68d69 100644 --- a/changelogs/fragments/569_keep_mountpoint.yml +++ b/changelogs/fragments/569_keep_mountpoint.yml @@ -1,6 +1,3 @@ --- minor_changes: - keep_mountpoint - added keep_mountpoint option with default value false. If set to true keep_mountpoint changes the behaviour of state: absent by keeping the mountpoint. - -# vim: ai sw=2 ts=2 et nu - From 572167b9c182c35e3e34fb975170bd155f956d31 Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:10:24 +0200 Subject: [PATCH 10/11] Update mount.py deleted trailing newlines --- plugins/modules/mount.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 7b357e6be1..d8e01b96fd 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -186,7 +186,7 @@ path: /tmp/mnt-pnt state: remounted -# The following will fail on first run +# The following will fail on first run # if /home/mydir is not empty after unmounting, # though unmount and remove from fstab are successfull. # It will be successfull on subsequent runs (already unmounted). @@ -194,7 +194,7 @@ ansible.posix.mount: path: /home/mydir state: absent -# The following will not fail on first run +# The following will not fail on first run # if /home/mydir is not empty after unmounting. # It will leave /home/mydir and its content (if any) after unmounting. - name: Unmount and remove from fstab, but keep /home/mydir From d05a5c70b5c68ff30dd76296495711e41ec7b88a Mon Sep 17 00:00:00 2001 From: Yves MOYROUD <41052194+YvesMP@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:24:52 +0200 Subject: [PATCH 11/11] Update 569_keep_mountpoint.yml escape : --- changelogs/fragments/569_keep_mountpoint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/569_keep_mountpoint.yml b/changelogs/fragments/569_keep_mountpoint.yml index 9b77b68d69..3536263fc8 100644 --- a/changelogs/fragments/569_keep_mountpoint.yml +++ b/changelogs/fragments/569_keep_mountpoint.yml @@ -1,3 +1,3 @@ --- minor_changes: -- keep_mountpoint - added keep_mountpoint option with default value false. If set to true keep_mountpoint changes the behaviour of state: absent by keeping the mountpoint. +- keep_mountpoint - added keep_mountpoint option with default value false. If set to true keep_mountpoint changes the behaviour of state\: absent by keeping the mountpoint.