Beispiel #1
0
    def truncate(self, path, length, fh=None):
        logging.debug("truncate: %s", repr((path, length, fh)))

        f = None

        if fh == None:
            #print ("  closed file")
            src_path = self.getSource(path)

            if not os.path.exists(src_path):
                raise fuse.FuseOSError(errno.ENOENT)

            if os.path.isdir(src_path):
                raise fuse.FuseOSError(errno.EISDIR)

            f = File(src_path, False)
        else:
            #print ("  file handle ", fh)
            if fh not in self.file_handles:
                raise fuse.FuseOSError(errno.ENOENT)

            f = self.file[fh]
            if f.is_dir:
                raise fuse.FuseOSError(errno.EISDIR)

        self.copyOnWrite(f)
        #print ("truncate file ", repr (f.src_path))
        os.truncate(f.src_path, length)
Beispiel #2
0
    def Read(self, path, length=None, offset=0, fh=None):
        """Reads data from a file.

    Args:
      path: The path to the file to read.
      length: How many bytes to read.
      offset: Offset in bytes from which reading should start.
      fh: A file handler. Not used.

    Returns:
      A string containing the file contents requested.

    Raises:
      FuseOSError: If we try and read a directory or if we try and read an
      object that doesn't support reading.

    """
        if self._IsDir(path):
            raise fuse.FuseOSError(errno.EISDIR)

        fd = aff4.FACTORY.Open(self.root.Add(path), token=self.token)

        # If the object has Read() and Seek() methods, let's use them.
        if all((hasattr(fd, "Read"), hasattr(fd, "Seek"), callable(fd.Read),
                callable(fd.Seek))):
            # By default, read the whole file.
            if length is None:
                length = fd.Get(fd.Schema.SIZE)

            fd.Seek(offset)
            return fd.Read(length)
        else:
            # If we don't have Read/Seek methods, we probably can't read this object.
            raise fuse.FuseOSError(errno.EIO)
Beispiel #3
0
    def readdir(self, path, fh):
        self.logger.info('readdir %s', path)

        try:
            cache_entry = self.cache.get_entry(path)
        except FileNotFoundError as e:
            self.logger.error('file not found error: %s', path)
            raise fuse.FuseOSError(errno.ENOENT)

        if cache_entry.metadata['is_dir'] is False:
            self.logger.error('%s not a directory', path)
            raise fuse.FuseOSError(errno.ENOTDIR)

        files = ['.', '..']
        if not 'contents' in cache_entry.metadata:
            # cache entry might not be full, fetching info
            self.logger.info('setting metadata cache dirty: %s',
                             cache_entry.path)
            cache_entry.dirty = True

        for content in cache_entry.metadata['contents']:
            basename = os.path.basename(content['path'])
            files.append(basename)

        return files
Beispiel #4
0
 def open(self, path, flags):
     # Only support 'READ ONLY' flag
     access_flags = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
     fh = 0
     if flags & access_flags != os.O_RDONLY:
         raise fuse.FuseOSError(errno.EACCES)
     else:
         cur_path, hide_raw = self.get_path(path)
         if len(cur_path) == 6:
             uid, gid, pid = fuse.fuse_get_context()
             username = self.get_username(uid)
             files = get_datasets(username, cur_path[1], cur_path[2],
                                  cur_path[3], cur_path[4], self.datapath,
                                  hide_raw)
             fname = next((f[1] for f in files if f[0] == cur_path[5]),
                          None)
             if fname:
                 self.gzfile = None
                 fh = os.open(fname, flags)
             elif cur_path[5].endswith('ugz'):
                 # Check to see if we're being asked about a gzipped file
                 fn = cur_path[5][:-3] + 'gz'
                 fname = next((f[1] for f in files if f[0] == fn), None)
                 if fname:
                     self.gzfile = gzip.open(fname, 'r')
                     fh = self.gzfile.fileno()
                 else:
                     raise fuse.FuseOSError(errno.ENOENT)
             else:
                 raise fuse.FuseOSError(errno.ENOENT)
         elif len(cur_path) == 2 and cur_path[1] == 'README.txt':
             fh = os.open(self.readme_fname, flags)
     return fh
