Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / manage_accounts / __init__.py @ 54b7d9b0

History | View | Annotate | Download (15.9 kB)

1 94bff756 Sofia Papagiannaki
# Copyright 2012 GRNET S.A. All rights reserved.
2 94bff756 Sofia Papagiannaki
#
3 94bff756 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 94bff756 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 94bff756 Sofia Papagiannaki
# conditions are met:
6 94bff756 Sofia Papagiannaki
#
7 94bff756 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 94bff756 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 94bff756 Sofia Papagiannaki
#      disclaimer.
10 94bff756 Sofia Papagiannaki
#
11 94bff756 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 94bff756 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 94bff756 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 94bff756 Sofia Papagiannaki
#      provided with the distribution.
15 94bff756 Sofia Papagiannaki
#
16 94bff756 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 94bff756 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 94bff756 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 94bff756 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 94bff756 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 94bff756 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 94bff756 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 94bff756 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 94bff756 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 94bff756 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 94bff756 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 94bff756 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 94bff756 Sofia Papagiannaki
#
29 94bff756 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 94bff756 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 94bff756 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 94bff756 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 94bff756 Sofia Papagiannaki
34 94bff756 Sofia Papagiannaki
import re
35 94bff756 Sofia Papagiannaki
import os
36 94bff756 Sofia Papagiannaki
37 3248f20a Sofia Papagiannaki
from functools import wraps
38 3248f20a Sofia Papagiannaki
39 1acbcc7e Sofia Papagiannaki
os.environ['DJANGO_SETTINGS_MODULE'] = 'synnefo.settings'
40 1acbcc7e Sofia Papagiannaki
41 ed2064f8 Christos Stavrakakis
from pithos.api.util import (get_backend, split_container_object_string,
42 ed2064f8 Christos Stavrakakis
                             Checksum, NoChecksum)
43 ed2064f8 Christos Stavrakakis
44 94bff756 Sofia Papagiannaki
45 94bff756 Sofia Papagiannaki
def data_read_iterator(str, size=1024):
46 94bff756 Sofia Papagiannaki
    offset = 0
47 94bff756 Sofia Papagiannaki
    while True:
48 94bff756 Sofia Papagiannaki
        data = str[offset:offset + size]
49 94bff756 Sofia Papagiannaki
        offset = offset + size
50 94bff756 Sofia Papagiannaki
        if not data:
51 94bff756 Sofia Papagiannaki
            break
52 94bff756 Sofia Papagiannaki
        yield data
53 94bff756 Sofia Papagiannaki
54 94bff756 Sofia Papagiannaki
55 3248f20a Sofia Papagiannaki
def manage_transactions(lock_container_path=False):
56 3248f20a Sofia Papagiannaki
    """Decorator function for ManageAccounts methods."""
57 3248f20a Sofia Papagiannaki
    def decorator(func):
58 3248f20a Sofia Papagiannaki
        @wraps(func)
59 3248f20a Sofia Papagiannaki
        def wrapper(self, *args, **kwargs):
60 3248f20a Sofia Papagiannaki
            self.backend.pre_exec(lock_container_path)
61 3248f20a Sofia Papagiannaki
            try:
62 3248f20a Sofia Papagiannaki
                result = func(self, *args, **kwargs)
63 3248f20a Sofia Papagiannaki
            except:
64 3248f20a Sofia Papagiannaki
                self.backend.post_exec(False)
65 3248f20a Sofia Papagiannaki
                raise
66 3248f20a Sofia Papagiannaki
            else:
67 3248f20a Sofia Papagiannaki
                dry = kwargs.get('dry', False)
68 3248f20a Sofia Papagiannaki
                if dry:
69 3248f20a Sofia Papagiannaki
                    self.backend.post_exec(False)
70 3248f20a Sofia Papagiannaki
                else:
71 3248f20a Sofia Papagiannaki
                    self.backend.post_exec(True)
72 3248f20a Sofia Papagiannaki
                return result
73 3248f20a Sofia Papagiannaki
        return wrapper
74 3248f20a Sofia Papagiannaki
    return decorator
