def set_read_only(path, read_only): """Sets or resets the write bit on a file or directory. Zaps out access to 'group' and 'others'. """ mode = fs.lstat(path).st_mode # TODO(maruel): Stop removing GO bits. mode = (mode & 0500) if read_only else (mode | 0200) if hasattr(os, 'lchmod'): fs.lchmod(path, mode) # pylint: disable=E1101 else: if stat.S_ISLNK(mode): # Skip symlink without lchmod() support. logging.debug('Can\'t change %sw bit on symlink %s', '-' if read_only else '+', path) return # TODO(maruel): Implement proper DACL modification on Windows. fs.chmod(path, mode)
def set_read_only(path, read_only): """Sets or resets the write bit on a file or directory. Zaps out access to 'group' and 'others'. """ mode = fs.lstat(path).st_mode # TODO(maruel): Stop removing GO bits. mode = (mode & 0500) if read_only else (mode | 0200) if hasattr(os, 'lchmod'): fs.lchmod(path, mode) # pylint: disable=E1101 else: if stat.S_ISLNK(mode): # Skip symlink without lchmod() support. logging.debug( 'Can\'t change %sw bit on symlink %s', '-' if read_only else '+', path) return # TODO(maruel): Implement proper DACL modification on Windows. fs.chmod(path, mode)
def set_read_only(path, read_only): """Sets or resets the write bit on a file or directory. Zaps out access to 'group' and 'others'. """ mode = fs.lstat(path).st_mode # TODO(maruel): Stop removing GO bits. if read_only: mode &= stat.S_IRUSR | stat.S_IXUSR # 0500 else: mode |= stat.S_IRUSR | stat.S_IWUSR # 0600 if sys.platform != 'win32' and stat.S_ISDIR(mode): mode |= stat.S_IXUSR # 0100 if hasattr(os, 'lchmod'): fs.lchmod(path, mode) # pylint: disable=E1101 else: if stat.S_ISLNK(mode): # Skip symlink without lchmod() support. return # TODO(maruel): Implement proper DACL modification on Windows. fs.chmod(path, mode)
def cleanup(self): """Cleans up the cache directory. Ensures there is no unknown files in cache_dir. Ensures the read-only bits are set correctly. At that point, the cache was already loaded, trimmed to respect cache policies. """ with self._lock: fs.chmod(self.cache_dir, 0o700) # Ensure that all files listed in the state still exist and add new ones. previous = set(self._lru) # It'd be faster if there were a readdir() function. for filename in fs.listdir(self.cache_dir): if filename == self.STATE_FILE: fs.chmod(os.path.join(self.cache_dir, filename), 0o600) continue if filename in previous: fs.chmod(os.path.join(self.cache_dir, filename), 0o400) previous.remove(filename) continue # An untracked file. Delete it. logging.warning('Removing unknown file %s from cache', filename) p = self._path(filename) if fs.isdir(p): try: file_path.rmtree(p) except OSError: pass else: file_path.try_remove(p) continue if previous: # Filter out entries that were not found. logging.warning('Removed %d lost files', len(previous)) for filename in previous: self._lru.pop(filename) self._save()
def readable_copy(outfile, infile): """Makes a copy of the file that is readable by everyone.""" fs.copy2(infile, outfile) fs.chmod( outfile, fs.stat(outfile).st_mode | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
def cleanup(self): """Cleans up the cache directory. Ensures there is no unknown files in cache_dir. Ensures the read-only bits are set correctly. At that point, the cache was already loaded, trimmed to respect cache policies. """ with self._lock: fs.chmod(self.cache_dir, 0o700) # Ensure that all files listed in the state still exist and add new ones. previous = set(self._lru) # It'd be faster if there were a readdir() function. for filename in fs.listdir(self.cache_dir): if filename == self.STATE_FILE: fs.chmod(os.path.join(self.cache_dir, filename), 0o600) continue if filename in previous: fs.chmod(os.path.join(self.cache_dir, filename), 0o400) previous.remove(filename) continue # An untracked file. Delete it. logging.warning('Removing unknown file %s from cache', filename) p = self._path(filename) if fs.isdir(p): try: file_path.rmtree(p) except OSError: pass else: file_path.try_remove(p) continue if previous: # Filter out entries that were not found. logging.warning('Removed %d lost files', len(previous)) for filename in previous: self._lru.pop(filename) self._save() # Verify hash of every single item to detect corruption. the corrupted # files will be evicted. with self._lock: for digest, (_, timestamp) in list(self._lru._items.items()): # verify only if the mtime is grather than the timestamp in state.json # to avoid take too long time. if self._get_mtime(digest) <= timestamp: continue logging.warning('Item has been modified. item: %s', digest) if self._is_valid_hash(digest): # Update timestamp in state.json self._lru.touch(digest) continue # remove corrupted file from LRU and file system self._lru.pop(digest) self._delete_file(digest, UNKNOWN_FILE_SIZE) logging.error('Deleted corrupted item: %s', digest) self._save()