Beispiel #1
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            boot=dict(type='bool', default=True),
            dump=dict(type='str'),
            fstab=dict(type='str'),
            fstype=dict(type='str'),
            path=dict(type='path', required=True, aliases=['name']),
            opts=dict(type='str'),
            passno=dict(type='str'),
            src=dict(type='path'),
            backup=dict(type='bool', default=False),
            state=dict(type='str',
                       required=True,
                       choices=[
                           'absent', 'mounted', 'present', 'unmounted',
                           'remounted'
                       ]),
        ),
        supports_check_mode=True,
        required_if=(
            ['state', 'mounted', ['src', 'fstype']],
            ['state', 'present', ['src', 'fstype']],
        ),
    )

    # solaris args:
    #   name, src, fstype, opts, boot, passno, state, fstab=/etc/vfstab
    # linux args:
    #   name, src, fstype, opts, dump, passno, state, fstab=/etc/fstab
    # Note: Do not modify module.params['fstab'] as we need to know if the user
    # explicitly specified it in mount() and remount()
    if platform.system().lower() == 'sunos':
        args = dict(name=module.params['path'],
                    opts='-',
                    passno='-',
                    fstab=module.params['fstab'],
                    boot='yes')
        if args['fstab'] is None:
            args['fstab'] = '/etc/vfstab'
    else:
        args = dict(name=module.params['path'],
                    opts='defaults',
                    dump='0',
                    passno='0',
                    fstab=module.params['fstab'])
        if args['fstab'] is None:
            args['fstab'] = '/etc/fstab'

        # FreeBSD doesn't have any 'default' so set 'rw' instead
        if platform.system() == 'FreeBSD':
            args['opts'] = 'rw'

    linux_mounts = []

    # Cache all mounts here in order we have consistent results if we need to
    # call is_bind_mounted() multiple times
    if platform.system() == 'Linux':
        linux_mounts = get_linux_mounts(module)

        if linux_mounts is None:
            args['warnings'] = ('Cannot open file /proc/self/mountinfo. '
                                'Bind mounts might be misinterpreted.')

    # Override defaults with user specified params
    for key in ('src', 'fstype', 'passno', 'opts', 'dump', 'fstab'):
        if module.params[key] is not None:
            args[key] = module.params[key]

    # If fstab file does not exist, we first need to create it. This mainly
    # happens when fstab option is passed to the module.
    if not os.path.exists(args['fstab']):
        if not os.path.exists(os.path.dirname(args['fstab'])):
            os.makedirs(os.path.dirname(args['fstab']))
        try:
            open(args['fstab'], 'a').close()
        except PermissionError as e:
            module.fail_json(msg="Failed to open %s due to permission issue" %
                             args['fstab'])
        except Exception as e:
            module.fail_json(msg="Failed to open %s due to %s" %
                             (args['fstab'], to_native(e)))

    # absent:
    #   Remove from fstab and unmounted.
    # unmounted:
    #   Do not change fstab state, but unmount.
    # present:
    #   Add to fstab, do not change mount state.
    # mounted:
    #   Add to fstab if not there and make sure it is mounted. If it has
    #   changed in fstab then remount it.

    state = module.params['state']
    name = module.params['path']
    changed = False

    if state == 'absent':
        name, changed = unset_mount(module, args)

        if changed and not module.check_mode:
            if ismount(name) or is_bind_mounted(module, linux_mounts, name):
                res, msg = umount(module, name)

                if res:
                    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:
                res, msg = umount(module, name)

                if res:
                    module.fail_json(msg="Error unmounting %s: %s" %
                                     (name, msg))

            changed = True
    elif state == 'mounted':
        dirs_created = []
        if not os.path.exists(name) and not module.check_mode:
            try:
                # Something like mkdir -p but with the possibility to undo.
                # Based on some copy-paste from the "file" module.
                curpath = ''
                for dirname in name.strip('/').split('/'):
                    curpath = '/'.join([curpath, dirname])
                    # Remove leading slash if we're creating a relative path
                    if not os.path.isabs(name):
                        curpath = curpath.lstrip('/')

                    b_curpath = to_bytes(curpath, errors='surrogate_or_strict')
                    if not os.path.exists(b_curpath):
                        try:
                            os.mkdir(b_curpath)
                            dirs_created.append(b_curpath)
                        except OSError as ex:
                            # Possibly something else created the dir since the os.path.exists
                            # check above. As long as it's a dir, we don't need to error out.
                            if not (ex.errno == errno.EEXIST
                                    and os.path.isdir(b_curpath)):
                                raise

            except (OSError, IOError) as e:
                module.fail_json(msg="Error making dir %s: %s" %
                                 (name, to_native(e)))

        name, backup_lines, changed = _set_mount_save_old(module, args)
        res = 0

        if (ismount(name) or is_bind_mounted(module, linux_mounts, name,
                                             args['src'], args['fstype'])):
            if changed and not module.check_mode:
                res, msg = remount(module, args)
                changed = True
        else:
            changed = True

            if not module.check_mode:
                res, msg = mount(module, args)

        if res:
            # Not restoring fstab after a failed mount was reported as a bug,
            # ansible/ansible#59183
            # A non-working fstab entry may break the system at the reboot,
            # so undo all the changes if possible.
            try:
                write_fstab(module, backup_lines, args['fstab'])
            except Exception:
                pass

            try:
                for dirname in dirs_created[::-1]:
                    os.rmdir(dirname)
            except Exception:
                pass

            module.fail_json(msg="Error mounting %s: %s" % (name, msg))
    elif state == 'present':
        name, changed = set_mount(module, args)
    elif state == 'remounted':
        if not module.check_mode:
            res, msg = remount(module, args)

            if res:
                module.fail_json(msg="Error remounting %s: %s" % (name, msg))

        changed = True
    else:
        module.fail_json(msg='Unexpected position reached')

    module.exit_json(changed=changed, **args)