Beispiel #5
0
    def open(self, path, flags):
        flags = 32768 - flags
        self.logger.info('open %s %d', path, flags)

        if flags == os.O_RDWR:
            self.logger.info('invalid flags: O_RDWR')
            raise fuse.FuseOSError(errno.EINVAL)

        if flags == os.O_WRONLY:
            # if it O_WRONLY, let self.create do its thing
            self.logger.info('valid flags: O_WRONLY')
            return self.create(path, 0444)
        elif flags != os.O_RDONLY:
            # if there is no O_WRONLY / O_RD_ONLY
            self.logger.error('invalid flags: not O_RDONLY or O_WRONLY')
            raise fuse.FuseOSError(errno.EINVAL)

        # in case of O_RDONLY
        self.logger.info('valid flags: O_RDONLY')
        try:
            cache_entry = self.cache.get_entry(path, self.client)
        except FileNotFoundError as e:
            self.logger.error('file not found error: %s', path)
            raise fuse.FuseOSError(errno.ENOENT)

        try:
            fd = self.download_manager.open_file(path)
            self.cache.set_entry(path, cache_entry)
            return fd
        except Exception as e:
            self.logger.error('WTFF: %s', str(e))
            raise fuse.FuseOSError(errno.EACCES)
Beispiel #6
0
Datei: fs.py Projekt: jd/ki
 def chmod(self, path, mode):
     try:
         self.box.root[path] = (mode, self.box.root[path].item)
     except NotDirectory:
         raise fuse.FuseOSError(errno.ENOTDIR)
     except NoChild:
         raise fuse.FuseOSError(errno.ENOENT)
Beispiel #7
0
    def _getPath(self, path):
        """
        Given a fuse path, return the associated resource.

        :param path: path within the fuse.
        :returns: a Girder resource dictionary.
        """
        # If asked about a file in top level directory or the top directory,
        # return that it doesn't exist.  Other methods should handle '',
        # '/user', and 'collection' before calling this method.
        if '/' not in path.rstrip('/')[1:]:
            raise fuse.FuseOSError(errno.ENOENT)
        try:
            # We can't filter the resource, since that removes files'
            # assetstore information and users' size information.
            resource = path_util.lookUpPath(path.rstrip('/'),
                                            filter=False,
                                            force=True)
        except (path_util.NotFoundException, AccessException):
            raise fuse.FuseOSError(errno.ENOENT)
        except ValidationException:
            raise fuse.FuseOSError(errno.EROFS)
        except Exception:
            logger.exception('ServerFuse server internal error')
            raise fuse.FuseOSError(errno.EROFS)
        return resource  # {model, document}
Beispiel #8
0
 def getattr(self, path, fh=None):
     uid, gid, pid = fuse.fuse_get_context()
     if fh:
         fs = os.fstat(fh)
         at = fs.st_atime
         ct = fs.st_ctime
         mt = fs.st_mtime
         sz = fs.st_size
         mode = stat.S_IFREG | 0444
         nlink = 1
         # TODO: get the uncompressed size for gzip files.
     else:
         fn = path.split('/')[-1]
         is_dir = '%' in fn or not bool(os.path.splitext(fn)[1])
         at = ct = mt = int(time.time())
         if is_dir:
             sz = 0
             mode = stat.S_IFDIR | 0555
             nlink = 2
         else:
             mode = stat.S_IFREG | 0444
             nlink = 1
             username = self.get_username(uid)
             cur_path, hide_raw = self.get_path(path)
             sz = 1
             if len(cur_path) == 6:
                 files = get_datasets(username, cur_path[1], cur_path[2],
                                      cur_path[3], cur_path[4],
                                      self.datapath, hide_raw)
                 fname = next((f[1] for f in files if f[0] == cur_path[5]),
                              None)
                 if fname:
                     sz = os.path.getsize(fname)
                     ts = os.path.getmtime(fname)
                 elif cur_path[5].endswith('ugz'):
                     # Check to see if we're being asked about a gzipped file
                     fn = cur_path[5][:-3] + 'gz'
                     fname = next((f[1] for f in files if f[0] == fn), None)
                     if fname:
                         ts = os.path.getmtime(fname)
                         # Apparently there's no way to get the uncompressed size except by reading the last four bytes.
                         # TODO: consider saving this (as well as the timestamp) in the db.
                         with open(fname, 'r') as fp:
                             fp.seek(-4, 2)
                             sz = struct.unpack('<I', fp.read())[0]
                     else:
                         raise fuse.FuseOSError(errno.ENOENT)
                 else:
                     raise fuse.FuseOSError(errno.ENOENT)
     return {
         'st_atime': at,
         'st_ctime': ct,
         'st_gid': gid,
         'st_mode': mode,
         'st_mtime': mt,
         'st_nlink': nlink,
         'st_size': sz,
         'st_uid': uid
     }
