15 from llfuse import FUSEError
17 class Directory(object):
18 def __init__(self, inode, parent):
23 def __getitem__(self, item):
24 return self.entries[item]
26 def __setitem__(self, key, item):
27 self.entries[key] = item
30 return self.entries.iterkeys()
32 def __contains__(self, k):
33 return k in self.entries
39 def __init__(self, inode, parent, reader):
45 return self.reader.size()
47 class FileHandle(object):
48 def __init__(self, fh, entry):
52 class Operations(llfuse.Operations):
54 def __init__(self, collection):
55 super(Operations, self).__init__()
56 #self.api = arvados.api('v1')
58 # dict of inodes to collection entry
62 self.root = Directory(i, i)
63 self._inodes[i] = self.root
65 for s in collection.all_streams():
67 for part in s.name().split('/'):
68 if part != '' and part != '.':
71 cwd[part] = Directory(i, cwd.inode)
72 self._inodes[i] = cwd[part]
74 for k, v in s.files().items():
76 cwd[k] = File(i, cwd.inode, v)
77 self._inodes[i] = cwd[k]
79 # dict of inode to filehandle
80 self._filehandles = {}
81 self._filehandles_lock = threading.Lock()
82 self._filehandles_counter = 1
84 def access(self, inode, mode, ctx):
87 def getattr(self, inode):
88 e = self._inodes[inode]
90 entry = llfuse.EntryAttributes()
93 entry.entry_timeout = 300
94 entry.attr_timeout = 300
96 entry.st_mode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
97 if isinstance(e, Directory):
98 entry.st_mode |= stat.S_IFDIR
100 entry.st_mode |= stat.S_IFREG
107 entry.st_size = e.size()
109 entry.st_blksize = 512
117 def lookup(self, parent_inode, name):
118 #print "lookup: parent_inode", parent_inode, "name", name
124 if parent_inode in self._inodes:
125 p = self._inodes[parent_inode]
129 inode = p[name].inode
132 return self.getattr(inode)
134 raise llfuse.FUSEError(errno.ENOENT)
136 def open(self, inode, flags):
137 if inode in self._inodes:
138 p = self._inodes[inode]
140 raise llfuse.FUSEError(errno.ENOENT)
142 self._filehandles_lock.acquire()
144 fh = self._filehandles_counter
145 self._filehandles_counter += 1
146 self._filehandles[fh] = FileHandle(fh, p)
149 self._filehandles_lock.release()
151 def read(self, fh, off, size):
152 self._filehandles_lock.acquire()
154 if fh in self._filehandles:
155 handle = self._filehandles[fh]
157 raise llfuse.FUSEError(errno.EBADF)
159 self._filehandles_lock.release()
162 return handle.entry.reader.readfrom(off, size)
164 raise llfuse.FUSEError(errno.EPIPE)
166 def release(self, fh):
167 self._filehandles_lock.acquire()
169 del self._filehandles[fh]
171 self._filehandles_lock.release()
173 def opendir(self, inode):
174 #print "opendir: inode", inode
176 if inode in self._inodes:
177 p = self._inodes[inode]
179 raise llfuse.FUSEError(errno.ENOENT)
181 self._filehandles_lock.acquire()
183 fh = self._filehandles_counter
184 self._filehandles_counter += 1
185 self._filehandles[fh] = FileHandle(fh, list(p.entries.items()))
188 self._filehandles_lock.release()
190 def readdir(self, fh, off):
191 #print "readdir: fh", fh, "off", off
193 self._filehandles_lock.acquire()
195 if fh in self._filehandles:
196 handle = self._filehandles[fh]
198 raise llfuse.FUSEError(errno.EBADF)
200 self._filehandles_lock.release()
202 #print "handle.entry", handle.entry
205 while e < len(handle.entry):
206 yield (handle.entry[e][0], self.getattr(handle.entry[e][1].inode), e+1)
209 def releasedir(self, fh):
210 self._filehandles_lock.acquire()
212 del self._filehandles[fh]
214 self._filehandles_lock.release()
216 if __name__ == '__main__':
218 parser = argparse.ArgumentParser(
219 description='Mount Keep data under the local filesystem.')
220 parser.add_argument('mountpoint', type=str,
221 help="""Mount point.""")
223 parser.add_argument('--collection', type=str, action='append',
224 help="""Collection locator""")
226 args = parser.parse_args()
229 manifest = open('/home/tetron/work/arvados/sdk/python/testdata/jlake_manifest').read()
231 operations = Operations(arvados.CollectionReader(manifest))
233 #operations = Operations(arvados.CollectionReader(arvados.Keep.get(args.collection)))
235 llfuse.init(operations, args.mountpoint, [ b'fsname=keepfuse' ])
240 llfuse.close(unmount=True)