1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
# Copyright [2010] [Anso Labs, LLC]
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
17
Simple object store using Blobs and JSON files on disk.
26
from nova import exception
27
from nova import flags
28
from nova import utils
29
from nova.objectstore import stored
33
flags.DEFINE_string('buckets_path', utils.abspath('../buckets'),
38
def __init__(self, name):
40
self.path = os.path.abspath(os.path.join(FLAGS.buckets_path, name))
41
if not self.path.startswith(os.path.abspath(FLAGS.buckets_path)) or \
42
not os.path.isdir(self.path):
43
raise exception.NotFound()
45
self.ctime = os.path.getctime(self.path)
48
return "<Bucket: %s>" % self.name
52
""" list of all buckets """
54
for fn in glob.glob("%s/*.json" % FLAGS.buckets_path):
57
name = os.path.split(fn)[-1][:-5]
58
buckets.append(Bucket(name))
65
def create(bucket_name, user):
66
"""Create a new bucket owned by a user.
68
@bucket_name: a string representing the name of the bucket to create
69
@user: a nova.auth.user who should own the bucket.
72
NotAuthorized: if the bucket is already exists or has invalid name
74
path = os.path.abspath(os.path.join(
75
FLAGS.buckets_path, bucket_name))
76
if not path.startswith(os.path.abspath(FLAGS.buckets_path)) or \
78
raise exception.NotAuthorized()
82
with open(path+'.json', 'w') as f:
83
json.dump({'ownerId': user.id}, f)
87
""" dictionary of metadata around bucket,
88
keys are 'Name' and 'CreationDate'
93
"CreationDate": datetime.datetime.utcfromtimestamp(self.ctime),
99
with open(self.path+'.json') as f:
100
return json.load(f)['ownerId']
104
def is_authorized(self, user):
106
return user.is_admin() or self.owner_id == user.id
110
def list_keys(self, prefix='', marker=None, max_keys=1000, terse=False):
112
for root, dirs, files in os.walk(self.path):
113
for file_name in files:
114
object_names.append(os.path.join(root, file_name)[len(self.path)+1:])
120
start_pos = bisect.bisect_right(object_names, marker, start_pos)
122
start_pos = bisect.bisect_left(object_names, prefix, start_pos)
125
for object_name in object_names[start_pos:]:
126
if not object_name.startswith(prefix):
128
if len(contents) >= max_keys:
131
object_path = self._object_path(object_name)
132
c = {"Key": object_name}
134
info = os.stat(object_path)
136
"LastModified": datetime.datetime.utcfromtimestamp(
138
"Size": info.st_size,
148
"IsTruncated": truncated,
149
"Contents": contents,
152
def _object_path(self, object_name):
153
fn = os.path.join(self.path, object_name)
155
if not fn.startswith(self.path):
156
raise exception.NotAuthorized()
161
if len(os.listdir(self.path)) > 0:
162
raise exception.NotAuthorized()
164
os.remove(self.path+'.json')
166
def __getitem__(self, key):
167
return stored.Object(self, key)
169
def __setitem__(self, key, value):
170
with open(self._object_path(key), 'wb') as f:
173
def __delitem__(self, key):
174
stored.Object(self, key).delete()