75 3248f20a Sofia Papagiannaki
76 3248f20a Sofia Papagiannaki
77 ae6199c5 Sofia Papagiannaki
class ManageAccounts():
78 94bff756 Sofia Papagiannaki
    def __init__(self):
79 94bff756 Sofia Papagiannaki
        self.backend = get_backend()
80 94bff756 Sofia Papagiannaki
81 94bff756 Sofia Papagiannaki
    def cleanup(self):
82 94bff756 Sofia Papagiannaki
        self.backend.close()
83 94bff756 Sofia Papagiannaki
84 3248f20a Sofia Papagiannaki
    def _existing_accounts(self):
85 3248f20a Sofia Papagiannaki
        l = sorted([path for path, _ in self.backend.node.node_accounts()])
86 3248f20a Sofia Papagiannaki
        return l
87 3248f20a Sofia Papagiannaki
88 3248f20a Sofia Papagiannaki
    @manage_transactions()
89 94bff756 Sofia Papagiannaki
    def existing_accounts(self):
90 3248f20a Sofia Papagiannaki
        return self._existing_accounts()
91 94bff756 Sofia Papagiannaki
92 3248f20a Sofia Papagiannaki
    @manage_transactions()
93 94bff756 Sofia Papagiannaki
    def duplicate_accounts(self):
94 3248f20a Sofia Papagiannaki
        accounts = self._existing_accounts()
95 94bff756 Sofia Papagiannaki
        duplicates = []
96 94bff756 Sofia Papagiannaki
        for i in range(len(accounts)):
97 94bff756 Sofia Papagiannaki
            account = accounts[i]
98 94bff756 Sofia Papagiannaki
            matcher = re.compile(account, re.IGNORECASE)
99 3248f20a Sofia Papagiannaki
            duplicate = filter(matcher.match, (i for i in accounts[i + 1:] if
100 3248f20a Sofia Papagiannaki
                                               len(i) == len(account)))
101 94bff756 Sofia Papagiannaki
            if duplicate:
102 94bff756 Sofia Papagiannaki
                duplicate.insert(0, account)
103 94bff756 Sofia Papagiannaki
                duplicates.append(duplicate)
104 94bff756 Sofia Papagiannaki
        return duplicates
105 94bff756 Sofia Papagiannaki
106 3248f20a Sofia Papagiannaki
    def _list_all_containers(self, account, step=10):
107 94bff756 Sofia Papagiannaki
        containers = []
108 94bff756 Sofia Papagiannaki
        marker = None
109 94bff756 Sofia Papagiannaki
        while 1:
110 94bff756 Sofia Papagiannaki
            more = self.backend.list_containers(account, account, limit=10,
111 94bff756 Sofia Papagiannaki
                                                marker=marker)
112 94bff756 Sofia Papagiannaki
            if not more:
113 94bff756 Sofia Papagiannaki
                break
114 94bff756 Sofia Papagiannaki
            containers.extend(more)
115 94bff756 Sofia Papagiannaki
            marker = more[-1]
116 94bff756 Sofia Papagiannaki
        return containers
117 94bff756 Sofia Papagiannaki
118 3248f20a Sofia Papagiannaki
    @manage_transactions()
119 3248f20a Sofia Papagiannaki
    def list_all_containers(self, account, step=10):
120 3248f20a Sofia Papagiannaki
        return self._list_all_containers(account, step)
121 3248f20a Sofia Papagiannaki
122 3248f20a Sofia Papagiannaki
    def _list_all_container_objects(self, account, container, virtual=False):
123 94bff756 Sofia Papagiannaki
        objects = []
124 94bff756 Sofia Papagiannaki
        marker = None
125 94bff756 Sofia Papagiannaki
        while 1:
126 94bff756 Sofia Papagiannaki
            more = self.backend.list_objects(account, account, container,
127 94bff756 Sofia Papagiannaki
                                             marker=marker, virtual=virtual)
128 94bff756 Sofia Papagiannaki
            if not more:
129 94bff756 Sofia Papagiannaki
                break
130 94bff756 Sofia Papagiannaki
            objects.extend((i[0] for i in more))
