e61ba54bf681b6ef1f42ec882a72e0ac1999be60
[arvados.git] / services / fuse / arvados_fuse / fusefile.py
1 import logging
2 import re
3 import json
4 import llfuse
5
6 from fresh import FreshBase, convertTime
7
8 _logger = logging.getLogger('arvados.arvados_fuse')
9
10 class File(FreshBase):
11     """Base for file objects."""
12
13     def __init__(self, parent_inode, _mtime=0):
14         super(File, self).__init__()
15         self.inode = None
16         self.parent_inode = parent_inode
17         self._mtime = _mtime
18
19     def size(self):
20         return 0
21
22     def readfrom(self, off, size, num_retries=0):
23         return ''
24
25     def writeto(self, off, size, num_retries=0):
26         raise Exception("Not writable")
27
28     def mtime(self):
29         return self._mtime
30
31     def clear(self, force=False):
32         return True
33
34     def writable(self):
35         return False
36
37     def flush(self):
38         pass
39
40
41 class FuseArvadosFile(File):
42     """Wraps a ArvadosFile."""
43
44     def __init__(self, parent_inode, arvfile, _mtime):
45         super(FuseArvadosFile, self).__init__(parent_inode, _mtime)
46         self.arvfile = arvfile
47
48     def size(self):
49         _logger.debug("started calling self.arvfile.size()")
50         with llfuse.lock_released:
51             _logger.debug("locked_released and calling self.arvfile.size()")
52             return self.arvfile.size()
53
54     def readfrom(self, off, size, num_retries=0):
55         with llfuse.lock_released:
56             return self.arvfile.readfrom(off, size, num_retries, exact=True)
57
58     def writeto(self, off, buf, num_retries=0):
59         with llfuse.lock_released:
60             return self.arvfile.writeto(off, buf, num_retries)
61
62     def stale(self):
63         return False
64
65     def writable(self):
66         return self.arvfile.writable()
67
68     def flush(self):
69         with llfuse.lock_released:
70             if self.writable():
71                 self.arvfile.parent.root_collection().save()
72
73
74 class StringFile(File):
75     """Wrap a simple string as a file"""
76     def __init__(self, parent_inode, contents, _mtime):
77         super(StringFile, self).__init__(parent_inode, _mtime)
78         self.contents = contents
79
80     def size(self):
81         return len(self.contents)
82
83     def readfrom(self, off, size, num_retries=0):
84         return self.contents[off:(off+size)]
85
86
87 class ObjectFile(StringFile):
88     """Wrap a dict as a serialized json object."""
89
90     def __init__(self, parent_inode, obj):
91         super(ObjectFile, self).__init__(parent_inode, "", 0)
92         self.object_uuid = obj['uuid']
93         self.update(obj)
94
95     def uuid(self):
96         return self.object_uuid
97
98     def update(self, obj=None):
99         self._mtime = convertTime(obj['modified_at']) if 'modified_at' in obj else 0
100         self.contents = json.dumps(obj, indent=4, sort_keys=True) + "\n"
101
102     def persisted(self):
103         return True