[23633] in Source-Commits
Re: /svn/athena r23260 - in trunk/debathena/debathena/pyhesiodfs:
daemon@ATHENA.MIT.EDU (Evan Broder)
Mon Dec 22 14:34:10 2008
Message-ID: <494FEBA9.3060406@mit.edu>
Date: Mon, 22 Dec 2008 13:34:01 -0600
From: Evan Broder <broder@MIT.EDU>
MIME-Version: 1.0
To: broder@mit.edu
CC: source-commits@mit.edu
In-Reply-To: <200812221927.OAA19960@drugstore.mit.edu>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
I mentioned this on zephyr, but I would recommend against uploading this
to the live repo for now. I wanted to commit it so people could look
over the changes, and I believe that they work, but I want this package
to sit in the beta repo for a while before making it live.
- Evan
broder@MIT.EDU wrote:
> 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
>
>