import errno # for error number codes (ENOENT, etc)
# - note: these must be returned as negatives
+import sipb_xen_database
+
fuse.fuse_python_api = (0, 2)
-machines = ['moo17', 'remus']
realpath = "/home/machines/"
-uid = 1000
def dirFromList(list):
"""
self.st_ino = 0
self.st_dev = 0
self.st_nlink = 0
- self.st_uid = uid
+ self.st_uid = 0
self.st_gid = 0
self.st_size = 0
self.st_atime = 0
def __init__(self, *args, **kw):
Fuse.__init__(self, *args, **kw)
+ self.lasttime = time()
+ self.allow_other = 1
print 'Init complete.'
def mirrorPath(self, path):
return realpath + "/".join(getParts(path)[1:])
+ def getMachines(self):
+ if time() - self.lasttime > 15:
+ self.lasttime = time()
+ sipb_xen_database.clear_cache()
+ return [machine.name for machine in sipb_xen_database.Machine.select()]
+
+ def getUid(self, machine_name):
+ return sipb_xen_database.Machine.get_by(name=machine_name).machine_id + 1000
+
+ def getK5login(self, machine_name):
+ machine = sipb_xen_database.Machine.get_by(name=machine_name)
+ users = [acl.user for acl in machine.acl]
+ return "\n".join(map(self.userToPrinc, users) + [''])
+
+ def userToPrinc(self, user):
+ if '@' in user:
+ (princ, realm) = user.split('@')
+ else:
+ princ = user
+ realm = "ATHENA.MIT.EDU"
+
+ return princ.replace('.', '/') + '@' + realm
+
def getattr(self, path):
"""
- st_mode (protection bits)
st.st_mode = stat.S_IFDIR | 0755
st.st_nlink = 2
elif depth == 1:
- if parts[-1] in machines:
+ if parts[-1] in self.getMachines():
st.st_mode = stat.S_IFDIR | 0755
st.st_nlink = 2
+ st.st_uid = st.st_gid = self.getUid(parts[0])
else:
return -errno.ENOENT
elif depth == 2 and parts[-1] == '.k5login':
st.st_mode = stat.S_IFREG | 0444
st.st_nlink = 1
- st.st_size = 17
+ st.st_size = len(self.getK5login(parts[0]))
+ st.st_uid = st.st_gid = self.getUid(parts[0])
else:
- st = os.lstat(self.mirrorPath(path))
+ stats = list(os.lstat(self.mirrorPath(path)))
+ stats[4:6] = [self.getUid(parts[0])] * 2
+ return tuple(stats)
return st.toTuple()
def readdir(self, path, offset):
print '*** readdir', path, offset
+ for (value, zero) in self.getdir(path):
+ yield fuse.Direntry(value)
+
+ def getdir(self, path):
+ print '*** getdir', path
if path == '/':
- for r in ['.', '..']+machines:
- yield fuse.Direntry(r)
+ contents = ['.', '..']+self.getMachines()
elif getDepth(path) == 1:
- for r in set(os.listdir(self.mirrorPath(path)) + ['.k5login']):
- yield fuse.Direntry(r)
+ contents = set(os.listdir(self.mirrorPath(path)) + ['.k5login', '.', '..'])
else:
- for r in os.listdir(self.mirrorPath(path)):
- yield fuse.Direntry(r)
+ contents = os.listdir(self.mirrorPath(path)) + ['.', '..']
+ return [(i, 0) for i in contents]
def read ( self, path, length, offset ):
print '*** read', path, length, offset
+ parts = getParts(path)
+
if getDepth(path) < 2:
return -errno.ENOENT
- elif getParts(path)[1:] == ['.k5login']:
- pass
+ elif parts[1:] == ['.k5login']:
+ if parts[0] not in self.getMachines():
+ return -errno.ENOENT
+ else:
+ return self.getK5login(parts[0])[offset:length + offset]
else:
fname = self.mirrorPath(path)
if not os.path.isfile(fname):
return f.read(length)
if __name__ == '__main__':
+ sipb_xen_database.connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
usage="""
ConsoleFS [mount_path]
"""