Statistics
| Branch: | Tag: | Revision:

root / pithos / tools / pithos-fs @ 93abb8b2

History | View | Annotate | Download (12.2 kB)

1 51f905a2 Giorgos Verigakis
#!/usr/bin/env python
2 51f905a2 Giorgos Verigakis
3 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
4 51f905a2 Giorgos Verigakis
# 
5 51f905a2 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
6 51f905a2 Giorgos Verigakis
# without modification, are permitted provided that the following
7 51f905a2 Giorgos Verigakis
# conditions are met:
8 51f905a2 Giorgos Verigakis
# 
9 51f905a2 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
10 51f905a2 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
11 51f905a2 Giorgos Verigakis
#      disclaimer.
12 51f905a2 Giorgos Verigakis
# 
13 51f905a2 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
14 51f905a2 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
15 51f905a2 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
16 51f905a2 Giorgos Verigakis
#      provided with the distribution.
17 51f905a2 Giorgos Verigakis
# 
18 51f905a2 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 51f905a2 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 51f905a2 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 51f905a2 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 51f905a2 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 51f905a2 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 51f905a2 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 51f905a2 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 51f905a2 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 51f905a2 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 51f905a2 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 51f905a2 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
30 51f905a2 Giorgos Verigakis
# 
31 51f905a2 Giorgos Verigakis
# The views and conclusions contained in the software and
32 51f905a2 Giorgos Verigakis
# documentation are those of the authors and should not be
33 51f905a2 Giorgos Verigakis
# interpreted as representing official policies, either expressed
34 51f905a2 Giorgos Verigakis
# or implied, of GRNET S.A.
35 51f905a2 Giorgos Verigakis
36 51f905a2 Giorgos Verigakis
from cStringIO import StringIO
37 51f905a2 Giorgos Verigakis
from errno import (EACCES, EBADF, EINVAL, EISDIR, EIO, ENOENT, ENOTDIR,
38 51f905a2 Giorgos Verigakis
                    ENOTEMPTY)
39 51f905a2 Giorgos Verigakis
from getpass import getuser
40 51f905a2 Giorgos Verigakis
from stat import S_IFDIR, S_IFREG
41 51f905a2 Giorgos Verigakis
from sys import argv
42 51f905a2 Giorgos Verigakis
from time import time
43 51f905a2 Giorgos Verigakis
44 5a96180b Antony Chazapis
from pithos.lib.compat import parse_http_date
45 5a96180b Antony Chazapis
from pithos.lib.client import OOS_Client, Fault
46 5a96180b Antony Chazapis
from pithos.lib.fuse import FUSE, FuseOSError, Operations
47 43cc6f76 Sofia Papagiannaki
from pithos.lib.util import get_user, get_auth, get_url
48 51f905a2 Giorgos Verigakis
49 51f905a2 Giorgos Verigakis
50 51f905a2 Giorgos Verigakis
epoch = int(time())
51 51f905a2 Giorgos Verigakis
52 51f905a2 Giorgos Verigakis
53 51f905a2 Giorgos Verigakis
class StoreFS(Operations):
54 2152daa0 Giorgos Verigakis
    def __init__(self, verbose=False):
55 51f905a2 Giorgos Verigakis
        self.verbose = verbose
56 43cc6f76 Sofia Papagiannaki
        self.client = OOS_Client(get_url(), get_auth(), get_user())
57 51f905a2 Giorgos Verigakis
    
58 51f905a2 Giorgos Verigakis
    def __call__(self, op, path, *args):
59 51f905a2 Giorgos Verigakis
        container, sep, object = path[1:].partition('/')
60 51f905a2 Giorgos Verigakis
        if self.verbose:
61 51f905a2 Giorgos Verigakis
            data = repr(args)[:100]
62 51f905a2 Giorgos Verigakis
            print '-> %s %r %r %r' % (op, container, object, data)
63 51f905a2 Giorgos Verigakis
        ret = '[Unhandled Exception]'
64 51f905a2 Giorgos Verigakis
        
65 51f905a2 Giorgos Verigakis
        try:
66 51f905a2 Giorgos Verigakis
            if object:
67 71c0f614 Giorgos Verigakis
                func = getattr(self, 'object_' + op, None)
