From b24832c22aa44d2f8b5ecddaf12e7878653af28f Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Wed, 7 Nov 2012 19:39:43 +0100 Subject: [PATCH] Make image sizes more readable for humans By introducing the parameter --human-readable for several functions (image-list, image-show, image-update, image-create) it's possible to convert the size in bytes to something more readable like 9.309MB or 1.375GB. Change-Id: I4e2654994361dcf330ed6d681dbed73388f159cb --- glanceclient/common/utils.py | 12 ++++++++++++ glanceclient/v1/shell.py | 26 ++++++++++++++++++++++---- tests/test_utils.py | 5 +++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index 31b85300..628225de 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -168,3 +168,15 @@ def integrity_iter(iter, checksum): raise IOError(errno.EPIPE, 'Corrupt image download. Checksum was %s expected %s' % (md5sum, checksum)) + + +def make_size_human_readable(size): + suffix = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB'] + base = 1024.0 + + index = 0 + while size > base: + index = index + 1 + size = size / base + + return "%.3f%s" % (size, suffix[index]) diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py index 70d49338..e0e9fe81 100644 --- a/glanceclient/v1/shell.py +++ b/glanceclient/v1/shell.py @@ -54,6 +54,8 @@ DISK_FORMATS = ('Acceptable formats: ami, ari, aki, vhd, vmdk, raw, ' action='append', dest='properties', default=[]) @utils.arg('--page-size', metavar='', default=None, type=int, help='Number of images to request in each paginated request.') +@utils.arg('--human-readable', action='store_true', default=False, + help='Print image size in a human-friendly format.') def do_image_list(gc, args): """List images you can access.""" filter_keys = ['name', 'status', 'container_format', 'disk_format', @@ -71,12 +73,22 @@ def do_image_list(gc, args): images = gc.images.list(**kwargs) columns = ['ID', 'Name', 'Disk Format', 'Container Format', 'Size', 'Status'] + + if args.human_readable: + def convert_size(image): + image.size = utils.make_size_human_readable(image.size) + return image + + images = (convert_size(image) for image in images) + utils.print_list(images, columns) -def _image_show(image): +def _image_show(image, human_readable=False): # Flatten image properties dict for display info = copy.deepcopy(image._info) + if human_readable: + info['size'] = utils.make_size_human_readable(info['size']) for (k, v) in info.pop('properties').iteritems(): info['Property \'%s\'' % k] = v @@ -105,10 +117,12 @@ def _set_data_field(fields, args): @utils.arg('id', metavar='', help='ID of image to describe.') +@utils.arg('--human-readable', action='store_true', default=False, + help='Print image size in a human-friendly format.') def do_image_show(gc, args): """Describe a specific image.""" image = gc.images.get(args.id) - _image_show(image) + _image_show(image, args.human_readable) @utils.arg('--file', metavar='', @@ -165,6 +179,8 @@ def do_image_download(gc, args): @utils.arg('--property', metavar="", action='append', default=[], help=("Arbitrary property to associate with image. " "May be used multiple times.")) +@utils.arg('--human-readable', action='store_true', default=False, + help='Print image size in a human-friendly format.') def do_image_create(gc, args): """Create a new image.""" # Filter out None values @@ -188,7 +204,7 @@ def do_image_create(gc, args): _set_data_field(fields, args) image = gc.images.create(**fields) - _image_show(image) + _image_show(image, args.human_readable) @utils.arg('id', metavar='', help='ID of image to modify.') @@ -232,6 +248,8 @@ def do_image_create(gc, args): help=("If this flag is present, delete all image properties " "not explicitly set in the update request. Otherwise, " "those properties not referenced are preserved.")) +@utils.arg('--human-readable', action='store_true', default=False, + help='Print image size in a human-friendly format.') def do_image_update(gc, args): """Update a specific image.""" # Filter out None values @@ -255,7 +273,7 @@ def do_image_update(gc, args): _set_data_field(fields, args) image = gc.images.update(image_id, purge_props=args.purge_props, **fields) - _image_show(image) + _image_show(image, args.human_readable) @utils.arg('id', metavar='', nargs='+', diff --git a/tests/test_utils.py b/tests/test_utils.py index cf388bfe..d277c3c2 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -43,3 +43,8 @@ class TestUtils(unittest.TestCase): fixture = 'CCC' checksum = 'defb99e69a9f1f6e06f15006b1f166ae' data = ''.join([f for f in utils.integrity_iter(fixture, checksum)]) + + def test_make_size_human_readable(self): + self.assertEqual("1024.000kB", utils.make_size_human_readable(1048576)) + self.assertEqual("1.375GB", utils.make_size_human_readable(1476395008)) + self.assertEqual("9.309MB", utils.make_size_human_readable(9761280))