131 94bff756 Sofia Papagiannaki
            marker = more[-1][0]
132 94bff756 Sofia Papagiannaki
        return objects
133 94bff756 Sofia Papagiannaki
134 3248f20a Sofia Papagiannaki
    @manage_transactions()
135 3248f20a Sofia Papagiannaki
    def list_all_container_objects(self, account, container, virtual=False):
136 3248f20a Sofia Papagiannaki
        return self._list_all_container_objects(account, container, virtual)
137 3248f20a Sofia Papagiannaki
138 3248f20a Sofia Papagiannaki
    def _list_all_objects(self, account, virtual=False):
139 3248f20a Sofia Papagiannaki
        containers = self._list_all_containers(account)
140 94bff756 Sofia Papagiannaki
        objects = []
141 94bff756 Sofia Papagiannaki
        extend = objects.extend
142 94bff756 Sofia Papagiannaki
        for c in containers:
143 3248f20a Sofia Papagiannaki
            more = self._list_all_container_objects(account, c,
144 3248f20a Sofia Papagiannaki
                                                    virtual=virtual)
145 94bff756 Sofia Papagiannaki
            extend([os.path.join(c, i) for i in more])
146 94bff756 Sofia Papagiannaki
        return objects
147 94bff756 Sofia Papagiannaki
148 3248f20a Sofia Papagiannaki
    @manage_transactions()
149 3248f20a Sofia Papagiannaki
    def list_all_objects(self, account, virtual=False):
150 3248f20a Sofia Papagiannaki
        return self._list_all_objects(account, virtual)
151 3248f20a Sofia Papagiannaki
152 3248f20a Sofia Papagiannaki
    def _list_past_versions(self, account, container, name):
153 94bff756 Sofia Papagiannaki
        versions = self.backend.list_versions(account, account, container,
154 94bff756 Sofia Papagiannaki
                                              name)
155 94bff756 Sofia Papagiannaki
        # do not return the current version
156 94bff756 Sofia Papagiannaki
        return list(x[0] for x in versions[:-1])
157 94bff756 Sofia Papagiannaki
158 3248f20a Sofia Papagiannaki
    @manage_transactions()
159 3248f20a Sofia Papagiannaki
    def list_past_versions(self, account, container, name):
160 3248f20a Sofia Papagiannaki
        return self._list_past_versions(account, container, name)
161 3248f20a Sofia Papagiannaki
162 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
163 3248f20a Sofia Papagiannaki
    def move_object(self, src_account, src_container, src_name, dest_account,
164 3248f20a Sofia Papagiannaki
                    dry=True, silent=False):
165 3248f20a Sofia Papagiannaki
        if src_account not in self._existing_accounts():
166 99c11993 Sofia Papagiannaki
            raise NameError('%s does not exist' % src_account)
167 3248f20a Sofia Papagiannaki
        if dest_account not in self._existing_accounts():
168 99c11993 Sofia Papagiannaki
            raise NameError('%s does not exist' % dest_account)
169 94bff756 Sofia Papagiannaki
170 3046f62c Sofia Papagiannaki
        trans = self.backend.wrapper.conn.begin()
171 94bff756 Sofia Papagiannaki
        try:
172 99c11993 Sofia Papagiannaki
            self._copy_object(src_account, src_container, src_name,
173 99c11993 Sofia Papagiannaki
                              dest_account, move=True)
174 94bff756 Sofia Papagiannaki
175 94bff756 Sofia Papagiannaki
            if dry:
176 94bff756 Sofia Papagiannaki
                if not silent:
177 94bff756 Sofia Papagiannaki
                    print "Skipping database commit."
178 3046f62c Sofia Papagiannaki
                trans.rollback()
179 94bff756 Sofia Papagiannaki
            else:
180 3046f62c Sofia Papagiannaki
                trans.commit()
181 94bff756 Sofia Papagiannaki
                if not silent:
182 94bff756 Sofia Papagiannaki
                    print "%s is deleted." % src_account
183 94bff756 Sofia Papagiannaki
        except:
184 3046f62c Sofia Papagiannaki
            trans.rollback()
185 94bff756 Sofia Papagiannaki
            raise