68 71c0f614 Giorgos Verigakis
                funcargs = (container, object) + args
69 51f905a2 Giorgos Verigakis
            elif container:
70 71c0f614 Giorgos Verigakis
                func = getattr(self, 'container_' + op, None)
71 71c0f614 Giorgos Verigakis
                funcargs = (container,) + args
72 51f905a2 Giorgos Verigakis
            else:
73 71c0f614 Giorgos Verigakis
                func = getattr(self, 'account_' + op, None)
74 71c0f614 Giorgos Verigakis
                funcargs = args
75 71c0f614 Giorgos Verigakis
76 71c0f614 Giorgos Verigakis
            if not func:
77 71c0f614 Giorgos Verigakis
                # Fallback to defaults
78 71c0f614 Giorgos Verigakis
                func = getattr(self, op)
79 71c0f614 Giorgos Verigakis
                funcargs = (path,) + args
80 71c0f614 Giorgos Verigakis
            
81 71c0f614 Giorgos Verigakis
            ret = func(*funcargs)
82 51f905a2 Giorgos Verigakis
            return ret
83 51f905a2 Giorgos Verigakis
        except FuseOSError, e:
84 51f905a2 Giorgos Verigakis
            ret = str(e)
85 51f905a2 Giorgos Verigakis
            raise
86 51f905a2 Giorgos Verigakis
        finally:
87 51f905a2 Giorgos Verigakis
            if self.verbose:
88 51f905a2 Giorgos Verigakis
                print '<-', op, repr(ret)
89 51f905a2 Giorgos Verigakis
    
90 51f905a2 Giorgos Verigakis
    
91 51f905a2 Giorgos Verigakis
    def _get_container_meta(self, container, **kwargs):
92 51f905a2 Giorgos Verigakis
        try:
93 51f905a2 Giorgos Verigakis
            return self.client.retrieve_container_metadata(container, **kwargs)
94 51f905a2 Giorgos Verigakis
        except Fault:
95 51f905a2 Giorgos Verigakis
            raise FuseOSError(ENOENT)
96 51f905a2 Giorgos Verigakis
    
97 51f905a2 Giorgos Verigakis
    def _get_object_meta(self, container, object, **kwargs):
98 51f905a2 Giorgos Verigakis
        try:
99 51f905a2 Giorgos Verigakis
            return self.client.retrieve_object_metadata(container, object,
100 51f905a2 Giorgos Verigakis
                                                        **kwargs)
101 51f905a2 Giorgos Verigakis
        except Fault:
102 51f905a2 Giorgos Verigakis
            raise FuseOSError(ENOENT)
103 51f905a2 Giorgos Verigakis
    
104 51f905a2 Giorgos Verigakis
    
105 51f905a2 Giorgos Verigakis
    # Global
106 51f905a2 Giorgos Verigakis
    
107 51f905a2 Giorgos Verigakis
    def statfs(self, path):
108 51f905a2 Giorgos Verigakis
        return dict(f_bsize=1024, f_blocks=1024**2, f_bfree=1024**2,
109 51f905a2 Giorgos Verigakis
                    f_bavail=1024**2)
110 51f905a2 Giorgos Verigakis
    
111 51f905a2 Giorgos Verigakis
    
112 51f905a2 Giorgos Verigakis
    # Account Level
113 51f905a2 Giorgos Verigakis
    
114 51f905a2 Giorgos Verigakis
    def account_chmod(self, mode):
115 71c0f614 Giorgos Verigakis
        self.client.update_account_metadata(mode=str(mode))
116 51f905a2 Giorgos Verigakis
    
117 51f905a2 Giorgos Verigakis
    def account_chown(self, uid, gid):
118 51f905a2 Giorgos Verigakis
        self.client.update_account_metadata(uid=uid, gid=gid)
119 51f905a2 Giorgos Verigakis
    
120 51f905a2 Giorgos Verigakis
    def account_getattr(self, fh=None):
121 71c0f614 Giorgos Verigakis
        meta = self.client.retrieve_account_metadata()
122 51f905a2 Giorgos Verigakis
        mode = int(meta.get('x-account-meta-mode', 0755))
123 71c0f614 Giorgos Verigakis
        last_modified = meta.get('last-modified', None)
