[23632] in Source-Commits
/svn/athena r23260 - in trunk/debathena/debathena/pyhesiodfs: . debian debian/patches
daemon@ATHENA.MIT.EDU (broder@MIT.EDU)
Mon Dec 22 14:28:02 2008
Date: Mon, 22 Dec 2008 14:27:40 -0500 (EST)
From: broder@MIT.EDU
Message-Id: <200812221927.OAA19960@drugstore.mit.edu>
To: source-commits@MIT.EDU
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Author: broder
Date: 2008-12-22 14:27:39 -0500 (Mon, 22 Dec 2008)
New Revision: 23260
Modified:
trunk/debathena/debathena/pyhesiodfs/debian/changelog
trunk/debathena/debathena/pyhesiodfs/debian/patches/install-script-without-extension.patch
trunk/debathena/debathena/pyhesiodfs/debian/patches/no-hello.patch
trunk/debathena/debathena/pyhesiodfs/pyHesiodFS.py
Log:
Pull new pyHesiodFS that includes per-user caches and the ability to
manually remove and create symlinks.
Modified: trunk/debathena/debathena/pyhesiodfs/debian/changelog
===================================================================
--- trunk/debathena/debathena/pyhesiodfs/debian/changelog 2008-12-19 16:09:25 UTC (rev 23259)
+++ trunk/debathena/debathena/pyhesiodfs/debian/changelog 2008-12-22 19:27:39 UTC (rev 23260)
@@ -1,3 +1,9 @@
+debathena-pyhesiodfs (0.0.r162-0debathena1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Evan Broder <broder@mit.edu> Mon, 22 Dec 2008 14:03:14 -0500
+
debathena-pyhesiodfs (0.0.r157-0debathena2) unstable; urgency=low
* Rebuild with new version of python-hesiod
Modified: trunk/debathena/debathena/pyhesiodfs/debian/patches/install-script-without-extension.patch
===================================================================
--- trunk/debathena/debathena/pyhesiodfs/debian/patches/install-script-without-extension.patch 2008-12-19 16:09:25 UTC (rev 23259)
+++ trunk/debathena/debathena/pyhesiodfs/debian/patches/install-script-without-extension.patch 2008-12-22 19:27:39 UTC (rev 23260)
@@ -1,8 +1,9 @@
-Index: debathena-pyhesiodfs/setup.py
+Index: debathena-pyhesiodfs-0.0.r162/setup.py
===================================================================
---- debathena-pyhesiodfs.orig/setup.py
-+++ debathena-pyhesiodfs/setup.py
-@@ -11,5 +11,5 @@
+--- debathena-pyhesiodfs-0.0.r162.orig/setup.py 2008-12-22 13:53:01.000000000 -0500
++++ debathena-pyhesiodfs-0.0.r162/setup.py 2008-12-22 14:18:33.000000000 -0500
+@@ -10,6 +10,6 @@
+ version='1.0',
author='Quentin Smith',
author_email='pyhesiodfs@mit.edu',
- scripts=['pyHesiodFS.py'],
Modified: trunk/debathena/debathena/pyhesiodfs/debian/patches/no-hello.patch
===================================================================
--- trunk/debathena/debathena/pyhesiodfs/debian/patches/no-hello.patch 2008-12-19 16:09:25 UTC (rev 23259)
+++ trunk/debathena/debathena/pyhesiodfs/debian/patches/no-hello.patch 2008-12-22 19:27:39 UTC (rev 23260)
@@ -1,9 +1,9 @@
-Index: debathena-pyhesiodfs-0.0.r157/pyHesiodFS.py
+Index: debathena-pyhesiodfs-0.0.r162/pyHesiodFS.py
===================================================================
---- debathena-pyhesiodfs-0.0.r157.orig/pyHesiodFS.py 2008-11-11 14:20:55.000000000 -0500
-+++ debathena-pyhesiodfs-0.0.r157/pyHesiodFS.py 2008-11-11 14:21:15.000000000 -0500
-@@ -20,13 +20,6 @@
+--- debathena-pyhesiodfs-0.0.r162.orig/pyHesiodFS.py 2008-12-22 13:53:01.000000000 -0500
++++ debathena-pyhesiodfs-0.0.r162/pyHesiodFS.py 2008-12-22 14:20:36.000000000 -0500
+@@ -69,13 +69,6 @@
fuse.fuse_python_api = (0, 2)
@@ -17,18 +17,18 @@
if not hasattr(fuse, 'Stat'):
fuse.Stat = object
-@@ -72,10 +65,6 @@
+@@ -128,10 +121,6 @@
if path == '/':
- st.st_mode = stat.S_IFDIR | 0755
+ st.st_mode = stat.S_IFDIR | 0777
st.st_nlink = 2
- elif path == hello_path:
- st.st_mode = stat.S_IFREG | 0444
- st.st_nlink = 1
- st.st_size = len(hello_str)
elif '/' not in path[1:]:
- if self.findLocker(path[1:]):
+ if path[1:] not in self.negcache and self.findLocker(path[1:]):
st.st_mode = stat.S_IFLNK | 0777
-@@ -121,7 +110,7 @@
+@@ -178,7 +167,7 @@
return None
def getdir(self, path):
@@ -37,7 +37,7 @@
def readdir(self, path, offset):
for (r, zero) in self.getdir(path):
-@@ -130,27 +119,7 @@
+@@ -187,27 +176,8 @@
def readlink(self, path):
return self.findLocker(path[1:])
@@ -59,13 +59,31 @@
- else:
- buf = ''
- return buf
--
+-
+ def symlink(self, src, path):
+- if path == '/' or path == hello_path:
++ if path == '/':
+ return -errno.EPERM
+ elif '/' not in path[1:]:
+ self.mounts[self._user()][path[1:]] = src
+@@ -217,7 +187,7 @@
+ return -errno.EPERM
+
+ def unlink(self, path):
+- if path == '/' or path == hello_path:
++ if path == '/':
+ return -errno.EPERM
+ elif '/' not in path[1:]:
+ del self.mounts[self._user()][path[1:]]
+@@ -226,7 +196,6 @@
+ return -errno.EPERM
+
def main():
- global hello_str
try:
usage = Fuse.fusage
server = PyHesiodFS(version="%prog " + fuse.__version__,
-@@ -166,7 +135,6 @@
+@@ -242,7 +211,6 @@
sys.argv.pop(1)
server = PyHesiodFS()
Modified: trunk/debathena/debathena/pyhesiodfs/pyHesiodFS.py
===================================================================
--- trunk/debathena/debathena/pyhesiodfs/pyHesiodFS.py 2008-12-19 16:09:25 UTC (rev 23259)
+++ trunk/debathena/debathena/pyhesiodfs/pyHesiodFS.py 2008-12-22 19:27:39 UTC (rev 23260)
@@ -9,13 +9,62 @@
# See the file COPYING.
#
-import sys, os, stat, errno
+import sys, os, stat, errno, time
from syslog import *
import fuse
from fuse import Fuse
import hesiod
+try:
+ from collections import defaultdict
+except ImportError:
+ class defaultdict(dict):
+ """
+ A dictionary that automatically will fill in keys that don't exist
+ with the result from some default value factory
+
+ Based on the collections.defaultdict object in Python 2.5
+ """
+
+ def __init__(self, default_factory):
+ self.default_factory = default_factory
+ super(defaultdict, self).__init__()
+
+ def __getitem__(self, y):
+ if y not in self:
+ self[y] = self.default_factory()
+ return super(defaultdict, self).__getitem__(y)
+
+ def __str__(self):
+ print 'defaultdict(%s, %s)' % (self.default_factory,
+ super(defaultdict, self).__str__())
+
+class negcache(dict):
+ """
+ A set-like object that automatically expunges entries after
+ they're been there for a certain amount of time.
+
+ This only supports add, remove, and __contains__
+ """
+
+ def __init__(self, cache_time):
+ self.cache_time = cache_time
+
+ def add(self, obj):
+ self[obj] = time.time()
+
+ def remove(self, obj):
+ del self[obj]
+
+ def __contains__(self, k):
+ if super(negcache, self).__contains__(k):
+ if self[k] + self.cache_time > time.time():
+ return True
+ else:
+ del self[k]
+ return False
+
new_fuse = hasattr(fuse, '__version__')
fuse.fuse_python_api = (0, 2)
@@ -65,20 +114,28 @@
self.fuse_args.add("noapplexattr", True)
self.fuse_args.add("volname", "MIT")
self.fuse_args.add("fsname", "pyHesiodFS")
- self.mounts = {}
+ self.mounts = defaultdict(dict)
+
+ # Cache deletions for 10 seconds - should give people time to
+ # make a new symlink
+ self.negcache = negcache(10)
+ def _user(self):
+ return fuse.FuseGetContext()['uid']
+
def getattr(self, path):
st = MyStat()
if path == '/':
- st.st_mode = stat.S_IFDIR | 0755
+ st.st_mode = stat.S_IFDIR | 0777
st.st_nlink = 2
elif path == hello_path:
st.st_mode = stat.S_IFREG | 0444
st.st_nlink = 1
st.st_size = len(hello_str)
elif '/' not in path[1:]:
- if self.findLocker(path[1:]):
+ if path[1:] not in self.negcache and self.findLocker(path[1:]):
st.st_mode = stat.S_IFLNK | 0777
+ st.st_uid = self._user()
st.st_nlink = 1
st.st_size = len(self.findLocker(path[1:]))
else:
@@ -91,12 +148,12 @@
return st.toTuple()
def getCachedLockers(self):
- return self.mounts.keys()
+ return self.mounts[self._user()].keys()
def findLocker(self, name):
"""Lookup a locker in hesiod and return its path"""
- if name in self.mounts:
- return self.mounts[name]
+ if name in self.mounts[self._user()]:
+ return self.mounts[self._user()][name]
else:
try:
filsys = hesiod.FilsysLookup(name)
@@ -113,7 +170,7 @@
syslog(LOG_NOTICE, "Unknown locker type "+pointer['type']+" for locker "+name+" ("+repr(pointer)+" )")
return None
else:
- self.mounts[name] = pointer['location']
+ self.mounts[self._user()][name] = pointer['location']
syslog(LOG_INFO, "Mounting "+name+" on "+pointer['location'])
return pointer['location']
else:
@@ -148,6 +205,25 @@
else:
buf = ''
return buf
+
+ def symlink(self, src, path):
+ if path == '/' or path == hello_path:
+ return -errno.EPERM
+ elif '/' not in path[1:]:
+ self.mounts[self._user()][path[1:]] = src
+ self.negcache.remove(path[1:])
+ print self.mounts[self._user()]
+ else:
+ return -errno.EPERM
+
+ def unlink(self, path):
+ if path == '/' or path == hello_path:
+ return -errno.EPERM
+ elif '/' not in path[1:]:
+ del self.mounts[self._user()][path[1:]]
+ self.negcache.add(path[1:])
+ else:
+ return -errno.EPERM
def main():
global hello_str