186 94bff756 Sofia Papagiannaki
187 99c11993 Sofia Papagiannaki
    def _copy_object(self, src_account, src_container, src_name,
188 3248f20a Sofia Papagiannaki
                     dest_account, move=False):
189 94bff756 Sofia Papagiannaki
        path = os.path.join(src_container, src_name)
190 94bff756 Sofia Papagiannaki
        fullpath = os.path.join(src_account, path)
191 94bff756 Sofia Papagiannaki
        dest_container = src_container
192 94bff756 Sofia Papagiannaki
        dest_name = src_name
193 94bff756 Sofia Papagiannaki
194 94bff756 Sofia Papagiannaki
        meta = self.backend.get_object_meta(src_account, src_account,
195 94bff756 Sofia Papagiannaki
                                            src_container, src_name, 'pithos',
196 94bff756 Sofia Papagiannaki
                                            version=None)
197 94bff756 Sofia Papagiannaki
        content_type = meta.get('type')
198 94bff756 Sofia Papagiannaki
199 94bff756 Sofia Papagiannaki
        # get source object history
200 3248f20a Sofia Papagiannaki
        versions = self._list_past_versions(src_account, src_container,
201 3248f20a Sofia Papagiannaki
                                            src_name)
202 94bff756 Sofia Papagiannaki
203 94bff756 Sofia Papagiannaki
        # get source object permissions
204 94bff756 Sofia Papagiannaki
        permissions = self.backend.permissions.access_get(fullpath)
205 94bff756 Sofia Papagiannaki
206 94bff756 Sofia Papagiannaki
        # get source object public
207 94bff756 Sofia Papagiannaki
        public = self.backend.get_object_public(src_account, src_account,
208 94bff756 Sofia Papagiannaki
                                                src_container, src_name)
209 94bff756 Sofia Papagiannaki
210 94bff756 Sofia Papagiannaki
        if dest_container in self.backend.list_containers(dest_account,
211 94bff756 Sofia Papagiannaki
                                                          dest_account):
212 94bff756 Sofia Papagiannaki
            # Note: if dest_container contains an object with the same name
213 94bff756 Sofia Papagiannaki
            # a new version with the contents of the source object will be
214 94bff756 Sofia Papagiannaki
            # created and the one in the destination container will pass to
215 94bff756 Sofia Papagiannaki
            # history
216 94bff756 Sofia Papagiannaki
            self.backend.copy_object(dest_account, src_account, src_container,
217 94bff756 Sofia Papagiannaki
                                     src_name, dest_account, dest_container,
218 94bff756 Sofia Papagiannaki
                                     dest_name, content_type, 'pithos',
219 94bff756 Sofia Papagiannaki
                                     meta={}, replace_meta=False,
220 94bff756 Sofia Papagiannaki
                                     permissions=permissions)
221 94bff756 Sofia Papagiannaki
        else:
222 94bff756 Sofia Papagiannaki
            # create destination container and retry
223 94bff756 Sofia Papagiannaki
            self.backend.put_container(dest_account, dest_account,
224 94bff756 Sofia Papagiannaki
                                       dest_container)
225 94bff756 Sofia Papagiannaki
            self.backend.copy_object(dest_account, src_account, src_container,
226 94bff756 Sofia Papagiannaki
                                     src_name, dest_account, dest_container,
227 94bff756 Sofia Papagiannaki
                                     dest_name, content_type, 'pithos',
228 94bff756 Sofia Papagiannaki
                                     meta={}, replace_meta=False,
229 94bff756 Sofia Papagiannaki
                                     permissions=permissions)
230 94bff756 Sofia Papagiannaki
231 99c11993 Sofia Papagiannaki
        if move:
232 99c11993 Sofia Papagiannaki
            self.backend.delete_object(src_account, src_account,
233 99c11993 Sofia Papagiannaki
                                       src_container, src_name)
234 94bff756 Sofia Papagiannaki
235 94bff756 Sofia Papagiannaki
        dest_path, dest_node = self.backend._lookup_object(dest_account,
236 94bff756 Sofia Papagiannaki
                                                           dest_container,
237 94bff756 Sofia Papagiannaki
                                                           dest_name)
