Revision df79206f kamaki/clients/storage.py
b/kamaki/clients/storage.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from . import ClientError |
|
35 |
from .http import HTTPClient |
|
34 |
from . import Client, ClientError |
|
36 | 35 |
|
37 | 36 |
|
38 |
class StorageClient(HTTPClient):
|
|
37 |
class StorageClient(Client): |
|
39 | 38 |
"""OpenStack Object Storage API 1.0 client""" |
40 | 39 |
|
41 |
@property |
|
42 |
def url(self): |
|
43 |
url = self.config.get('storage_url') or self.config.get('url') |
|
44 |
if not url: |
|
45 |
raise ClientError('No URL was given') |
|
46 |
return url |
|
47 |
|
|
48 |
@property |
|
49 |
def token(self): |
|
50 |
token = self.config.get('storage_token') or self.config.get('token') |
|
51 |
if not token: |
|
52 |
raise ClientError('No token was given') |
|
53 |
return token |
|
40 |
def __init__(self, base_url, token, account=None, container=None): |
|
41 |
super(StorageClient, self).__init__(base_url, token) |
|
42 |
self.account = account |
|
43 |
self.container = container |
|
54 | 44 |
|
55 |
@property |
|
56 |
def account(self): |
|
57 |
account = self.config.get('storage_account') |
|
58 |
if not account: |
|
59 |
raise ClientError('No account was given') |
|
60 |
return account |
|
45 |
def assert_account(self): |
|
46 |
if not self.account: |
|
47 |
raise ClientError("Please provide an account") |
|
61 | 48 |
|
62 |
@property |
|
63 |
def container(self): |
|
64 |
container = self.config.get('storage_container') |
|
65 |
if not container: |
|
66 |
raise ClientError('No container was given') |
|
67 |
return container |
|
49 |
def assert_container(self): |
|
50 |
self.assert_account() |
|
51 |
if not self.container: |
|
52 |
raise ClientError("Please provide a container") |
|
68 | 53 |
|
69 | 54 |
def create_container(self, container): |
55 |
self.assert_account() |
|
70 | 56 |
path = '/%s/%s' % (self.account, container) |
71 |
self.http_put(path, success=201) |
|
57 |
r = self.put(path, success=(201, 202)) |
|
58 |
if r.status_code == 202: |
|
59 |
raise ClientError("Container already exists") |
|
72 | 60 |
|
73 |
def get_container_meta(self): |
|
74 |
path = '/%s/%s' % (self.account, self.container) |
|
75 |
resp, reply = self.raw_http_cmd('HEAD', path, success=204) |
|
61 |
def get_container_meta(self, container): |
|
62 |
self.assert_account() |
|
63 |
path = '/%s/%s' % (self.account, container) |
|
64 |
r = self.head(path, success=(204, 404)) |
|
65 |
if r.status_code == 404: |
|
66 |
raise ClientError("Container does not exist", r.status_code) |
|
67 |
|
|
76 | 68 |
reply = {} |
77 | 69 |
prefix = 'x-container-' |
78 |
for key, val in resp.getheaders():
|
|
70 |
for key, val in r.headers.items():
|
|
79 | 71 |
key = key.lower() |
80 | 72 |
if key.startswith(prefix): |
81 | 73 |
reply[key[len(prefix):]] = val |
74 |
|
|
82 | 75 |
return reply |
83 | 76 |
|
84 |
def create_object(self, object, f): |
|
77 |
def create_object(self, object, f, hash_cb=None, upload_cb=None): |
|
78 |
# This is a naive implementation, it loads the whole file in memory |
|
79 |
self.assert_container() |
|
85 | 80 |
path = '/%s/%s/%s' % (self.account, self.container, object) |
86 | 81 |
data = f.read() |
87 |
self.http_put(path, data, success=201)
|
|
88 |
|
|
82 |
self.put(path, data=data, success=201)
|
|
83 |
|
|
89 | 84 |
def get_object(self, object): |
85 |
self.assert_container() |
|
90 | 86 |
path = '/%s/%s/%s' % (self.account, self.container, object) |
91 |
resp, reply = self.raw_http_cmd('GET', path, success=200,
|
|
92 |
skip_read=True)
|
|
93 |
return resp.fp
|
|
94 |
|
|
87 |
r = self.get(path, raw=True)
|
|
88 |
size = int(r.headers['content-length'])
|
|
89 |
return r.raw, size
|
|
90 |
|
|
95 | 91 |
def delete_object(self, object): |
92 |
self.assert_container() |
|
96 | 93 |
path = '/%s/%s/%s' % (self.account, self.container, object) |
97 |
self.http_delete(path) |
|
94 |
self.delete(path, success=204) |
Also available in: Unified diff