Commit a591a7b4 authored by Giorgos Verigakis's avatar Giorgos Verigakis
Browse files

Add a store list command

parent a4f3a88e
......@@ -660,14 +660,12 @@ class glance_setmembers(object):
self.client.set_members(image_id, member)
class store_command(object):
"""base class for all store_* commands"""
class _store_account_command(object):
"""Base class for account level storage commands"""
def update_parser(cls, parser):
def update_parser(self, parser):
parser.add_option('--account', dest='account', metavar='NAME',
help="Specify an account to use")
parser.add_option('--container', dest='container', metavar='NAME',
help="Specify a container to use")
def progress(self, message):
"""Return a generator function to be used for progress tracking"""
......@@ -688,18 +686,26 @@ class store_command(object):
def main(self):
if self.options.account is not None:
self.client.account = self.options.account
class _store_container_command(_store_account_command):
"""Base class for container level storage commands"""
def update_parser(self, parser):
super(_store_container_command, self).update_parser(parser)
parser.add_option('--container', dest='container', metavar='NAME',
help="Specify a container to use")
def main(self):
super(_store_container_command, self).main()
if self.options.container is not None:
self.client.container = self.options.container
@command(api='storage')
class store_create(object):
class store_create(_store_account_command):
"""Create a container"""
def update_parser(cls, parser):
parser.add_option('--account', dest='account', metavar='NAME',
help="Specify an account to use")
def main(self, container):
if self.options.account:
self.client.account = self.options.account
......@@ -707,13 +713,9 @@ class store_create(object):
@command(api='storage')
class store_container(object):
class store_container(_store_account_command):
"""Get container info"""
def update_parser(cls, parser):
parser.add_option('--account', dest='account', metavar='NAME',
help="Specify an account to use")
def main(self, container):
if self.options.account:
self.client.account = self.options.account
......@@ -722,7 +724,29 @@ class store_container(object):
@command(api='storage')
class store_upload(store_command):
class store_list(_store_container_command):
"""List objects"""
def format_size(self, size):
units = ('B', 'K', 'M', 'G', 'T')
size = float(size)
for unit in units:
if size <= 1024:
break
size /= 1024
s = ('%.1f' % size).rstrip('.0')
return s + unit
def main(self, path=''):
super(store_list, self).main()
for object in self.client.list_objects():
size = self.format_size(object['bytes'])
print '%6s %s' % (size, object['name'])
@command(api='storage')
class store_upload(_store_container_command):
"""Upload a file"""
def main(self, path, remote_path=None):
......@@ -738,7 +762,7 @@ class store_upload(store_command):
@command(api='storage')
class store_download(store_command):
class store_download(_store_container_command):
"""Download a file"""
def main(self, remote_path, local_path='-'):
......@@ -764,7 +788,7 @@ class store_download(store_command):
@command(api='storage')
class store_delete(store_command):
class store_delete(_store_container_command):
"""Delete a file"""
def main(self, path):
......
......@@ -46,7 +46,7 @@ recvlog = logging.getLogger('clients.recv')
# Add a convenience json property to the responses
def _json(self):
try:
return json.loads(self.content)
return json.loads(self.content) if self.content else {}
except ValueError:
raise ClientError("Invalid JSON reply", self.status_code)
requests.Response.json = property(_json)
......
......@@ -94,7 +94,7 @@ class PithosClient(StorageClient):
assert size == file_size
path = '/%s/%s/%s' % (self.account, self.container, object)
params = {'hashmap': '', 'format': 'json'}
params = dict(format='json', hashmap='')
hashmap = dict(bytes=size, hashes=hashes.keys())
r = self.put(path, params=params, json=hashmap, success=(201, 409))
......
......@@ -84,7 +84,7 @@ class StorageClient(Client):
def get_object(self, object):
self.assert_container()
path = '/%s/%s/%s' % (self.account, self.container, object)
r = self.get(path, raw=True)
r = self.get(path, raw=True, success=200)
size = int(r.headers['content-length'])
return r.raw, size
......@@ -92,3 +92,10 @@ class StorageClient(Client):
self.assert_container()
path = '/%s/%s/%s' % (self.account, self.container, object)
self.delete(path, success=204)
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
......@@ -51,7 +51,7 @@ setup(
'console_scripts': ['kamaki = kamaki.cli:main']
},
install_requires=[
'requests>=0.10.2',
'requests>=0.10.6',
'clint>=0.3'
]
)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment