storage.py 3.94 KB
Newer Older
Giorgos Verigakis's avatar
Giorgos Verigakis committed
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
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
#   1. Redistributions of source code must retain the above
#      copyright notice, this list of conditions and the following
#      disclaimer.
#
#   2. Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials
#      provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.

Giorgos Verigakis's avatar
Giorgos Verigakis committed
34
from . import Client, ClientError
Giorgos Verigakis's avatar
Giorgos Verigakis committed
35
36


Giorgos Verigakis's avatar
Giorgos Verigakis committed
37
class StorageClient(Client):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
38
39
    """OpenStack Object Storage API 1.0 client"""
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
40
41
42
43
    def __init__(self, base_url, token, account=None, container=None):
        super(StorageClient, self).__init__(base_url, token)
        self.account = account
        self.container = container
Giorgos Verigakis's avatar
Giorgos Verigakis committed
44
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
45
46
47
    def assert_account(self):
        if not self.account:
            raise ClientError("Please provide an account")
Giorgos Verigakis's avatar
Giorgos Verigakis committed
48
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
49
50
51
52
    def assert_container(self):
        self.assert_account()
        if not self.container:
            raise ClientError("Please provide a container")
Giorgos Verigakis's avatar
Giorgos Verigakis committed
53
    
54
    def create_container(self, container):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
55
        self.assert_account()
56
        path = '/%s/%s' % (self.account, container)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
57
58
59
        r = self.put(path, success=(201, 202))
        if r.status_code == 202:
            raise ClientError("Container already exists")
60
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
61
62
63
64
65
66
67
    def get_container_meta(self, container):
        self.assert_account()
        path = '/%s/%s' % (self.account, container)
        r = self.head(path, success=(204, 404))
        if r.status_code == 404:
            raise ClientError("Container does not exist", r.status_code)
        
Giorgos Verigakis's avatar
Giorgos Verigakis committed
68
69
        reply = {}
        prefix = 'x-container-'
Giorgos Verigakis's avatar
Giorgos Verigakis committed
70
        for key, val in r.headers.items():
Giorgos Verigakis's avatar
Giorgos Verigakis committed
71
72
73
            key = key.lower()
            if key.startswith(prefix):
                reply[key[len(prefix):]] = val
Giorgos Verigakis's avatar
Giorgos Verigakis committed
74
        
Giorgos Verigakis's avatar
Giorgos Verigakis committed
75
        return reply
Giorgos Verigakis's avatar
Giorgos Verigakis committed
76
    
77
78
    def create_object(self, object, f, size=None, hash_cb=None,
                      upload_cb=None):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
79
80
        # This is a naive implementation, it loads the whole file in memory
        self.assert_container()
Giorgos Verigakis's avatar
Giorgos Verigakis committed
81
        path = '/%s/%s/%s' % (self.account, self.container, object)
82
        data = f.read(size) if size is not None else f.read()
Giorgos Verigakis's avatar
Giorgos Verigakis committed
83
84
        self.put(path, data=data, success=201)
    
85
    def get_object(self, object):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
86
        self.assert_container()
87
        path = '/%s/%s/%s' % (self.account, self.container, object)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
88
        r = self.get(path, raw=True, success=200)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
89
90
91
        size = int(r.headers['content-length'])
        return r.raw, size
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
92
    def delete_object(self, object):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
93
        self.assert_container()
Giorgos Verigakis's avatar
Giorgos Verigakis committed
94
        path = '/%s/%s/%s' % (self.account, self.container, object)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
95
        self.delete(path, success=204)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
96
97
98
99
100
101
102
    
    def list_objects(self, path=''):
        self.assert_container()
        path = '/%s/%s' % (self.account, self.container)
        params = dict(format='json')
        r = self.get(path, params=params, success=(200, 204))
        return r.json