diff options
| -rw-r--r-- | README (renamed from README.nsfs) | 16 | ||||
| -rw-r--r-- | bundled_examples/hello.py | 92 | ||||
| -rw-r--r-- | bundled_examples/xmp.py | 279 | ||||
| -rw-r--r-- | find_fuse_parts.py (renamed from _find_fuse_parts.py) | 0 | ||||
| -rw-r--r-- | nsfs.py | 4 | 
5 files changed, 12 insertions, 379 deletions
@@ -4,7 +4,7 @@ Python Namespace File System  :Author:    Bryan Newbold  :Date:      July 2008 -:URL:       http://git.bryannewbold.com?p=pynsfs.git;a=summary +:URL:       http://git.bnewbold.net?p=pynsfs.git;a=summary  .. contents::  @@ -20,7 +20,7 @@ The source code can be checked out from the above URL.  Features  --------------- -An example session goes like:: +An example session (as root) goes like::      snark# ls /mnt/python/ @@ -94,22 +94,23 @@ An example session goes like::  The root directory is the global namespace; modules are available as   subdirectories and all other objects are accessible as files. Strings can -be appended to; all other "files" are readonly and return their string +be appended to; all other "files" are read-only and return their string  representation. "Files" can be deleted; "directories" can not. Hard links to  files are possible.  Requirements  --------------- -This was developed and has only been tested on FreeBSD 7.0 with Python 2.5.1  -version 0.2 of the python-fuse bindings.  +This was developed on FreeBSD 7.0 with Python 2.5.1 version 0.2 of the +python-fuse bindings. It has also been tested on Ubuntu 10.04 with Python 2.6.5 +and the "python-fuse" package.   * `FUSE Filesystem`__ installed and configured on a compatible operating system  * Recent version of Python__  * `FUSE Python Bindings`__  Once everything is installed and configured, the script can just be run -as root; no installation necessary. +as root.  __ http://fuse.sourceforge.net/  __ http://python.org @@ -148,3 +149,6 @@ CHANGELOG  July 28, 2008    First implementation +April 29, 2011 +  Minor repo cleanup + diff --git a/bundled_examples/hello.py b/bundled_examples/hello.py deleted file mode 100644 index b0775a6..0000000 --- a/bundled_examples/hello.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python - -#    Copyright (C) 2006  Andrew Straw  <strawman@astraw.com> -# -#    This program can be distributed under the terms of the GNU LGPL. -#    See the file COPYING. -# - -import os, stat, errno -# pull in some spaghetti to make this stuff work without fuse-py being installed -try: -    import _find_fuse_parts -except ImportError: -    pass -import fuse -from fuse import Fuse - - -if not hasattr(fuse, '__version__'): -    raise RuntimeError, \ -        "your fuse-py doesn't know of fuse.__version__, probably it's too old." - -fuse.fuse_python_api = (0, 2) - -hello_path = '/hello' -hello_str = 'Hello World!\n' - -class MyStat(fuse.Stat): -    def __init__(self): -        self.st_mode = 0 -        self.st_ino = 0 -        self.st_dev = 0 -        self.st_nlink = 0 -        self.st_uid = 0 -        self.st_gid = 0 -        self.st_size = 0 -        self.st_atime = 0 -        self.st_mtime = 0 -        self.st_ctime = 0 - -class HelloFS(Fuse): - -    def getattr(self, path): -        st = MyStat() -        if path == '/': -            st.st_mode = stat.S_IFDIR | 0755 -            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) -        else: -            return -errno.ENOENT -        return st - -    def readdir(self, path, offset): -        for r in  '.', '..', hello_path[1:]: -            yield fuse.Direntry(r) - -    def open(self, path, flags): -        if path != hello_path: -            return -errno.ENOENT -        accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR -        if (flags & accmode) != os.O_RDONLY: -            return -errno.EACCES - -    def read(self, path, size, offset): -        if path != hello_path: -            return -errno.ENOENT -        slen = len(hello_str) -        if offset < slen: -            if offset + size > slen: -                size = slen - offset -            buf = hello_str[offset:offset+size] -        else: -            buf = '' -        return buf - -def main(): -    usage=""" -Userspace hello example - -""" + Fuse.fusage -    server = HelloFS(version="%prog " + fuse.__version__, -                     usage=usage, -                     dash_s_do='setsingle') - -    server.parse(errex=1) -    server.main() - -if __name__ == '__main__': -    main() diff --git a/bundled_examples/xmp.py b/bundled_examples/xmp.py deleted file mode 100644 index a82c097..0000000 --- a/bundled_examples/xmp.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python - -#    Copyright (C) 2001  Jeff Epler  <jepler@unpythonic.dhs.org> -#    Copyright (C) 2006  Csaba Henk  <csaba.henk@creo.hu> -# -#    This program can be distributed under the terms of the GNU LGPL. -#    See the file COPYING. -# - -import os, sys -from errno import * -from stat import * -import fcntl -# pull in some spaghetti to make this stuff work without fuse-py being installed -try: -    import _find_fuse_parts -except ImportError: -    pass -import fuse -from fuse import Fuse - - -if not hasattr(fuse, '__version__'): -    raise RuntimeError, \ -        "your fuse-py doesn't know of fuse.__version__, probably it's too old." - -fuse.fuse_python_api = (0, 2) - -fuse.feature_assert('stateful_files', 'has_init') - - -def flag2mode(flags): -    md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'} -    m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)] - -    if flags | os.O_APPEND: -        m = m.replace('w', 'a', 1) - -    return m - - -class Xmp(Fuse): - -    def __init__(self, *args, **kw): - -        Fuse.__init__(self, *args, **kw) - -        # do stuff to set up your filesystem here, if you want -        #import thread -        #thread.start_new_thread(self.mythread, ()) -        self.root = '/' - -#    def mythread(self): -# -#        """ -#        The beauty of the FUSE python implementation is that with the python interp -#        running in foreground, you can have threads -#        """ -#        print "mythread: started" -#        while 1: -#            time.sleep(120) -#            print "mythread: ticking" - -    def getattr(self, path): -        return os.lstat("." + path) - -    def readlink(self, path): -        return os.readlink("." + path) - -    def readdir(self, path, offset): -        for e in os.listdir("." + path): -            yield fuse.Direntry(e) - -    def unlink(self, path): -        os.unlink("." + path) - -    def rmdir(self, path): -        os.rmdir("." + path) - -    def symlink(self, path, path1): -        os.symlink(path, "." + path1) - -    def rename(self, path, path1): -        os.rename("." + path, "." + path1) - -    def link(self, path, path1): -        os.link("." + path, "." + path1) - -    def chmod(self, path, mode): -        os.chmod("." + path, mode) - -    def chown(self, path, user, group): -        os.chown("." + path, user, group) - -    def truncate(self, path, len): -        f = open("." + path, "a") -        f.truncate(len) -        f.close() - -    def mknod(self, path, mode, dev): -        os.mknod("." + path, mode, dev) - -    def mkdir(self, path, mode): -        os.mkdir("." + path, mode) - -    def utime(self, path, times): -        os.utime("." + path, times) - -#    The following utimens method would do the same as the above utime method. -#    We can't make it better though as the Python stdlib doesn't know of -#    subsecond preciseness in acces/modify times. -#   -#    def utimens(self, path, ts_acc, ts_mod): -#      os.utime("." + path, (ts_acc.tv_sec, ts_mod.tv_sec)) - -    def access(self, path, mode): -        if not os.access("." + path, mode): -            return -EACCES - -#    This is how we could add stub extended attribute handlers... -#    (We can't have ones which aptly delegate requests to the underlying fs -#    because Python lacks a standard xattr interface.) -# -#    def getxattr(self, path, name, size): -#        val = name.swapcase() + '@' + path -#        if size == 0: -#            # We are asked for size of the value. -#            return len(val) -#        return val -# -#    def listxattr(self, path, size): -#        # We use the "user" namespace to please XFS utils -#        aa = ["user." + a for a in ("foo", "bar")] -#        if size == 0: -#            # We are asked for size of the attr list, ie. joint size of attrs -#            # plus null separators. -#            return len("".join(aa)) + len(aa) -#        return aa - -    def statfs(self): -        """ -        Should return an object with statvfs attributes (f_bsize, f_frsize...). -        Eg., the return value of os.statvfs() is such a thing (since py 2.2). -        If you are not reusing an existing statvfs object, start with -        fuse.StatVFS(), and define the attributes. - -        To provide usable information (ie., you want sensible df(1) -        output, you are suggested to specify the following attributes: - -            - f_bsize - preferred size of file blocks, in bytes -            - f_frsize - fundamental size of file blcoks, in bytes -                [if you have no idea, use the same as blocksize] -            - f_blocks - total number of blocks in the filesystem -            - f_bfree - number of free blocks -            - f_files - total number of file inodes -            - f_ffree - nunber of free file inodes -        """ - -        return os.statvfs(".") - -    def fsinit(self): -        os.chdir(self.root) - -    class XmpFile(object): - -        def __init__(self, path, flags, *mode): -            self.file = os.fdopen(os.open("." + path, flags, *mode), -                                  flag2mode(flags)) -            self.fd = self.file.fileno() - -        def read(self, length, offset): -            self.file.seek(offset) -            return self.file.read(length) - -        def write(self, buf, offset): -            self.file.seek(offset) -            self.file.write(buf) -            return len(buf) - -        def release(self, flags): -            self.file.close() - -        def _fflush(self): -            if 'w' in self.file.mode or 'a' in self.file.mode: -                self.file.flush() - -        def fsync(self, isfsyncfile): -            self._fflush() -            if isfsyncfile and hasattr(os, 'fdatasync'): -                os.fdatasync(self.fd) -            else: -                os.fsync(self.fd) - -        def flush(self): -            self._fflush() -            # cf. xmp_flush() in fusexmp_fh.c -            os.close(os.dup(self.fd)) - -        def fgetattr(self): -            return os.fstat(self.fd) - -        def ftruncate(self, len): -            self.file.truncate(len) - -        def lock(self, cmd, owner, **kw): -            # The code here is much rather just a demonstration of the locking -            # API than something which actually was seen to be useful. - -            # Advisory file locking is pretty messy in Unix, and the Python -            # interface to this doesn't make it better. -            # We can't do fcntl(2)/F_GETLK from Python in a platfrom independent -            # way. The following implementation *might* work under Linux.  -            # -            # if cmd == fcntl.F_GETLK: -            #     import struct -            #  -            #     lockdata = struct.pack('hhQQi', kw['l_type'], os.SEEK_SET, -            #                            kw['l_start'], kw['l_len'], kw['l_pid']) -            #     ld2 = fcntl.fcntl(self.fd, fcntl.F_GETLK, lockdata) -            #     flockfields = ('l_type', 'l_whence', 'l_start', 'l_len', 'l_pid') -            #     uld2 = struct.unpack('hhQQi', ld2) -            #     res = {} -            #     for i in xrange(len(uld2)): -            #          res[flockfields[i]] = uld2[i] -            #   -            #     return fuse.Flock(**res) - -            # Convert fcntl-ish lock parameters to Python's weird -            # lockf(3)/flock(2) medley locking API... -            op = { fcntl.F_UNLCK : fcntl.LOCK_UN, -                   fcntl.F_RDLCK : fcntl.LOCK_SH, -                   fcntl.F_WRLCK : fcntl.LOCK_EX }[kw['l_type']] -            if cmd == fcntl.F_GETLK: -                return -EOPNOTSUPP -            elif cmd == fcntl.F_SETLK: -                if op != fcntl.LOCK_UN: -                    op |= fcntl.LOCK_NB -            elif cmd == fcntl.F_SETLKW: -                pass -            else: -                return -EINVAL - -            fcntl.lockf(self.fd, op, kw['l_start'], kw['l_len']) - - -    def main(self, *a, **kw): - -        self.file_class = self.XmpFile - -        return Fuse.main(self, *a, **kw) - - -def main(): - -    usage = """ -Userspace nullfs-alike: mirror the filesystem tree from some point on. - -""" + Fuse.fusage - -    server = Xmp(version="%prog " + fuse.__version__, -                 usage=usage, -                 dash_s_do='setsingle') - -    server.parser.add_option(mountopt="root", metavar="PATH", default='/', -                             help="mirror filesystem from under PATH [default: %default]") -    server.parse(values=server, errex=1) - -    try: -        if server.fuse_args.mount_expected(): -            os.chdir(server.root) -    except OSError: -        print >> sys.stderr, "can't enter root of underlying filesystem" -        sys.exit(1) - -    server.main() - - -if __name__ == '__main__': -    main() diff --git a/_find_fuse_parts.py b/find_fuse_parts.py index 2a04ab3..2a04ab3 100644 --- a/_find_fuse_parts.py +++ b/find_fuse_parts.py @@ -17,7 +17,7 @@ import errno   # for error number codes (ENOENT, etc)  # pull in some spaghetti to make this stuff work without fuse-py being installed  try: -    import _find_fuse_parts +    import find_fuse_parts  except ImportError:      pass  import fuse @@ -59,7 +59,7 @@ class DefaultStatVfs(fuse.StatVfs):          self.n_unamed_fields = 0  class NamespaceFS(Fuse): -    """Generates a file system from a python namespace, for kicks. +    """Generates a virtual file system from a python namespace.      """      def __init__(self, *args, **kw):  | 