124 71c0f614 Giorgos Verigakis
        modified = parse_http_date(last_modified) if last_modified else epoch
125 51f905a2 Giorgos Verigakis
        count = int(meta['x-account-container-count'])
126 51f905a2 Giorgos Verigakis
        uid = int(meta.get('x-account-meta-uid', 0))
127 51f905a2 Giorgos Verigakis
        gid = int(meta.get('x-account-meta-gid', 0))
128 51f905a2 Giorgos Verigakis
        
129 51f905a2 Giorgos Verigakis
        return {
130 51f905a2 Giorgos Verigakis
            'st_mode': S_IFDIR | mode,
131 51f905a2 Giorgos Verigakis
            'st_nlink': 2 + count,
132 51f905a2 Giorgos Verigakis
            'st_uid': uid,
133 51f905a2 Giorgos Verigakis
            'st_gid': gid,
134 51f905a2 Giorgos Verigakis
            'st_ctime': epoch,
135 51f905a2 Giorgos Verigakis
            'st_mtime': modified,
136 51f905a2 Giorgos Verigakis
            'st_atime': modified}
137 51f905a2 Giorgos Verigakis
    
138 51f905a2 Giorgos Verigakis
    def account_getxattr(self, name, position=0):
139 51f905a2 Giorgos Verigakis
        meta = self.client.retrieve_account_metadata(restricted=True)
140 51f905a2 Giorgos Verigakis
        return meta.get('xattr-' + name, '')
141 51f905a2 Giorgos Verigakis
    
142 51f905a2 Giorgos Verigakis
    def account_listxattr(self):
143 51f905a2 Giorgos Verigakis
        meta = self.client.retrieve_account_metadata(restricted=True)
144 51f905a2 Giorgos Verigakis
        prefix = 'xattr-'
145 51f905a2 Giorgos Verigakis
        return [k[len(prefix):] for k in meta if k.startswith(prefix)]
146 51f905a2 Giorgos Verigakis
    
147 51f905a2 Giorgos Verigakis
    def account_readdir(self, fh):
148 2152daa0 Giorgos Verigakis
        return ['.', '..'] + self.client.list_containers() or []
149 51f905a2 Giorgos Verigakis
    
150 51f905a2 Giorgos Verigakis
    def account_removexattr(self, name):
151 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
152 51f905a2 Giorgos Verigakis
        self.client.delete_account_metadata([attr])
153 51f905a2 Giorgos Verigakis
    
154 51f905a2 Giorgos Verigakis
    def account_setxattr(self, name, value, options, position=0):
155 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
156 51f905a2 Giorgos Verigakis
        meta = {attr: value}
157 51f905a2 Giorgos Verigakis
        self.client.update_account_metadata(**meta)
158 51f905a2 Giorgos Verigakis
    
159 51f905a2 Giorgos Verigakis
    
160 51f905a2 Giorgos Verigakis
    # Container Level
161 51f905a2 Giorgos Verigakis
    
162 51f905a2 Giorgos Verigakis
    def container_chmod(self, container, mode):
163 71c0f614 Giorgos Verigakis
        self.client.update_container_metadata(container, mode=str(mode))
164 51f905a2 Giorgos Verigakis
    
165 51f905a2 Giorgos Verigakis
    def container_chown(self, container, uid, gid):
166 51f905a2 Giorgos Verigakis
        self.client.update_container_metadata(container, uid=uid, gid=gid)
167 51f905a2 Giorgos Verigakis
    
168 51f905a2 Giorgos Verigakis
    def container_getattr(self, container, fh=None):
169 51f905a2 Giorgos Verigakis
        meta = self._get_container_meta(container)
170 51f905a2 Giorgos Verigakis
        mode = int(meta.get('x-container-meta-mode', 0755))
171 51f905a2 Giorgos Verigakis
        modified = parse_http_date(meta['last-modified'])
172 51f905a2 Giorgos Verigakis
        count = int(meta['x-container-object-count'])
173 51f905a2 Giorgos Verigakis
        uid = int(meta.get('x-account-meta-uid', 0))
174 51f905a2 Giorgos Verigakis
        gid = int(meta.get('x-account-meta-gid', 0))
175 51f905a2 Giorgos Verigakis
        
