Exemplo n.º 1
0
    def run(self, path, permissions, recursive=False):
        if permissions.get('user') or permissions.get('group'):
            user = permissions.get('user')
            group = permissions.get('group')
            uid = gid = -1

            if user:
                try:
                    uid = pwd.getpwnam(user).pw_uid
                except KeyError:
                    raise TaskException(errno.ENOENT, 'User {0} not found'.format(user))

            if group:
                try:
                    gid = grp.getgrnam(group).gr_gid
                except KeyError:
                    raise TaskException(errno.ENOENT, 'Group {0} not found'.format(group))

            bsd.lchown(path, uid, gid, recursive)

        if permissions.get('modes'):
            modes = permissions['modes']
            if modes.get('value'):
                modes = int(modes['value'])
            else:
                modes = modes_to_oct(modes)

            bsd.lchmod(path, modes, recursive)

        if permissions.get('acl'):
            a = acl.ACL()
            a.__setstate__(permissions['acl'])
            a.apply(path)
            if not recursive:
                return

            for root, dirs, files in os.walk(path):
                for n in files:
                    a.apply(file=os.path.join(root, n))

                for n in dirs:
                    a.apply(file=os.path.join(root, n))

        self.dispatcher.dispatch_event('file.permissions.changed', {
            'path': path,
            'recursive': recursive,
            'permissions': permissions
        })
Exemplo n.º 2
0
    def run(self, path, permissions, recursive=False):
        if not os.path.exists(path):
            raise TaskException(errno.ENOENT, 'Path {0} does not exist'.format(path))

        if recursive and not os.path.isdir(path):
            raise TaskException(errno.EINVAL, 'Recursive specified, but {0} is not directory'.format(path))

        if permissions.get('user') or permissions.get('group'):
            user = permissions.get('user')
            group = permissions.get('group')
            uid = gid = -1

            if user:
                try:
                    user = self.dispatcher.call_sync('dscached.account.getpwnam', user)
                    uid = user['uid']
                except RpcException:
                    raise TaskException(errno.ENOENT, 'User {0} not found'.format(user))

            if group:
                try:
                    group = self.dispatcher.call_sync('dscached.group.getgrnam', group)
                    gid = group['gid']
                except KeyError:
                    raise TaskException(errno.ENOENT, 'Group {0} not found'.format(group))

            bsd.lchown(path, uid, gid, recursive)

        ds = None
        chmod_safe = True

        try:
            poolname, dsname, rest = self.dispatcher.call_sync('volume.decode_path', path)
            ds = self.dispatcher.call_sync('volume.dataset.query', [('id', '=', dsname)], {'single': True})
            chmod_safe = ds['permissions_type'] == 'PERM'
        except RpcException:
            pass

        if permissions.get('modes'):
            modes = permissions['modes']
            if modes.get('value'):
                modes = int(modes['value'])
            else:
                modes = modes_to_oct(modes)

            try:
                bsd.lchmod(path, modes, recursive)
            except OSError as err:
                if err.errno == errno.EPERM:
                    if chmod_safe:
                        self.add_warning(TaskWarning(err.errno, 'chmod() failed: {0}'.format(err.strerror)))
                else:
                    raise TaskException(err.errno, 'chmod() failed: {0}'.format(err.strerror))

        if permissions.get('acl'):
            a = acl.ACL()
            a.__setstate__(permissions['acl'])
            a.apply(path)
            if not recursive:
                return

            # Build second ACL, but with inherits removed. It will be applied on files
            b = acl.ACL()
            b.__setstate__(permissions['acl'])
            for i in b.entries:
                i.flags[acl.NFS4Flag.DIRECTORY_INHERIT] = False
                i.flags[acl.NFS4Flag.FILE_INHERIT] = False

            for root, dirs, files in os.walk(path):
                for n in files:
                    b.apply(file=os.path.join(root, n))

                for n in dirs:
                    a.apply(file=os.path.join(root, n))

        if ds:
            self.dispatcher.dispatch_event('zfs.dataset.changed', {
                'operation': 'update',
                'ids': [ds['id']]
            })

        self.dispatcher.dispatch_event('file.permissions.changed', {
            'path': path,
            'recursive': recursive,
            'permissions': permissions
        })