mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-11 15:32:39 +00:00
macfuse: rework fuse initialisation, integrate with 'tahoe'
this provides a variety of changes to the macfuse 'tahoefuse' implementation. most notably it extends the 'tahoe' command available through the mac build to provide a 'fuse' subcommand, which invokes tahoefuse. this addresses various aspects of main(argv) handling, sys.argv manipulation to provide an appropriate command line syntax that meshes with the fuse library's built- in command line parsing. this provides a "tahoe fuse [dir_cap_name] [fuse_options] mountpoint" command, where dir_cap_name is an optional name of a .cap file to be found in ~/.tahoe/private defaulting to the standard root_dir.cap. fuse_options if given are passed into the fuse system as its normal command line options and the mountpoint is checked for existence before launching fuse. the tahoe 'fuse' command is provided as an additional_command to the tahoe runner in the case that it's launched from the mac .app binary. this also includes a tweak to the TFS class which incorporates the ctime and mtime of files into the tahoe fs model, if available.
This commit is contained in:
parent
21f2d03203
commit
2ae8a482aa
@ -5,6 +5,39 @@ _junk = depends # appease pyflakes
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from twisted.python import usage
|
||||||
|
|
||||||
|
class ReplOptions(usage.Options):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def repl(config, stdout, stderr):
|
||||||
|
import code
|
||||||
|
return code.interact()
|
||||||
|
|
||||||
|
class DbgRunnerExtension(object):
|
||||||
|
subCommands = [
|
||||||
|
["dbgrepl", None, ReplOptions, "Open a python interpreter"],
|
||||||
|
]
|
||||||
|
dispatch = {
|
||||||
|
"dbgrepl": repl,
|
||||||
|
}
|
||||||
|
|
||||||
|
class FuseOptions(usage.Options):
|
||||||
|
def parseOptions(self, args):
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
def fuse(config, stdout, stderr):
|
||||||
|
import macfuse.tahoefuse
|
||||||
|
macfuse.tahoefuse.main(config.args)
|
||||||
|
|
||||||
|
class FuseRunnerExtension(object):
|
||||||
|
subCommands = [
|
||||||
|
["fuse", None, FuseOptions, "Mount a filesystem via fuse"],
|
||||||
|
]
|
||||||
|
dispatch = {
|
||||||
|
"fuse": fuse,
|
||||||
|
}
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
if len(argv) == 1:
|
if len(argv) == 1:
|
||||||
# then we were given no args; do default mac node startup
|
# then we were given no args; do default mac node startup
|
||||||
@ -13,7 +46,12 @@ def main(argv):
|
|||||||
else:
|
else:
|
||||||
# given any cmd line args, do 'tahoe' cli behaviour
|
# given any cmd line args, do 'tahoe' cli behaviour
|
||||||
from allmydata.scripts import runner
|
from allmydata.scripts import runner
|
||||||
sys.exit(runner.runner(argv[1:], install_node_control=False))
|
#runner_extensions = [DbgRunnerExtension, FuseRunnerExtension, ]
|
||||||
|
runner_extensions = [FuseRunnerExtension, ]
|
||||||
|
sys.exit(runner.runner(argv[1:],
|
||||||
|
install_node_control=False,
|
||||||
|
additional_commands=runner_extensions,
|
||||||
|
))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
@ -6,6 +6,7 @@ from allmydata.scripts.common_http import do_http as do_http_req
|
|||||||
|
|
||||||
import base64
|
import base64
|
||||||
import sha
|
import sha
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
import stat
|
import stat
|
||||||
@ -23,6 +24,8 @@ import traceback
|
|||||||
import simplejson
|
import simplejson
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
USAGE = 'usage: tahoe fuse [dir_cap_name] [fuse_options] mountpoint'
|
||||||
|
|
||||||
if not hasattr(fuse, '__version__'):
|
if not hasattr(fuse, '__version__'):
|
||||||
raise RuntimeError, \
|
raise RuntimeError, \
|
||||||
"your fuse-py doesn't know of fuse.__version__, probably it's too old."
|
"your fuse-py doesn't know of fuse.__version__, probably it's too old."
|
||||||
@ -101,7 +104,7 @@ class TahoeFuseFile(object):
|
|||||||
self.fname = self.tfs.cache.tmp_file(os.urandom(20))
|
self.fname = self.tfs.cache.tmp_file(os.urandom(20))
|
||||||
if self.fnode is None:
|
if self.fnode is None:
|
||||||
log('TFF: [%s] open(%s) for write: no such file, creating new File' % (self.name, self.fname, ))
|
log('TFF: [%s] open(%s) for write: no such file, creating new File' % (self.name, self.fname, ))
|
||||||
self.fnode = File(0, None)
|
self.fnode = File(0, None, None)
|
||||||
self.fnode.tmp_fname = self.fname # XXX kill this
|
self.fnode.tmp_fname = self.fname # XXX kill this
|
||||||
self.parent.add_child(self.name, self.fnode)
|
self.parent.add_child(self.name, self.fnode)
|
||||||
elif hasattr(self.fnode, 'tmp_fname'):
|
elif hasattr(self.fnode, 'tmp_fname'):
|
||||||
@ -208,8 +211,9 @@ class TahoeFuse(fuse.Fuse):
|
|||||||
log("TF: __init__(%r, %r)" % (args, kw))
|
log("TF: __init__(%r, %r)" % (args, kw))
|
||||||
|
|
||||||
self.tfs = tfs
|
self.tfs = tfs
|
||||||
|
_tfs_ = tfs
|
||||||
class MyFuseFile(TahoeFuseFile):
|
class MyFuseFile(TahoeFuseFile):
|
||||||
tfs = tfs
|
tfs = _tfs_
|
||||||
self.file_class = MyFuseFile
|
self.file_class = MyFuseFile
|
||||||
log("TF: file_class: %r" % (self.file_class,))
|
log("TF: file_class: %r" % (self.file_class,))
|
||||||
|
|
||||||
@ -341,22 +345,24 @@ class TahoeFuse(fuse.Fuse):
|
|||||||
self.log("mkdir(%r, %r)" % (path, mode))
|
self.log("mkdir(%r, %r)" % (path, mode))
|
||||||
self.tfs.mkdir(path)
|
self.tfs.mkdir(path)
|
||||||
|
|
||||||
def main(tfs):
|
def launch_tahoe_fuse(tfs, argv):
|
||||||
|
sys.argv = ['tahoe fuse'] + list(argv)
|
||||||
usage = "Userspace tahoe fs: cache a tahoe tree and present via fuse\n" + fuse.Fuse.fusage
|
|
||||||
|
|
||||||
server = TahoeFuse(tfs, version="%prog " + fuse.__version__,
|
server = TahoeFuse(tfs, version="%prog " + fuse.__version__,
|
||||||
usage=usage,
|
usage=USAGE,
|
||||||
dash_s_do='setsingle')
|
dash_s_do='setsingle')
|
||||||
server.parse(errex=1)
|
server.parse(errex=1)
|
||||||
server.main()
|
server.main()
|
||||||
|
|
||||||
|
|
||||||
def getbasedir():
|
def getbasedir(cap_name='root_dir'):
|
||||||
f = file(os.path.expanduser("~/.tahoe/private/root_dir.cap"), 'rb')
|
fname = os.path.expanduser("~/.tahoe/private/%s.cap" % (cap_name,))
|
||||||
|
if os.path.exists(fname):
|
||||||
|
f = file(fname, 'rb')
|
||||||
bd = f.read().strip()
|
bd = f.read().strip()
|
||||||
f.close()
|
f.close()
|
||||||
return bd
|
return bd
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def getnodeurl():
|
def getnodeurl():
|
||||||
f = file(os.path.expanduser("~/.tahoe/node.url"), 'rb')
|
f = file(os.path.expanduser("~/.tahoe/node.url"), 'rb')
|
||||||
@ -437,17 +443,34 @@ class Directory(object):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
class File(object):
|
class File(object):
|
||||||
def __init__(self, size, ro_uri):
|
def __init__(self, size, ro_uri, metadata):
|
||||||
self.size = size
|
self.size = size
|
||||||
if ro_uri:
|
if ro_uri:
|
||||||
ro_uri = str(ro_uri)
|
ro_uri = str(ro_uri)
|
||||||
self.ro_uri = ro_uri
|
self.ro_uri = ro_uri
|
||||||
|
self.metadata = metadata or {}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<File %s>" % (fingerprint(self.ro_uri) or [self.tmp_fname],)
|
return "<File %s>" % (fingerprint(self.ro_uri) or [self.tmp_fname],)
|
||||||
|
|
||||||
def pprint(self, prefix='', printed=None):
|
def pprint(self, prefix='', printed=None):
|
||||||
return " %s (%s)" % (prefix, self.size, )
|
times, remainder = self.get_times()
|
||||||
|
return " %s (%s) %s %s" % (prefix, self.size, times, remainder)
|
||||||
|
|
||||||
|
def get_times(self):
|
||||||
|
rem = self.metadata.copy()
|
||||||
|
now = time.time()
|
||||||
|
times = {}
|
||||||
|
for T in ['c', 'm']:
|
||||||
|
t = rem.pop('%stime'%T, None)
|
||||||
|
if not t:
|
||||||
|
t = 'none'
|
||||||
|
elif (now-t) < 86400:
|
||||||
|
t = time.strftime('%a:%H:%M:%S', time.localtime(t))
|
||||||
|
else:
|
||||||
|
t = time.strftime('%Y:%b:%d:%H:%M', time.localtime(t))
|
||||||
|
times[T] = t
|
||||||
|
return times, rem
|
||||||
|
|
||||||
def get_stat(self):
|
def get_stat(self):
|
||||||
if hasattr(self, 'tmp_fname'):
|
if hasattr(self, 'tmp_fname'):
|
||||||
@ -521,7 +544,7 @@ class TFS(object):
|
|||||||
cobj = self.dir_for(name, cattrs.get('ro_uri'), cattrs.get('rw_uri'))
|
cobj = self.dir_for(name, cattrs.get('ro_uri'), cattrs.get('rw_uri'))
|
||||||
else:
|
else:
|
||||||
assert ctype == "filenode"
|
assert ctype == "filenode"
|
||||||
cobj = File(cattrs.get('size'), cattrs.get('ro_uri'))
|
cobj = File(cattrs.get('size'), cattrs.get('ro_uri'), cattrs.get('metadata'))
|
||||||
dirobj.children[name] = cobj
|
dirobj.children[name] = cobj
|
||||||
|
|
||||||
def dir_for(self, name, ro_uri, rw_uri):
|
def dir_for(self, name, ro_uri, rw_uri):
|
||||||
@ -646,14 +669,45 @@ class FileCache(object):
|
|||||||
def print_tree():
|
def print_tree():
|
||||||
log('tree:\n' + _tfs.pprint())
|
log('tree:\n' + _tfs.pprint())
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def main(argv):
|
||||||
log("\n\nmain()")
|
log("\n\nmain(%s)" % (argv,))
|
||||||
tfs = TFS(getnodeurl(), getbasedir())
|
|
||||||
|
if not argv:
|
||||||
|
argv = ['--help']
|
||||||
|
if len(argv) == 1 and argv[0] in ['-h', '--help', '--version']:
|
||||||
|
#print USAGE
|
||||||
|
launch_tahoe_fuse(None, argv)
|
||||||
|
return -2
|
||||||
|
|
||||||
|
if not argv[0].startswith('-'):
|
||||||
|
cap_name = argv[0]
|
||||||
|
basedir = getbasedir(cap_name)
|
||||||
|
if basedir is None:
|
||||||
|
print 'root dir named "%s" not found.' % (cap_name,)
|
||||||
|
return -2
|
||||||
|
argv = argv[1:]
|
||||||
|
else:
|
||||||
|
basedir = getbasedir() # default 'root_dir'
|
||||||
|
|
||||||
|
if argv[-1].startswith('-'):
|
||||||
|
print 'mountpoint not given'
|
||||||
|
return -2
|
||||||
|
mountpoint = os.path.abspath(argv[-1])
|
||||||
|
if not os.path.exists(mountpoint):
|
||||||
|
#raise OSError(2, 'No such file or directory: "%s"' % (mountpoint,))
|
||||||
|
print 'No such file or directory: "%s"' % (mountpoint,)
|
||||||
|
return -2
|
||||||
|
|
||||||
|
nodeurl = getnodeurl()
|
||||||
|
|
||||||
|
tfs = TFS(nodeurl, basedir)
|
||||||
print tfs.pprint()
|
print tfs.pprint()
|
||||||
|
|
||||||
# make tfs instance accesible to print_tree() for dbg
|
# make tfs instance accesible to print_tree() for dbg
|
||||||
global _tfs
|
global _tfs
|
||||||
_tfs = tfs
|
_tfs = tfs
|
||||||
|
|
||||||
main(tfs)
|
launch_tahoe_fuse(tfs, argv)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv)
|
||||||
|
@ -283,16 +283,3 @@ class MacGuiApp(wx.App):
|
|||||||
def on_account_page(self, event):
|
def on_account_page(self, event):
|
||||||
webbrowser.open(DEFAULT_SERVER_URL + ACCOUNT_PAGE)
|
webbrowser.open(DEFAULT_SERVER_URL + ACCOUNT_PAGE)
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
if len(argv) == 1:
|
|
||||||
# then we were given no args; do default mac node startup
|
|
||||||
sys.exit(run_macapp())
|
|
||||||
else:
|
|
||||||
# given any cmd line args, do 'tahoe' cli behaviour
|
|
||||||
from allmydata.scripts import runner
|
|
||||||
sys.exit(runner.runner(argv[1:], install_node_control=False))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(sys.argv)
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user