238 94bff756 Sofia Papagiannaki
        assert dest_path == '/'.join([dest_account, path])
239 94bff756 Sofia Papagiannaki
240 94bff756 Sofia Papagiannaki
        # turn history versions to point to the newly created node
241 94bff756 Sofia Papagiannaki
        for serial in versions:
242 94bff756 Sofia Papagiannaki
            self.backend.node.version_put_property(serial, 'node', dest_node)
243 94bff756 Sofia Papagiannaki
244 94bff756 Sofia Papagiannaki
        if public:
245 94bff756 Sofia Papagiannaki
            # set destination object public
246 94bff756 Sofia Papagiannaki
            fullpath = '/'.join([dest_account, dest_container, dest_name])
247 56f3c759 Sofia Papagiannaki
            self.backend.permissions.public_set(
248 56f3c759 Sofia Papagiannaki
                fullpath,
249 4a105ce2 Sofia Papagiannaki
                self.backend.public_url_security,
250 56f3c759 Sofia Papagiannaki
                self.backend.public_url_alphabet
251 56f3c759 Sofia Papagiannaki
            )
252 94bff756 Sofia Papagiannaki
253 99c11993 Sofia Papagiannaki
    def _merge_account(self, src_account, dest_account, delete_src=False):
254 94bff756 Sofia Papagiannaki
            # TODO: handle exceptions
255 94bff756 Sofia Papagiannaki
            # copy all source objects
256 3248f20a Sofia Papagiannaki
            for path in self._list_all_objects(src_account):
257 94bff756 Sofia Papagiannaki
                src_container, src_name = split_container_object_string(
258 94bff756 Sofia Papagiannaki
                    '/%s' % path)
259 94bff756 Sofia Papagiannaki
260 94bff756 Sofia Papagiannaki
                # give read permissions to the dest_account
261 99c11993 Sofia Papagiannaki
                permissions = self.backend.get_object_permissions(
262 94bff756 Sofia Papagiannaki
                    src_account, src_account, src_container, src_name)
263 94bff756 Sofia Papagiannaki
                if permissions:
264 94bff756 Sofia Papagiannaki
                    permissions = permissions[2]
265 94bff756 Sofia Papagiannaki
                permissions['read'] = permissions.get('read', [])
266 94bff756 Sofia Papagiannaki
                permissions['read'].append(dest_account)
267 94bff756 Sofia Papagiannaki
                self.backend.update_object_permissions(src_account,
268 94bff756 Sofia Papagiannaki
                                                       src_account,
269 94bff756 Sofia Papagiannaki
                                                       src_container,
270 94bff756 Sofia Papagiannaki
                                                       src_name,
271 94bff756 Sofia Papagiannaki
                                                       permissions)
272 94bff756 Sofia Papagiannaki
273 99c11993 Sofia Papagiannaki
                self._copy_object(src_account, src_container, src_name,
274 3248f20a Sofia Papagiannaki
                                  dest_account, move=delete_src)
275 94bff756 Sofia Papagiannaki
276 94bff756 Sofia Papagiannaki
            # move groups also
277 94bff756 Sofia Papagiannaki
            groups = self.backend.get_account_groups(src_account, src_account)
278 94bff756 Sofia Papagiannaki
            (v.replace(src_account, dest_account) for v in groups.values())
279 94bff756 Sofia Papagiannaki
            self.backend.update_account_groups(dest_account, dest_account,
280 94bff756 Sofia Papagiannaki
                                               groups)
281 99c11993 Sofia Papagiannaki
            if delete_src:
282 99c11993 Sofia Papagiannaki
                self._delete_account(src_account)
283 94bff756 Sofia Papagiannaki
284 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
285 94bff756 Sofia Papagiannaki
    def merge_account(self, src_account, dest_account, only_stats=True,
286 99c11993 Sofia Papagiannaki
                      dry=True, silent=False, delete_src=False):
287 3248f20a Sofia Papagiannaki
        if src_account not in self._existing_accounts():
288 99c11993 Sofia Papagiannaki
            raise NameError('%s does not exist' % src_account)
289 3248f20a Sofia Papagiannaki
        if dest_account not in self._existing_accounts():
290 99c11993 Sofia Papagiannaki
            raise NameError('%s does not exist' % dest_account)
291 99c11993 Sofia Papagiannaki
292 94bff756 Sofia Papagiannaki
        if only_stats:
293 94bff756 Sofia Papagiannaki
            print "The following %s's entries will be moved to %s:" \
294 94bff756 Sofia Papagiannaki
                % (src_account, dest_account)
295 3248f20a Sofia Papagiannaki
            print "Objects: %r" % self._list_all_objects(src_account)
296 94bff756 Sofia Papagiannaki
            print "Groups: %r" \
297 94bff756 Sofia Papagiannaki
                % self.backend.get_account_groups(src_account,
298 94bff756 Sofia Papagiannaki
                                                  src_account).keys()
299 94bff756 Sofia Papagiannaki
            return
300 3248f20a Sofia Papagiannaki
        self._merge_account(src_account, dest_account, delete_src)
301 94bff756 Sofia Papagiannaki
302 3046f62c Sofia Papagiannaki
        trans = self.backend.wrapper.conn.begin()
303 94bff756 Sofia Papagiannaki
        try:
304 99c11993 Sofia Papagiannaki
            self._merge_account(src_account, dest_account, delete_src)
305 94bff756 Sofia Papagiannaki
306 94bff756 Sofia Papagiannaki
            if dry:
307 94bff756 Sofia Papagiannaki
                if not silent:
308 94bff756 Sofia Papagiannaki
                    print "Skipping database commit."
309 3046f62c Sofia Papagiannaki
                trans.rollback()
310 94bff756 Sofia Papagiannaki
            else:
311 3046f62c Sofia Papagiannaki
                trans.commit()
312 94bff756 Sofia Papagiannaki
                if not silent:
313 99c11993 Sofia Papagiannaki
                    msg = "%s merged into %s."
314 94bff756 Sofia Papagiannaki
                    print msg % (src_account, dest_account)
315 94bff756 Sofia Papagiannaki
        except:
316 3046f62c Sofia Papagiannaki
            trans.rollback()
317 94bff756 Sofia Papagiannaki
            raise
318 94bff756 Sofia Papagiannaki
319 3248f20a Sofia Papagiannaki
    def _delete_container_contents(self, account, container):
320 94bff756 Sofia Papagiannaki
        self.backend.delete_container(account, account, container,
321 94bff756 Sofia Papagiannaki
                                      delimiter='/')
322 94bff756 Sofia Papagiannaki
323 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
324 3248f20a Sofia Papagiannaki
    def delete_container_contents(self, account, container):
325 3248f20a Sofia Papagiannaki
        return self._delete_container(account, account, container,
326 3248f20a Sofia Papagiannaki
                                      delimiter='/')
327 3248f20a Sofia Papagiannaki
328 3248f20a Sofia Papagiannaki
    def _delete_container(self, account, container):
329 94bff756 Sofia Papagiannaki
        self.backend.delete_container(account, account, container)
330 94bff756 Sofia Papagiannaki
331 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
332 3248f20a Sofia Papagiannaki
    def delete_container(self, account, container):
333 3248f20a Sofia Papagiannaki
        self._delete_container(account, account, container)
334 3248f20a Sofia Papagiannaki
335 94bff756 Sofia Papagiannaki
    def _delete_account(self, account):
336 3248f20a Sofia Papagiannaki
        for c in self._list_all_containers(account):
337 3248f20a Sofia Papagiannaki
            self._delete_container_contents(account, c)
338 3248f20a Sofia Papagiannaki
            self._delete_container(account, c)
339 94bff756 Sofia Papagiannaki
        self.backend.delete_account(account, account)
340 94bff756 Sofia Papagiannaki
341 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
342 94bff756 Sofia Papagiannaki
    def delete_account(self, account, only_stats=True, dry=True, silent=False):
343 3248f20a Sofia Papagiannaki
        if account not in self._existing_accounts():
344 99c11993 Sofia Papagiannaki
            raise NameError('%s does not exist' % account)