Beispiel #9
0
	def read(self, path, size, offset, fh):
		f = self.traverse(path)
		if f is None:
			raise fuse.FuseOSError(errno.ENOENT)
		if f.dir():
			raise fuse.FuseOSError(errno.EISDIR)
		
		return f.read(size, offset)
Beispiel #10
0
Datei: fs.py Projekt: jd/ki
 def opendir(self, path):
     try:
         entry = self._get_child(path)
     except FetchError:
         raise fuse.FuseOSError(errno.EIO)
     if not isinstance(entry.item, Directory):
         raise fuse.FuseOSError(errno.ENOTDIR)
     return self.to_fd(*entry)
Beispiel #11
0
Datei: fs.py Projekt: jd/ki
 def rename(self, old, new):
     try:
         self.box.root[new] = self.box.root[old]
         del self.box.root[old]
     except NotDirectory:
         raise fuse.FuseOSError(errno.ENOTDIR)
     except NoChild:
         raise fuse.FuseOSError(errno.ENOENT)
Beispiel #12
0
	def readdir(self, path, fh):
		f = self.traverse(path)
		if f is None:
			raise fuse.FuseOSError(errno.EOENT)
		if not f.dir():
			raise fuse.FuseOSError(errno.ENOTDIR)
		
		return f.readdir()
Beispiel #13
0
 def access(self, path, amode):
     if amode & os.W_OK:
         raise fuse.FuseOSError(EACCES)
     obj = self._getpath(path)
     if not obj.exist:
         raise fuse.FuseOSError(ENOENT)
     elif (obj.stat.st_mode & amode) != amode:
         raise fuse.FuseOSError(EACCES)
     return 0
Beispiel #14
0
Datei: fs.py Projekt: jd/ki
    def _create(self, path, mode, obj):
        try:
            self.box.root[path] = (mode, obj)
        except NoChild:
            raise fuse.FuseOSError(errno.ENOENT)
        except NotDirectory:
            raise fuse.FuseOSError(errno.ENOTDIR)

        return self.to_fd(mode, obj)
Beispiel #15
0
Datei: fs.py Projekt: jd/ki
 def unlink(self, path):
     path = Path(path)
     (directory_mode, directory) = self._get_child(path[:-1])
     if not isinstance(directory, Directory):
         raise fuse.FuseOSError(errno.ENOTDIR)
     try:
         del directory[path[-1]]
     except NoChild:
         raise fuse.FuseOSError(errno.ENOENT)
Beispiel #16
0
Datei: fs.py Projekt: jd/ki
    def open(self, path, flags):
        try:
            entry = self._get_child(path, File)
        except FetchError:
            raise fuse.FuseOSError(errno.EIO)

        if not self.box.is_writable and flags & (os.O_WRONLY | os.O_RDWR):
            raise fuse.FuseOSError(errno.EROFS)

        return self.to_fd(*entry)
Beispiel #17
0
 def getattr(self, path, fh=None):
     logger.debug("getattr path={}".format(path))
     try:
         entry = self._getPath(path)
         if entry:
             return entry.getAttr()
     except Exception as e:
         logger.exception("Error in getattr(%s)", path)
         raise fuse.FuseOSError(EHOSTUNREACH)
     raise fuse.FuseOSError(ENOENT)
