Skip to content

Instantly share code, notes, and snippets.

@brianv0
Created February 19, 2015 22:46
Show Gist options
  • Save brianv0/08795ebf2018035840f7 to your computer and use it in GitHub Desktop.
Save brianv0/08795ebf2018035840f7 to your computer and use it in GitHub Desktop.
FUSE example for datacatalog
#!/usr/bin/env python
from __future__ import with_statement
import os
import sys
import errno
import requests
import json
from fuse import FUSE, FuseOSError, Operations
from stat import S_IFDIR, S_IFLNK, S_IFREG
baseurl = 'http://srs.slac.stanford.edu/datacat-v0.2/r'
pathurl = '%s/path' %baseurl
class Passthrough(Operations):
sess = requests.Session()
cache = {}
def __init__(self, root):
self.root = root
def getURL(self, base, path):
fp = "%s%s%s" %(base, self.root, path)
return fp
# Filesystem methods
# ==================
def access(self, path, mode):
print "path", self.root + path, mode
fp = self.getURL(pathurl, path)
if fp not in self.cache:
r = self.sess.get(fp)
if self.cache[fp] == 404:
self.cache[fp] = r.status_code
else:
self.cache[fp] = r.content
if self.cache[fp] == 404:
return -1
def chmod(self, path, mode):
print "chmod"
raise FuseOSError(errno.EACCES)
def chown(self, path, uid, gid):
print "chow", path
raise FuseOSError(errno.EACCES)
opened = False
def getattr(self, path, fh=None):
fp = self.getURL(pathurl, path)
print "getattr: " + fp
print self.opened
if fp == "http://localhost:8080/rest-datacat-v1/r/path/Data/something.txt?site=SLAC":
if self.opened:
print "created"
mode = (S_IFREG | 0777)
size = 0
return dict({'st_ctime': 1287441132.0, 'st_mtime': 1287441132.0, 'st_nlink': 1, 'st_mode': mode, 'st_size': size, 'st_gid': 501, 'st_uid': 501, 'st_atime': 1287441132.0})
if fp not in self.cache:
r = self.sess.get(fp, headers={"accept":"application/json"})
if r.status_code == 404:
self.cache[fp] = 404
else:
self.cache[fp] = r.content
if self.cache[fp] == 404:
raise FuseOSError(errno.ENOENT)
dat = json.loads(self.cache[fp])
size = 0
mode = (S_IFDIR | 0777)
return dict({'st_ctime': 1287441132.0, 'st_mtime': 1287441132.0, 'st_nlink': 1, 'st_mode': mode, 'st_size': size, 'st_gid': 501, 'st_uid': 501, 'st_atime': 1287441132.0})
def readdir(self, path, fh):
fp = self.getURL(pathurl, path)
print "readdir " + fp
r = self.sess.get(fp, headers={"accept":"application/json"})
dat = json.loads(r.content)
dirents = ['.', '..']
if dat['_type'] in ('group','folder'):
r = self.sess.get(self.getURL(pathurl, path) + ";children", headers={"accept":"application/json"})
dat = json.loads(r.content)
for i in dat:
dirents.append(i['name'])
self.cache[self.getURL(pathurl, path + "/" + i['name'])] = json.dumps(i)
for r in dirents:
yield r
def readlink(self, path):
print "readlink", path
return path
def mknod(self, path, mode, dev):
print "mknod", path
raise FuseOSError(errno.EACCES)
def rmdir(self, path):
print "rmdir"
raise FuseOSError(errno.EACCES)
def mkdir(self, path, mode):
print "mkdir: " + path
raise FuseOSError(errno.EACCES)
def _xattr(self, path):
self.access(path, "READ")
fp = self.getURL(pathurl, path)
obj = json.loads(self.cache[fp])
if 'metadata' in obj:
return {i["key"]:str(i["value"]) for i in obj['metadata']}
return {}
def getxattr(self, path, name, position=0):
md = self._xattr(path)
return md.get(name,'')
def listxattr(self, path):
md = self._xattr(path)
if md:
return md.keys()
return []
def statfs(self, path):
print "statfs: " + self.getURL(pathurl, path)
"""Returns a dictionary with keys identical to the statvfs C
structure of statvfs(3).
The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
On Mac OS X f_bsize and f_frsize must be a power of 2
(minimum 512)."""
return {
"f_namemax" : 512,
"f_bsize" : 1024 * 1024,
"f_blocks" : 1024 * 1024 * 1024,
"f_bfree" : 1024 * 1024 * 1024,
"f_bavail" : 1024 * 1024 * 1024,
"f_files" : 1024 * 1024 * 1024,
"f_favail" : 1024 * 1024 * 1024,
"f_ffree" : 1024 * 1024 * 1024,
"f_frsize" : 512
}
def unlink(self, path):
print "unlink", path
raise FuseOSError(errno.EACCES)
def symlink(self, target, name):
print "symlink"
raise FuseOSError(errno.EACCES)
def rename(self, old, new):
raise FuseOSError(errno.EACCES)
def link(self, target, name):
print "link"
raise FuseOSError(errno.EACCES)
def utimens(self, path, times=None):
print "utimens"
raise FuseOSError(errno.EACCES)
# File methods
# ============
new = None
def open(self, path, flags):
print "open: " + path
"""full_path = self._full_path(path)
return os.open(full_path, flags)"""
raise FuseOSError(errno.EACCES)
i = 4
def create(self, path, mode, fi=None):
self.opened = True
print "create: " + path
self.new = open("something.new","w+b")
return 4
"""full_path = self._full_path(path)
return os.open(full_path, os.O_WRONLY | os.O_CREAT, mode)"""
raise FuseOSError(errno.EACCES)
def read(self, path, length, offset, fh):
"""os.lseek(fh, offset, os.SEEK_SET)
return os.read(fh, length)"""
raise FuseOSError(errno.EACCES)
def write(self, path, buf, offset, fh):
"""os.lseek(fh, offset, os.SEEK_SET)
return os.write(fh, buf)"""
raise FuseOSError(errno.EACCES)
def truncate(self, path, length, fh=None):
"""full_path = self._full_path(path)
with open(full_path, 'r+') as f:
f.truncate(length)"""
raise FuseOSError(errno.EACCES)
def flush(self, path, fh):
#return os.fsync(fh)
raise FuseOSError(errno.EACCES)
def release(self, path, fh):
print "release", path
#return os.close(fh)
return 0
def fsync(self, path, fdatasync, fh):
print "fsync", path
#return self.flush(path, fh)
raise FuseOSError(errno.EACCES)
def main(mountpoint, root):
FUSE(Passthrough(root), mountpoint, foreground=True, default_permissions=True, allow_other=True, atime=False, auto_cache=True, noappledouble=True)
if __name__ == '__main__':
main(sys.argv[2], sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment