[23633] in Source-Commits

home help back first fref pref prev next nref lref last post

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
>
>   

home help back first fref pref prev next nref lref last post