176 51f905a2 Giorgos Verigakis
        return {
177 51f905a2 Giorgos Verigakis
            'st_mode': S_IFDIR | mode,
178 51f905a2 Giorgos Verigakis
            'st_nlink': 2 + count,
179 51f905a2 Giorgos Verigakis
            'st_uid': uid,
180 51f905a2 Giorgos Verigakis
            'st_gid': gid,
181 51f905a2 Giorgos Verigakis
            'st_ctime': epoch,
182 51f905a2 Giorgos Verigakis
            'st_mtime': modified,
183 51f905a2 Giorgos Verigakis
            'st_atime': modified}
184 51f905a2 Giorgos Verigakis
    
185 51f905a2 Giorgos Verigakis
    def container_getxattr(self, container, name, position=0):
186 51f905a2 Giorgos Verigakis
        meta = self._get_container_meta(container)
187 51f905a2 Giorgos Verigakis
        return meta.get('xattr-' + name, '')
188 51f905a2 Giorgos Verigakis
    
189 51f905a2 Giorgos Verigakis
    def container_listxattr(self, container):
190 51f905a2 Giorgos Verigakis
        meta = self._get_container_meta(container, restricted=True)
191 51f905a2 Giorgos Verigakis
        prefix = 'xattr-'
192 51f905a2 Giorgos Verigakis
        return [k[len(prefix):] for k in meta if k.startswith(prefix)]
193 51f905a2 Giorgos Verigakis
    
194 51f905a2 Giorgos Verigakis
    def container_mkdir(self, container, mode):
195 71c0f614 Giorgos Verigakis
        mode = str(mode & 0777)
196 71c0f614 Giorgos Verigakis
        self.client.create_container(container, mode=mode)
197 51f905a2 Giorgos Verigakis
    
198 51f905a2 Giorgos Verigakis
    def container_readdir(self, container, fh):
199 2152daa0 Giorgos Verigakis
        objects = self.client.list_objects(container, delimiter='/', prefix='')
200 51f905a2 Giorgos Verigakis
        files = [o for o in objects if not o.endswith('/')]
201 51f905a2 Giorgos Verigakis
        return ['.', '..'] + files
202 51f905a2 Giorgos Verigakis
    
203 51f905a2 Giorgos Verigakis
    def container_removexattr(self, container, name):
204 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
205 51f905a2 Giorgos Verigakis
        self.client.delete_container_metadata(container, [attr])
206 51f905a2 Giorgos Verigakis
    
207 51f905a2 Giorgos Verigakis
    def container_rename(self, container, path):
208 51f905a2 Giorgos Verigakis
        new_container, sep, new_object = path[1:].partition('/')
209 51f905a2 Giorgos Verigakis
        if not new_container or new_object:
210 51f905a2 Giorgos Verigakis
            raise FuseOSError(EINVAL)
211 51f905a2 Giorgos Verigakis
        self.client.delete_container(container)
212 51f905a2 Giorgos Verigakis
        self.client.create_container(new_container)
213 51f905a2 Giorgos Verigakis
    
214 51f905a2 Giorgos Verigakis
    def container_rmdir(self, container):
215 51f905a2 Giorgos Verigakis
        try:
216 51f905a2 Giorgos Verigakis
            self.client.delete_container(container)
217 51f905a2 Giorgos Verigakis
        except Fault:
218 51f905a2 Giorgos Verigakis
            raise FuseOSError(ENOENT)
219 51f905a2 Giorgos Verigakis
    
220 51f905a2 Giorgos Verigakis
    def container_setxattr(self, container, name, value, options, position=0):
221 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
222 51f905a2 Giorgos Verigakis
        meta = {attr: value}
223 51f905a2 Giorgos Verigakis
        self.client.update_container_metadata(container, **meta)
224 51f905a2 Giorgos Verigakis
    
225 51f905a2 Giorgos Verigakis
    
226 51f905a2 Giorgos Verigakis
    # Object Level
227 51f905a2 Giorgos Verigakis
    
228 51f905a2 Giorgos Verigakis
    def object_chmod(self, container, object, mode):
229 71c0f614 Giorgos Verigakis
        self.client.update_object_metadata(container, object, mode=str(mode))
