Commit 7f1e44a3 by willmcgugan

Added fsmount command, made memroyfs work with threads

parent 91093534
...@@ -63,4 +63,8 @@ ...@@ -63,4 +63,8 @@
* Separated behaviour of setcontents and createfile * Separated behaviour of setcontents and createfile
* Added a getmmap to base * Added a getmmap to base
* Added command line scripts fsls, fstree, fscat, fscp, fsmv * Added command line scripts fsls, fstree, fscat, fscp, fsmv
* Added command line scripts fsmkdir, fsmount
* Made automatically pick up keys if no other authentication is available
* Optimized listdir and listdirinfo in SFTPFS
* Made memoryfs work with threads
...@@ -149,9 +149,11 @@ class FS(object): ...@@ -149,9 +149,11 @@ class FS(object):
:param thread_synconize: If True, a lock object will be created for the object, otherwise a dummy lock will be used. :param thread_synconize: If True, a lock object will be created for the object, otherwise a dummy lock will be used.
:type thread_synchronize: bool :type thread_synchronize: bool
""" """
super(FS, self).__init__() super(FS, self).__init__()
self.closed = False self.closed = False
self.thread_synchronize = thread_synchronize
if thread_synchronize: if thread_synchronize:
self._lock = threading.RLock() self._lock = threading.RLock()
else: else:
...@@ -188,9 +190,10 @@ class FS(object): ...@@ -188,9 +190,10 @@ class FS(object):
return state return state
def __setstate__(self,state): def __setstate__(self,state):
for (k,v) in state.iteritems(): self.__dict__.update(state)
self.__dict__[k] = v #for (k,v) in state.iteritems():
lock = state.get("_lock",None) # self.__dict__[k] = v
lock = state.get("_lock")
if lock is not None: if lock is not None:
if lock: if lock:
self._lock = threading.RLock() self._lock = threading.RLock()
......
#!/usr/bin/env python
import sys
from fs.commands.fsmount import run
sys.exit(run())
#!/usr/bin/env python
from fs.opener import opener
from fs.commands.runner import Command
import sys
import platform
import os
import os.path
import time
class FSMount(Command):
usage = """fsmount [SYSTEM PATH] [FS]
or fsmount -u [SYSTEM PATH]
Mounts a file system on a system path"""
version = "1.0"
def get_optparse(self):
optparse = super(FSMount, self).get_optparse()
optparse.add_option('-f', '--foreground', dest='foreground', action="store_true", default=False,
help="run the mount process in the foreground", metavar="FOREGROUND")
optparse.add_option('-u', '--unmount', dest='unmount', action="store_true", default=False,
help="unmount path", metavar="UNMOUNT")
return optparse
def do_run(self, options, args):
if options.unmount:
try:
mount_path = args[0]
except IndexError:
self.error('Mount path required\n')
return 1
from fs.expose import fuse
fuse.unmount(mount_path)
return
try:
mount_path = args[0]
except IndexError:
self.error('Mount path required\n')
return 1
try:
fs_url = args[1]
except IndexError:
self.error('FS required\n')
return 1
if platform.system() == 'Windows':
pass
else:
fs, path = self.open_fs(fs_url, create=True)
if path:
if not fs.isdir(path):
self.error('%s is not a directory on %s' % (fs_url. fs))
return 1
fs = fs.opendir(path)
path = '/'
if not os.path.exists(mount_path):
os.makedirs(mount_path)
from fs.expose import fuse
if options.foreground:
fuse_process = fuse.mount(fs,
mount_path,
foreground=True)
else:
mp = fuse.mount(fs,
mount_path,
foreground=False)
def run():
return FSMount().run()
if __name__ == "__main__":
sys.exit(run())
\ No newline at end of file
...@@ -245,11 +245,14 @@ class FSOperations(Operations): ...@@ -245,11 +245,14 @@ class FSOperations(Operations):
@handle_fs_errors @handle_fs_errors
def readdir(self, path, fh=None): def readdir(self, path, fh=None):
path = path.decode(NATIVE_ENCODING) path = path.decode(NATIVE_ENCODING)
entries = [] entries = ['.', '..']
#print
#print self.fs
for (nm,info) in self.fs.listdirinfo(path): for (nm,info) in self.fs.listdirinfo(path):
#print "*", repr(nm), info
self._fill_stat_dict(pathjoin(path,nm),info) self._fill_stat_dict(pathjoin(path,nm),info)
entries.append((nm.encode(NATIVE_ENCODING),info,0)) entries.append((nm.encode(NATIVE_ENCODING),info,0))
entries = [".",".."] + entries #print
return entries return entries
@handle_fs_errors @handle_fs_errors
...@@ -472,7 +475,7 @@ def unmount(path): ...@@ -472,7 +475,7 @@ def unmount(path):
return return
if "not found" in stderr: if "not found" in stderr:
return return
raise OSError("filesystem could not be unmounted: %s (%s) " % (path,stderr,)) raise OSError("filesystem could not be unmounted: %s (%s) " % (path, str(stderr).rstrip(),))
class MountProcess(subprocess.Popen): class MountProcess(subprocess.Popen):
......
...@@ -18,10 +18,8 @@ from ftplib import FTP, error_perm, error_temp, error_proto, error_reply ...@@ -18,10 +18,8 @@ from ftplib import FTP, error_perm, error_temp, error_proto, error_reply
try: try:
from ftplib import _GLOBAL_DEFAULT_TIMEOUT from ftplib import _GLOBAL_DEFAULT_TIMEOUT
_FTPLIB_TIMEOUT = True
except ImportError: except ImportError:
_GLOBAL_DEFAULT_TIMEOUT = None _GLOBAL_DEFAULT_TIMEOUT = object()
_FTPLIB_TIMEOUT = False
import threading import threading
from time import sleep from time import sleep
...@@ -934,7 +932,7 @@ class FTPFS(FS): ...@@ -934,7 +932,7 @@ class FTPFS(FS):
def _open_ftp(self): def _open_ftp(self):
try: try:
ftp = FTP() ftp = FTP()
if _FTPLIB_TIMEOUT: if self.timeout is not _GLOBAL_DEFAULT_TIMEOUT:
ftp.connect(self.host, self.port, self.timeout) ftp.connect(self.host, self.port, self.timeout)
else: else:
ftp.connect(self.host, self.port) ftp.connect(self.host, self.port)
......
...@@ -365,7 +365,7 @@ class TempOpener(Opener): ...@@ -365,7 +365,7 @@ class TempOpener(Opener):
@classmethod @classmethod
def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create): def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create):
from fs.tempfs import TempFS from fs.tempfs import TempFS
return TempFS(identifier=fs_name_params, temp_dir=fs_path, create=create), None return TempFS(identifier=fs_name_params, temp_dir=fs_path), None
opener = OpenerRegistry([OSFSOpener, opener = OpenerRegistry([OSFSOpener,
......
...@@ -98,6 +98,7 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS): ...@@ -98,6 +98,7 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
super(OSFS, self).__init__(thread_synchronize=thread_synchronize) super(OSFS, self).__init__(thread_synchronize=thread_synchronize)
self.encoding = encoding or sys.getfilesystemencoding() self.encoding = encoding or sys.getfilesystemencoding()
self.dir_mode = dir_mode
root_path = os.path.expanduser(os.path.expandvars(root_path)) root_path = os.path.expanduser(os.path.expandvars(root_path))
root_path = os.path.normpath(os.path.abspath(root_path)) root_path = os.path.normpath(os.path.abspath(root_path))
# Enable long pathnames on win32 # Enable long pathnames on win32
...@@ -319,4 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS): ...@@ -319,4 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
def getsize(self, path): def getsize(self, path):
return self._stat(path).st_size return self._stat(path).st_size
@convert_os_errors
def opendir(self, path):
"""A specialised opendir that returns another OSFS rather than a SubDir
This is more optimal than a SubDir because no path delegation is required.
"""
if path in ('', '/'):
return self
path = normpath(path)
if not self.exists(path):
raise ResourceNotFoundError(path)
sub_path = pathjoin(self.root_path, path)
return OSFS(sub_path,
thread_synchronize=self.thread_synchronize,
encoding=self.encoding,
create=False,
dir_mode=self.dir_mode)
...@@ -38,7 +38,7 @@ def re_raise_faults(func): ...@@ -38,7 +38,7 @@ def re_raise_faults(func):
cls = _object_by_name(cls) cls = _object_by_name(cls)
# Re-raise using the remainder of the fault code as message # Re-raise using the remainder of the fault code as message
if cls: if cls:
raise cls(msg=msg) raise cls('', msg=msg)
raise f raise f
except socket.error, e: except socket.error, e:
raise RemoteConnectionError(str(e), details=e) raise RemoteConnectionError(str(e), details=e)
......
...@@ -12,7 +12,8 @@ COMMANDS = ['fscat', ...@@ -12,7 +12,8 @@ COMMANDS = ['fscat',
'fsrm', 'fsrm',
'fsserve', 'fsserve',
'fstree', 'fstree',
'fsmkdir'] 'fsmkdir',
'fsmount']
classifiers = [ classifiers = [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment