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 })
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: try: b.apply(file=os.path.join(root, n)) except OSError: pass for n in dirs: try: a.apply(file=os.path.join(root, n)) except OSError: pass 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 })
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 })