230 51f905a2 Giorgos Verigakis
    
231 51f905a2 Giorgos Verigakis
    def object_chown(self, container, uid, gid):
232 71c0f614 Giorgos Verigakis
        self.client.update_object_metadata(container, object,
233 71c0f614 Giorgos Verigakis
                                            uid=str(uid), gid=str(gid))
234 51f905a2 Giorgos Verigakis
    
235 51f905a2 Giorgos Verigakis
    def object_create(self, container, object, mode, fi=None):
236 51f905a2 Giorgos Verigakis
        mode &= 0777
237 71c0f614 Giorgos Verigakis
        self.client.create_object(container, object,
238 71c0f614 Giorgos Verigakis
                                    f=None,
239 71c0f614 Giorgos Verigakis
                                    content_type='application/octet-stream',
240 71c0f614 Giorgos Verigakis
                                    mode=str(mode))
241 51f905a2 Giorgos Verigakis
        return 0
242 51f905a2 Giorgos Verigakis
    
243 51f905a2 Giorgos Verigakis
    def object_getattr(self, container, object, fh=None):
244 51f905a2 Giorgos Verigakis
        meta = self._get_object_meta(container, object)
245 51f905a2 Giorgos Verigakis
        modified = parse_http_date(meta['last-modified'])
246 51f905a2 Giorgos Verigakis
        uid = int(meta.get('x-account-meta-uid', 0))
247 51f905a2 Giorgos Verigakis
        gid = int(meta.get('x-account-meta-gid', 0))
248 2152daa0 Giorgos Verigakis
        size = int(meta.get('content-length', 0))
249 51f905a2 Giorgos Verigakis
        
250 51f905a2 Giorgos Verigakis
        if meta['content-type'] == 'application/directory':
251 2152daa0 Giorgos Verigakis
            mode = int(meta.get('x-object-meta-mode', 0755))
252 51f905a2 Giorgos Verigakis
            flags = S_IFDIR
253 51f905a2 Giorgos Verigakis
            nlink = 2
254 51f905a2 Giorgos Verigakis
        else:
255 2152daa0 Giorgos Verigakis
            mode = int(meta.get('x-object-meta-mode', 0644))
256 51f905a2 Giorgos Verigakis
            flags = S_IFREG
257 51f905a2 Giorgos Verigakis
            nlink = 1
258 51f905a2 Giorgos Verigakis
        
259 51f905a2 Giorgos Verigakis
        return {
260 51f905a2 Giorgos Verigakis
            'st_mode': flags | mode,
261 51f905a2 Giorgos Verigakis
            'st_nlink': nlink,
262 51f905a2 Giorgos Verigakis
            'st_uid': uid,
263 51f905a2 Giorgos Verigakis
            'st_gid': gid,
264 51f905a2 Giorgos Verigakis
            'st_ctime': epoch,
265 51f905a2 Giorgos Verigakis
            'st_mtime': modified,
266 51f905a2 Giorgos Verigakis
            'st_atime': modified,
267 51f905a2 Giorgos Verigakis
            'st_size': size}
268 51f905a2 Giorgos Verigakis
    
269 51f905a2 Giorgos Verigakis
    def object_getxattr(self, container, object, name, position=0):
270 51f905a2 Giorgos Verigakis
        meta = self._get_object_meta(container, object, restricted=True)
271 51f905a2 Giorgos Verigakis
        return meta.get('xattr-' + name, '')
272 51f905a2 Giorgos Verigakis
    
273 51f905a2 Giorgos Verigakis
    def object_listxattr(self, container, object):
274 51f905a2 Giorgos Verigakis
        meta = self._get_object_meta(container, object, restricted=True)
275 51f905a2 Giorgos Verigakis
        prefix = 'xattr-'
276 51f905a2 Giorgos Verigakis
        return [k[len(prefix):] for k in meta if k.startswith(prefix)]
277 51f905a2 Giorgos Verigakis
    
278 51f905a2 Giorgos Verigakis
    def object_mkdir(self, container, object, mode):
279 71c0f614 Giorgos Verigakis
        mode = str(mode & 0777)
280 51f905a2 Giorgos Verigakis
        self.client.create_directory_marker(container, object)
