aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2011-04-29 16:00:17 -0400
committerbnewbold <bnewbold@robocracy.org>2011-04-29 16:00:17 -0400
commitfc80cc72b0e1900ea0e0dc540d6a52551e9b19c1 (patch)
tree3bada2c98e2e93ed09b861293ab78b4e035219fb
parentfba9ce54b4cfbcc8b2847ea1cc22144ba79957b0 (diff)
downloadpynsfs-master.tar.gz
pynsfs-master.zip
minor repo cleanupHEADmaster
-rw-r--r--README (renamed from README.nsfs)16
-rw-r--r--bundled_examples/hello.py92
-rw-r--r--bundled_examples/xmp.py279
-rw-r--r--find_fuse_parts.py (renamed from _find_fuse_parts.py)0
-rw-r--r--nsfs.py4
5 files changed, 12 insertions, 379 deletions
diff --git a/README.nsfs b/README
index 9e37d08..694541c 100644
--- a/README.nsfs
+++ b/README
@@ -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
diff --git a/nsfs.py b/nsfs.py
index d306097..1189472 100644
--- a/nsfs.py
+++ b/nsfs.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):