Beispiel #18
0
    def access(self, path, amode):
        logging.debug("access: %s", repr((path, amode)))
        src_path = self.getSource(path)

        if not os.path.lexists(src_path):
            raise fuse.FuseOSError(errno.ENOENT)

        if os.access(src_path, amode, follow_symlinks=False):
            return 0

        raise fuse.FuseOSError(errno.EACCES)
Beispiel #19
0
    def mkdir(self, path, mode):
        if path == '/':
            raise fuse.FuseOSError(errno.EEXIST)

        _, *path = path.split('/')
        if len(path) != 1:
            raise fuse.FuseOSError(errno.EACCES)

        with self._db.cursor() as c:
            if not c.tags.new(path[0]):
                raise fuse.FuseOSError(errno.EEXIST)
Beispiel #20
0
Datei: fs.py Projekt: jd/ki
    def access(self, path, amode):
        try:
            (mode, child) = self._get_child(path)
        except FetchError as e:
            mode = e.mode

        if amode & posix.W_OK and not self.box.is_writable:
            raise fuse.FuseOSError(errno.EACCES)
        if amode & posix.X_OK:
            if not mode & stat.S_IXUSR and not mode & stat.S_IFDIR:
                raise fuse.FuseOSError(errno.EACCES)
Beispiel #21
0
Datei: fs.py Projekt: jd/ki
 def symlink(self, target, source):
     target = Path(target)
     try:
         (target_directory_mode,
          target_directory) = self._get_child(target[:-1])
     except FetchError:
         raise fuse.FuseOSError(errno.EIO)
     if not isinstance(target_directory, Directory):
         raise fuse.FuseOSError(errno.ENOTDIR)
     target_directory[target[-1]] = (stat.S_IFLNK,
                                     Symlink(self.box.storage,
                                             target=source))
Beispiel #22
0
Datei: fs.py Projekt: jd/ki
 def _get_child(self, path, cls=None):
     """Get the mode and child of path.
     Also check that child is instance of cls."""
     try:
         entry = self.box.root[path]
     except NotDirectory:
         raise fuse.FuseOSError(errno.ENOTDIR)
     except NoChild:
         raise fuse.FuseOSError(errno.ENOENT)
     if cls is not None and not isinstance(entry.item, cls):
         raise fuse.FuseOSError(errno.EINVAL)
     return entry
Beispiel #23
0
    def unlink(self, path):
        logging.debug("unlink: %s", repr(path))
        src_path = self.getSource(path)

        if not os.path.lexists(src_path):
            raise fuse.FuseOSError(errno.ENOENT)

        if not os.path.islink(src_path) and os.path.isdir(src_path):
            raise fuse.FuseOSError(errno.EISDIR)

        f = File(src_path, False)
        self.copyOnWrite(f, use_rename=True)
Beispiel #24
0
def as_node(node: Node_Like) -> 'core.Node':
    if node is None:
        raise fuse.FuseOSError(errno.ENOENT)
    elif isinstance(node, core.Node):
        return node
    elif isinstance(node, bytes) or isinstance(node, str):
        return nodetypes.BlobFile(as_bytes(node))
    elif isinstance(node, dict):
        return nodetypes.DictDir(node)
    elif util.is_iterable(node) or util.is_async_iterable(node):
        return nodetypes.GeneratorFile(node)

    raise fuse.FuseOSError(errno.EIO)
Beispiel #25
0
    def flush(self, path, fh):
        logging.debug("flush: %s", repr((path, fh)))

        if fh not in self.file_handles:
            raise fuse.FuseOSError(errno.ENOENT)

        f = self.file_handles[fh]

        if f.file == None:
            raise fuse.FuseOSError(errno.ENOENT)

        f.file.flush()
        return 0
Beispiel #26
0
 def getattr_related(self, path, subpath):
     gallery_ID, rest = split_path(subpath)
     if type(try_convert(gallery_ID)) is not int:
         raise fuse.FuseOSError(errno.ENOENT)
     ctx = {'path': path, 'ctime': now()}
     galleries = self.fetch_json(RELATED_URL.format(gallery_ID),
                                 self.json_to_galleries, ctx)
     self.fs['related'][int(gallery_ID)] = galleries
     try:
         dig(galleries, rest)
     except (KeyError, AttributeError, TypeError):
         raise fuse.FuseOSError(errno.ENOENT)
     return self.attrs[path]