281 51f905a2 Giorgos Verigakis
        self.client.update_object_metadata(container, object, mode=mode)
282 51f905a2 Giorgos Verigakis
    
283 51f905a2 Giorgos Verigakis
    def object_read(self, container, object, nbyte, offset, fh):
284 51f905a2 Giorgos Verigakis
        data = self.client.retrieve_object(container, object)
285 51f905a2 Giorgos Verigakis
        return data[offset:offset + nbyte]
286 51f905a2 Giorgos Verigakis
    
287 51f905a2 Giorgos Verigakis
    def object_readdir(self, container, object, fh):
288 2152daa0 Giorgos Verigakis
        objects = self.client.list_objects(container, delimiter='/',
289 2152daa0 Giorgos Verigakis
                                            prefix=object)
290 51f905a2 Giorgos Verigakis
        files = [o.rpartition('/')[2] for o in objects if not o.endswith('/')]
291 51f905a2 Giorgos Verigakis
        return ['.', '..'] + files
292 51f905a2 Giorgos Verigakis
    
293 51f905a2 Giorgos Verigakis
    def object_removexattr(self, container, object, name):
294 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
295 51f905a2 Giorgos Verigakis
        self.client.delete_object_metadata(container, object, [attr])
296 51f905a2 Giorgos Verigakis
    
297 51f905a2 Giorgos Verigakis
    def object_rename(self, container, object, path):
298 51f905a2 Giorgos Verigakis
        new_container, sep, new_object = path[1:].partition('/')
299 51f905a2 Giorgos Verigakis
        if not new_container or not new_object:
300 51f905a2 Giorgos Verigakis
            raise FuseOSError(EINVAL)
301 51f905a2 Giorgos Verigakis
        self.client.move_object(container, object, new_container, new_object)
302 51f905a2 Giorgos Verigakis
    
303 51f905a2 Giorgos Verigakis
    def object_rmdir(self, container, object):
304 51f905a2 Giorgos Verigakis
        self.client.delete_object(container, object)
305 51f905a2 Giorgos Verigakis
    
306 51f905a2 Giorgos Verigakis
    def object_setxattr(self, container, object, name, value, options,
307 51f905a2 Giorgos Verigakis
                        position=0):
308 51f905a2 Giorgos Verigakis
        attr = 'xattr-' + name
309 51f905a2 Giorgos Verigakis
        meta = {attr: value}
310 51f905a2 Giorgos Verigakis
        self.client.update_object_metadata(container, object, **meta)
311 51f905a2 Giorgos Verigakis
    
312 51f905a2 Giorgos Verigakis
    def object_truncate(self, container, object, length, fh=None):
313 51f905a2 Giorgos Verigakis
        data = self.client.retrieve_object(container, object)
314 51f905a2 Giorgos Verigakis
        f = StringIO(data[:length])
315 51f905a2 Giorgos Verigakis
        self.client.update_object(container, object, f)
316 51f905a2 Giorgos Verigakis
    
317 51f905a2 Giorgos Verigakis
    def object_unlink(self, container, object):
318 51f905a2 Giorgos Verigakis
        self.client.delete_object(container, object)
319 51f905a2 Giorgos Verigakis
    
320 51f905a2 Giorgos Verigakis
    def object_write(self, container, object, data, offset, fh):
321 51f905a2 Giorgos Verigakis
        f = StringIO(data)
322 71c0f614 Giorgos Verigakis
        self.client.update_object(container, object, f, offset=offset)
323 51f905a2 Giorgos Verigakis
        return len(data)
324 51f905a2 Giorgos Verigakis
325 51f905a2 Giorgos Verigakis
326 2152daa0 Giorgos Verigakis
if __name__ == '__main__':
327 2152daa0 Giorgos Verigakis
    if len(argv) != 2:
328 2152daa0 Giorgos Verigakis
        print 'usage: %s <mountpoint>' % argv[0]
329 51f905a2 Giorgos Verigakis
        exit(1)
330 51f905a2 Giorgos Verigakis
    
331 51f905a2 Giorgos Verigakis
    user = getuser()
332 2152daa0 Giorgos Verigakis
    fs = StoreFS(verbose=True)
333 2152daa0 Giorgos Verigakis
    fuse = FUSE(fs, argv[1], foreground=True)