diff --git a/changelogs/fragments/209_add_mode_for_mount.yml b/changelogs/fragments/209_add_mode_for_mount.yml new file mode 100644 index 0000000000..def2f90649 --- /dev/null +++ b/changelogs/fragments/209_add_mode_for_mount.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- mount - add ``umask`` parameter to control permissions of the directories created by the module (https://github.com/ansible-collections/ansible.posix/issues/163). diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 5c4970d537..7c12a455cb 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -105,6 +105,14 @@ the original file back if you somehow clobbered it incorrectly. type: bool default: no + umask: + description: + - The umask to set before creating new directory(ies) for the mount point. + If the mount point already exists, this parameter is not used. + - Note that after running this task and the device being successfully mounted, + the mode of the original directory will be hidden by the target device. + type: raw + version_added: '1.3.0' notes: - As of Ansible 2.3, the I(name) option has been changed to I(path) as default, but I(name) still works as well. @@ -122,6 +130,7 @@ fstype: iso9660 opts: ro,noauto state: present + umask: 0022 - name: Mount up device by label ansible.posix.mount: @@ -665,6 +674,7 @@ def main(): src=dict(type='path'), backup=dict(type='bool', default=False), state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted']), + umask=dict(type='raw'), ), supports_check_mode=True, required_if=( @@ -761,6 +771,7 @@ def main(): state = module.params['state'] name = module.params['path'] + umask = module.params['umask'] changed = False if state == 'absent': @@ -792,6 +803,15 @@ def main(): elif state == 'mounted': dirs_created = [] if not os.path.exists(name) and not module.check_mode: + old_umask = None + if umask is not None: + if not isinstance(umask, int): + try: + umask = int(umask, 8) + except ValueError as e: + module.fail_json(msg="umask must be an octal integer: %s" % (to_native(e))) + old_umask = os.umask(umask) + try: # Something like mkdir -p but with the possibility to undo. # Based on some copy-paste from the "file" module. @@ -816,6 +836,9 @@ def main(): except (OSError, IOError) as e: module.fail_json( msg="Error making dir %s: %s" % (name, to_native(e))) + finally: + if old_umask is not None: + os.umask(old_umask) name, backup_lines, changed = _set_mount_save_old(module, args) res = 0 diff --git a/tests/integration/targets/mount/tasks/main.yml b/tests/integration/targets/mount/tasks/main.yml index 44e120b370..324e1335b7 100644 --- a/tests/integration/targets/mount/tasks/main.yml +++ b/tests/integration/targets/mount/tasks/main.yml @@ -332,3 +332,79 @@ - /tmp/myfs.img - /tmp/myfs when: ansible_system in ('Linux') + +- name: Block to test umask option + block: + - name: Make sure that mount point does not exist + file: + path: /tmp/mount_dest + state: absent + - name: Create a directory to bind mount + file: + state: directory + path: /tmp/mount_source + - name: Bind mount a filesystem with umask + mount: + src: /tmp/mount_source + path: /tmp/mount_dest + state: mounted + fstype: None + opts: bind + umask: 0777 + when: ansible_system != 'FreeBSD' + - name: Bind mount a filesystem with umask(FreeBSD) + mount: + src: /tmp/mount_source + path: /tmp/mount_dest + state: mounted + fstype: nullfs + umask: 0777 + when: ansible_system == 'FreeBSD' + - name: Unmount FS to access underlying directory + command: | + umount /tmp/mount_dest + - name: Stat mount point directory + stat: + path: /tmp/mount_dest + register: mount_point_stat + - name: Assert that the mount point has right permission + assert: + that: + - mount_point_stat['stat']['mode'] == '0000' + - name: Cleanup directory + file: + path: /tmp/mount_dest + state: absent + - name: Bind mount a filesystem with string umask + mount: + src: /tmp/mount_source + path: /tmp/mount_dest + state: mounted + fstype: None + opts: bind + umask: "0777" + when: ansible_system != 'FreeBSD' + - name: Bind mount a filesystem with string umask(FreeBSD) + mount: + src: /tmp/mount_source + path: /tmp/mount_dest + state: mounted + fstype: nullfs + umask: "0777" + when: ansible_system == 'FreeBSD' + - name: Unmount FS to access underlying directory + command: | + umount /tmp/mount_dest + - name: Stat mount point directory + stat: + path: /tmp/mount_dest + register: mount_point_stat + - name: Assert that the mount point has right permission + assert: + that: + - mount_point_stat['stat']['mode'] == '0000' + - name: Remove the test FS + file: + path: /tmp/mount_dest + state: absent + when: ansible_system not in ('Darwin')