diff --git a/bareos/fuse/__init__.py b/bareos/fuse/__init__.py index 2ef7f377e80..215da07feea 100644 --- a/bareos/fuse/__init__.py +++ b/bareos/fuse/__init__.py @@ -1,3 +1,4 @@ #__all__ = [ "bconsole" ] +from bareos.fuse.exceptions import * from bareos.fuse.bareosfuse import BareosFuse import bareos.fuse.node diff --git a/bareos/fuse/bareosfuse.py b/bareos/fuse/bareosfuse.py index cda79a1eee1..c5ae2897361 100644 --- a/bareos/fuse/bareosfuse.py +++ b/bareos/fuse/bareosfuse.py @@ -9,7 +9,9 @@ import errno import fuse import logging +import socket import stat +import os.path from pprint import pformat fuse.fuse_python_api = (0, 2) @@ -20,6 +22,8 @@ class BareosFuse(fuse.Fuse): def __init__(self, *args, **kw): self.bsock = None self.bareos = None + self.restoreclient = None + self.restorepath = '/var/cache/bareosfs/' super(BareosFuse, self).__init__(*args, **kw) self.multithreaded = False @@ -32,34 +36,39 @@ def initLogging(self): hdlr.setFormatter(formatter) self.logger.addHandler(hdlr) - def main(self, *args, **kw): - # use main() instead of fsinit, - # as this prevents FUSE from being started in case of errors. - - self.initLogging() - self.logger.debug('start') + def parse(self, *args, **kw): + super(BareosFuse, self).parse(*args, **kw) if self.fuse_args.mount_expected(): options = [ 'address', 'port', 'dirname', 'name', 'password' ] - parameter = {} + self.bsockParameter = {} for i in options: if hasattr(self, i): - self.logger.debug( "%s: %s" %(i, getattr(self,i))) - parameter[i] = getattr(self,i) + self.bsockParameter[i] = getattr(self,i) else: - self.logger.debug( "%s: missing, default: %s" %(i, str(getattr(self,i,None)))) - self.logger.debug('options: %s' % (parameter)) + #self.logger.debug( "%s: missing, default: %s" %(i, str(getattr(self,i,None)))) + pass if not hasattr(self, 'password'): - raise RuntimeError("missing parameter password") + raise bareos.fuse.ParameterMissing("missing parameter password") else: password = bareos.bsock.Password(self.password) - parameter['password']=password - self.bsock = bareos.bsock.BSockJson(**parameter) - if not hasattr(self, 'restoreclient'): - self.restoreclient = None - #raise RuntimeError("missing parameter restoreclient") - # TODO: check if restoreclient is valid - if not hasattr(self, 'restorepath'): - self.restorepath = '/var/cache/bareosfs/' + self.bsockParameter['password']=password + self.restorepath = os.path.normpath(self.restorepath) + if not os.path.isabs(self.restorepath): + raise bareos.fuse.RestorePathInvalid("restorepath must be an absolute path") + + + def main(self, *args, **kw): + # use main() instead of fsinit, + # as this prevents FUSE from being started in case of errors. + + self.initLogging() + self.logger.debug('start') + if self.fuse_args.mount_expected(): + try: + self.bsock = bareos.bsock.BSockJson(**self.bsockParameter) + except socket.error as e: + self.logger.exception(e) + raise bareos.fuse.SocketConnectionRefused(e) self.bareos = Root(self.bsock, self.restoreclient, self.restorepath) super(BareosFuse, self).main(*args, **kw) self.logger.debug('done') diff --git a/bareos/fuse/exceptions.py b/bareos/fuse/exceptions.py new file mode 100644 index 00000000000..bab281b3646 --- /dev/null +++ b/bareos/fuse/exceptions.py @@ -0,0 +1,19 @@ +""" +Bareos-Fuse specific exceptions +""" + +class ParameterMissing(Exception): + """parameter missing""" + pass + +class SocketConnectionRefused(Exception): + """network socket connection refused""" + pass + +class RestoreClientUnknown(Exception): + """given restore client is not known""" + pass + +class RestorePathInvalid(Exception): + """restore path is invalid""" + pass diff --git a/bareos/fuse/node/bvfscommon.py b/bareos/fuse/node/bvfscommon.py index d20c7dd4757..a91cb236e6b 100644 --- a/bareos/fuse/node/bvfscommon.py +++ b/bareos/fuse/node/bvfscommon.py @@ -22,9 +22,12 @@ def init(self, root, jobid, path, filename, stat): self.xattr = { 'user.bareos.restorepath': str(self.restorepathfull), 'user.bareos.restored': 'no', - 'user.bareos.do_options': "mark | restore", - 'user.bareos.do': '', } + if self.root.restoreclient: + # restore is only possible, if a restoreclient is given + self.xattr['user.bareos.do_options'] = 'restore' + self.xattr['user.bareos.do'] = '' + if stat: self.set_stat(stat) diff --git a/bareos/fuse/root.py b/bareos/fuse/root.py index 6cd7ec396c5..8e127412df5 100644 --- a/bareos/fuse/root.py +++ b/bareos/fuse/root.py @@ -2,6 +2,7 @@ bareosfs root node (top level directory) """ +import bareos.fuse.exceptions from bareos.fuse.nodefactory import NodeFactory from bareos.fuse.node.directory import Directory from bareos.fuse.node import * @@ -13,6 +14,10 @@ class Root(Directory): def __init__(self, bsock, restoreclient, restorepath): self.bsock = bsock self.restoreclient = restoreclient + if restoreclient: + data = self.bsock.call(".clients") + if not restoreclient in [item['name'] for item in data['clients']]: + raise bareos.fuse.RestoreClientUnknown(restoreclient) self.restorepath = restorepath super(Root, self).__init__(self, None) self.factory = NodeFactory(self)