Welcome to mirror list, hosted at ThFree Co, Russian Federation.

bareosfuse.py « fuse « bareos - github.com/bareos/python-bareos.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c851c0ea36c3c9e5d00cfda455624b426264148f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
FUSE filesystem on bareos data.
"""

from   bareos.bsock import DirectorConsoleJson
import bareos.bsock
from   bareos.util  import Path
from   bareos.fuse.root  import Root
import errno
import fuse
import logging
import socket
import stat
import os.path
from   pprint import pformat

fuse.fuse_python_api = (0, 2)


class BareosFuse(fuse.Fuse):

    def __init__(self, *args, **kw):
        self.bsock = None
        self.bareos = None
        self.restoreclient = None
        self.restorejob = None
        self.restorepath = '/var/cache/bareosfs/'
        super(BareosFuse, self).__init__(*args, **kw)
        self.multithreaded = False

    def initLogging(self):
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        if hasattr(self, "logfile"):
            hdlr = logging.FileHandler(self.logfile)
            # limit message size
            formatter = logging.Formatter('%(asctime)s  %(levelname)-7s %(module)s %(funcName)s( %(message).800s )')
            hdlr.setFormatter(formatter)
            self.logger.addHandler(hdlr)

    def parse(self, *args, **kw):
        super(BareosFuse, self).parse(*args, **kw)
        if self.fuse_args.mount_expected():
            options = [ 'address', 'port', 'dirname', 'name', 'password' ]
            self.bsockParameter = {}
            for i in options:
                if hasattr(self, i):
                    self.bsockParameter[i] = getattr(self,i)
                else:
                    #self.logger.debug( "%s: missing, default: %s" %(i, str(getattr(self,i,None))))
                    pass
            if not hasattr(self, 'password'):
                raise bareos.fuse.ParameterMissing("missing parameter password")
            else:
                password = bareos.bsock.Password(self.password)
                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.restorejob, self.restorepath)
        super(BareosFuse, self).main(*args, **kw)
        self.logger.debug('done')

    def getattr(self, path):
        if self.bareos:
            stat = self.bareos.getattr(Path(path))
            if isinstance(stat, fuse.Stat):
                self.logger.debug("{path}: dev={stat.st_dev}, ino={stat.st_ino}, mode={stat.st_mode}, nlink={stat.st_nlink}, uid={stat.st_uid}, gid={stat.st_gid}, size={stat.st_size}, atime={stat.st_atime}, ctime={stat.st_ctime}, mtime={stat.st_mtime}".format(path=path, stat=stat))
            else:
                self.logger.debug("%s: (int) %i" % (path, stat))
            return stat

    def read(self, path, size, offset):
        result = self.bareos.read(Path(path), size, offset)
        self.logger.debug("%s: %s" % (path, result))
        return result

    def readdir(self, path, offset):
        entries = self.bareos.readdir(Path(path), offset)
        self.logger.debug("%s: %s" % (path, entries))
        if not entries:
            return -errno.ENOENT
        else:
            return [fuse.Direntry(f) for f in entries]

    def readlink(self, path):
        result = self.bareos.readlink(Path(path))
        self.logger.debug("%s: %s" % (path, result))
        return result

    def listxattr(self, path, size):
        '''
        list extended attributes
        '''
        keys = self.bareos.listxattr(Path(path))
        if size == 0:
            # We are asked for size of the attr list, ie. joint size of attrs
            # plus null separators.
            result = len("".join(keys)) + len(keys)
            self.logger.debug("%s: len=%s" % (path, result))
        else:
            result = keys
            self.logger.debug("%s: keys=%s" % (path, ", ".join(keys)))
        return result

    def getxattr(self, path, key, size):
        '''
        get value of extended attribute
        burpfs exposes some filesystem attributes for the root directory
        (e.g. backup number, cache prefix - see FileSystem.xattr_fields_root)
        and may also expose several other attributes for each file/directory
        in the future (see FileSystem.xattr_fields)
        '''
        value = self.bareos.getxattr(Path(path), key)
        self.logger.debug("%s: %s=%s" % (path, key, str(value)))
        if value == None:
            result = -errno.ENODATA
        elif size == 0:
            # we are asked for size of the value
            result = len(value)
            self.logger.debug("%s: len=%s" % (path, result))
        else:
            result = value
            self.logger.debug("%s: %s=%s" % (path, key, result))
        return result

    def setxattr(self, path, key, value, flags):
        '''
        set value of extended attribute
        '''
        result = self.bareos.setxattr(Path(path), key, value, flags)
        self.logger.debug("%s: %s=%s: %s" % (path, key, value, str(result)))
        return result

    def rename(self, oldpath, newpath):
        result = self.bareos.rename(Path(oldpath), Path(newpath))
        self.logger.debug("%s => %s: %s" % (oldpath, newpath, result))
        return result