Beispiel #2
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            account_subsystem=dict(type='bool', default=False),
            attributes=dict(type='list',
                            default=["agblksize='4096'", "isnapshot='no'"]),
            auto_mount=dict(type='bool', default=True),
            device=dict(type='str'),
            filesystem=dict(type='str', required=True),
            fs_type=dict(type='str', default='jfs2'),
            permissions=dict(type='str', default='rw', choices=['rw', 'ro']),
            mount_group=dict(type='str'),
            nfs_server=dict(type='str'),
            rm_mount_point=dict(type='bool', default=False),
            size=dict(type='str'),
            state=dict(type='str',
                       default='present',
                       choices=['absent', 'mounted', 'present', 'unmounted']),
            vg=dict(type='str'),
        ),
        supports_check_mode=True,
    )

    account_subsystem = module.params['account_subsystem']
    attributes = module.params['attributes']
    auto_mount = module.params['auto_mount']
    device = module.params['device']
    fs_type = module.params['fs_type']
    permissions = module.params['permissions']
    mount_group = module.params['mount_group']
    filesystem = module.params['filesystem']
    nfs_server = module.params['nfs_server']
    rm_mount_point = module.params['rm_mount_point']
    size = module.params['size']
    state = module.params['state']
    vg = module.params['vg']

    result = dict(
        changed=False,
        msg='',
    )

    if state == 'present':
        fs_mounted = ismount(filesystem)
        fs_exists = _fs_exists(module, filesystem)

        # Check if fs is mounted or exists.
        if fs_mounted or fs_exists:
            result['msg'] = "File system %s already exists." % filesystem
            result['changed'] = False

            # If parameter size was passed, resize fs.
            if size is not None:
                result['changed'], result['msg'] = resize_fs(
                    module, filesystem, size)

        # If fs doesn't exist, create it.
        else:
            # Check if fs will be a NFS device.
            if nfs_server is not None:
                if device is None:
                    result[
                        'msg'] = 'Parameter "device" is required when "nfs_server" is defined.'
                    module.fail_json(**result)
                else:
                    # Create a fs from NFS export.
                    if _check_nfs_device(module, nfs_server, device):
                        result['changed'], result['msg'] = create_fs(
                            module, fs_type, filesystem, vg, device, size,
                            mount_group, auto_mount, account_subsystem,
                            permissions, nfs_server, attributes)

            if device is None:
                if vg is None:
                    result[
                        'msg'] = 'Required parameter "device" and/or "vg" is missing for filesystem creation.'
                    module.fail_json(**result)
                else:
                    # Create a fs from
                    result['changed'], result['msg'] = create_fs(
                        module, fs_type, filesystem, vg, device, size,
                        mount_group, auto_mount, account_subsystem,
                        permissions, nfs_server, attributes)

            if device is not None and nfs_server is None:
                # Create a fs from a previously lv device.
                result['changed'], result['msg'] = create_fs(
                    module, fs_type, filesystem, vg, device, size, mount_group,
                    auto_mount, account_subsystem, permissions, nfs_server,
                    attributes)

    elif state == 'absent':
        if ismount(filesystem):
            result['msg'] = "File system %s mounted." % filesystem

        else:
            fs_status = _fs_exists(module, filesystem)
            if not fs_status:
                result['msg'] = "File system %s does not exist." % filesystem
            else:
                result['changed'], result['msg'] = remove_fs(
                    module, filesystem, rm_mount_point)

    elif state == 'mounted':
        if ismount(filesystem):
            result['changed'] = False
            result['msg'] = "File system %s already mounted." % filesystem
        else:
            result['changed'], result['msg'] = mount_fs(module, filesystem)

    elif state == 'unmounted':
        if not ismount(filesystem):
            result['changed'] = False
            result['msg'] = "File system %s already unmounted." % filesystem
        else:
            result['changed'], result['msg'] = unmount_fs(module, filesystem)

    else:
        # Unreachable codeblock
        result['msg'] = "Unexpected state %s." % state
        module.fail_json(**result)

    module.exit_json(**result)