Beispiel #27
0
    def symlink(self, path0, source):
        if path0 == '/':
            raise fuse.FuseOSError(errno.EEXIST)

        _, *path = path0.split('/')
        if len(path) == 1:
            with self._db.cursor() as c:
                if c.tags.exists(path[0]):
                    raise fuse.FuseOSError(errno.EEXIST)

        if source.startswith('sel:'):
            source = compile_selection(source)

            if len(path) != 1:
                raise fuse.FuseOSError(errno.EACCES)

            with self._db.cursor() as c:
                if not c.selections.new(path[0], source):
                    raise fuse.FuseOSError(errno.EEXIST)

        else:
            if len(path) == 1:
                raise fuse.FuseOSError(errno.EACCES)

            if len(path) != 2:
                raise fuse.FuseOSError(errno.ENOENT)

            source = os.path.normpath(os.path.join(path0, source))
            with self._db.cursor() as c:
                if not c.files.new(path[1], source):
                    raise fuse.FuseOSError(errno.EEXIST)

                if path[0] != '__ALL__' and not c.files.add_tag(path[1], path[0]):
                    raise fuse.FuseOSError(errno.EBUSY)
Beispiel #28
0
    def rmdir(self, path):
        if path == '/':
            raise fuse.FuseOSError(errno.EINVAL)

        _, *path = path.split('/')
        if len(path) != 1:
            raise fuse.FuseOSError(errno.ENOTDIR)

        if path[0] == '__ALL__':
            raise fuse.FuseOSError(errno.EACCES)

        with self._db.cursor() as c:
            if not c.tags.remove(path[0]):
                raise fuse.FuseOSError(errno.ENOENT)
Beispiel #29
0
 def read(self):
     req = SESSION.get(self.url, timeout=CONFIG['timeout'])
     try:
         req.raise_for_status()
     except requests.exceptions.HTTPError:
         self.stat.setmode(0o000, True)
         self.init = 2
         self._readable = False
         if req.status_code == 403:
             raise fuse.FuseOSError(EACCES)
         elif req.status_code == 404:
             self.exist = False
             raise fuse.FuseOSError(ENOENT)
         else:
             raise fuse.FuseOSError(EIO)
     lm = req.headers.get('Last-Modified')
     if lm:
         self.stat.settime(time.mktime(parsedate(lm)))
     else:
         self.stat.settime(time.time())
     try:
         cwd, listing = parse_dir(req.content)
     except Exception:
         logging.exception('failed to parse listing: ' + self.url)
         listing = []
     content = ['.', '..']
     objmap = {}
     for name, modified, size, description in listing:
         fpath = os.path.join(self.path, name)
         if name[-1] == '/':
             fileobj = Directory(self.baseurl, fpath)
             fpath = fpath.rstrip('/')
         else:
             fileobj = File(self.baseurl, fpath)
             if size is None:
                 fileobj.get_stat()
             else:
                 fileobj.stat.st_size = size
         if modified:
             fileobj.stat.settime(calendar.timegm(modified))
         else:
             fileobj.stat.settime(self.stat.st_mtime)
         fileobj.init = fileobj.init or 1
         content.append(name.rstrip('/'))
         objmap[fpath] = fileobj
     self.content = content
     self.stat.st_nlink = len(content)
     self.init = 2
     self._readable = True
     return objmap
Beispiel #30
0
    def unlink(self, path):
        if path == '/':
            raise fuse.FuseOSError(errno.EISDIR)

        _, *path = path.split('/')
        if len(path) == 1:
            raise fuse.FuseOSError(errno.EISDIR)

        if len(path) != 2:
            raise fuse.FuseOSError(errno.ENOENT)

        with self._db.cursor() as c:
            if not (c.files.remove(path[1]) if path[0] == '__ALL__' else c.files.remove_tag(path[1], path[0])):
                raise fuse.FuseOSError(errno.ENOENT)