345 94bff756 Sofia Papagiannaki
        if only_stats:
346 94bff756 Sofia Papagiannaki
            print "The following %s's entries will be removed:" % account
347 3248f20a Sofia Papagiannaki
            print "Objects: %r" % self._list_all_objects(account)
348 94bff756 Sofia Papagiannaki
            print "Groups: %r" \
349 94bff756 Sofia Papagiannaki
                % self.backend.get_account_groups(account, account).keys()
350 94bff756 Sofia Papagiannaki
            return
351 3248f20a Sofia Papagiannaki
        self._delete_account(account)
352 94bff756 Sofia Papagiannaki
353 3046f62c Sofia Papagiannaki
        trans = self.backend.wrapper.conn.begin()
354 94bff756 Sofia Papagiannaki
        try:
355 94bff756 Sofia Papagiannaki
            self._delete_account(account)
356 94bff756 Sofia Papagiannaki
357 94bff756 Sofia Papagiannaki
            if dry:
358 94bff756 Sofia Papagiannaki
                if not silent:
359 94bff756 Sofia Papagiannaki
                    print "Skipping database commit."
360 3046f62c Sofia Papagiannaki
                trans.rollback()
361 94bff756 Sofia Papagiannaki
            else:
362 3046f62c Sofia Papagiannaki
                trans.commit()
363 94bff756 Sofia Papagiannaki
                if not silent:
364 94bff756 Sofia Papagiannaki
                    print "%s is deleted." % account
365 94bff756 Sofia Papagiannaki
        except:
366 3046f62c Sofia Papagiannaki
            trans.rollback()
367 94bff756 Sofia Papagiannaki
            raise
368 94bff756 Sofia Papagiannaki
369 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
370 94bff756 Sofia Papagiannaki
    def create_account(self, account):
371 94bff756 Sofia Papagiannaki
        return self.backend._lookup_account(account, create=True)
372 94bff756 Sofia Papagiannaki
373 3248f20a Sofia Papagiannaki
    @manage_transactions(lock_container_path=True)
374 94bff756 Sofia Papagiannaki
    def create_update_object(self, account, container, name, content_type,
375 133e3fcf Sofia Papagiannaki
                             data, meta=None, permissions=None,
376 133e3fcf Sofia Papagiannaki
                             request_user=None,
377 133e3fcf Sofia Papagiannaki
                             checksum_compute_class=NoChecksum):
378 78348987 Sofia Papagiannaki
        meta = meta or {}
379 78348987 Sofia Papagiannaki
        permissions = permissions or {}
380 133e3fcf Sofia Papagiannaki
381 3248f20a Sofia Papagiannaki
        assert checksum_compute_class in (
382 3248f20a Sofia Papagiannaki
            NoChecksum, Checksum), 'Invalid checksum_compute_class'
383 133e3fcf Sofia Papagiannaki
        checksum_compute = checksum_compute_class()
384 94bff756 Sofia Papagiannaki
        size = 0
385 94bff756 Sofia Papagiannaki
        hashmap = []
386 94bff756 Sofia Papagiannaki
        for block_data in data_read_iterator(data, self.backend.block_size):
387 94bff756 Sofia Papagiannaki
            size += len(block_data)
388 94bff756 Sofia Papagiannaki
            hashmap.append(self.backend.put_block(block_data))
389 133e3fcf Sofia Papagiannaki
            checksum_compute.update(block_data)
390 94bff756 Sofia Papagiannaki
391 133e3fcf Sofia Papagiannaki
        checksum = checksum_compute.hexdigest()
392 94bff756 Sofia Papagiannaki
393 94bff756 Sofia Papagiannaki
        request_user = request_user or account
394 94bff756 Sofia Papagiannaki
        return self.backend.update_object_hashmap(request_user, account,
395 94bff756 Sofia Papagiannaki
                                                  container, name, size,
396 94bff756 Sofia Papagiannaki
                                                  content_type, hashmap,
397 94bff756 Sofia Papagiannaki
                                                  checksum, 'pithos', meta,
398 94bff756 Sofia Papagiannaki
                                                  True, permissions)