Image update works

This commit is contained in:
Brian Waldon
2012-04-03 16:00:49 -07:00
parent d5bb951e5f
commit d191262413
4 changed files with 118 additions and 21 deletions

View File

@@ -18,9 +18,11 @@ import urllib
from glanceclient.common import base
CREATE_PARAMS = ['id', 'name', 'disk_format', 'container_format', 'min_disk',
UPDATE_PARAMS = ('name', 'disk_format', 'container_format', 'min_disk',
'min_ram', 'owner', 'size', 'is_public', 'protected',
'location', 'checksum', 'copy_from', 'properties']
'location', 'checksum', 'copy_from', 'properties')
CREATE_PARAMS = UPDATE_PARAMS + ('id',)
class Image(base.Resource):
@@ -91,6 +93,8 @@ class ImageManager(base.Manager):
TODO(bcwaldon): document accepted params
"""
image_data = kwargs.pop('data', None)
fields = {}
for field in kwargs:
if field in CREATE_PARAMS:
@@ -104,16 +108,24 @@ class ImageManager(base.Manager):
if copy_from is not None:
hdrs['x-glance-api-copy-from'] = copy_from
resp, body = self.api.post('/v1/images', headers=hdrs)
resp, body = self.api.post('/v1/images', headers=hdrs, body=image_data)
return Image(self, body['image'])
def update(self, image, **kwargs):
"""Update an image"""
fields = {}
if 'name' in kwargs:
fields['name'] = kwargs['name']
send_meta = self._image_meta_to_headers(fields)
url = '/v1/images/%s' % base.getid(image)
resp, body = self.api.put(url, headers=send_meta)
recv_meta = self._image_meta_from_headers(resp)
return Image(self, recv_meta)
for field in kwargs:
if field in UPDATE_PARAMS:
fields[field] = kwargs[field]
else:
msg = 'update() got an unexpected keyword argument \'%s\''
raise TypeError(msg % field)
copy_from = fields.pop('copy_from', None)
hdrs = self._image_meta_to_headers(fields)
if copy_from is not None:
hdrs['x-glance-api-copy-from'] = copy_from
image_id = base.getid(image)
resp, body = self.api.put('/v1/images/%s' % image_id, headers=hdrs)
return Image(self, body['image'])

View File

@@ -22,7 +22,7 @@ import glanceclient.v1.images
def do_image_list(gc, args):
"""List images."""
images = gc.images.list()
columns = ['ID', 'Name', 'Disk Format', 'Container Format', 'Size']
columns = ['ID', 'Name', 'Status']
utils.print_list(images, columns)
@@ -96,6 +96,56 @@ def do_image_create(gc, args):
_image_show(image)
@utils.arg('--name', metavar='<NAME>',
help='Name of image.')
@utils.arg('--disk_format', metavar='<CONTAINER_FORMAT>',
help='Disk format of image.')
@utils.arg('--container_format', metavar='<DISK_FORMAT>',
help='Container format of image.')
@utils.arg('--owner', metavar='<TENANT_ID>',
help='Tenant who should own image.')
@utils.arg('--size', metavar='<SIZE>',
help='Size of image data (in bytes).')
@utils.arg('--min_disk', metavar='<DISK_GB>',
help='Minimum size of disk needed to boot image (in gigabytes).')
@utils.arg('--min_ram', metavar='<DISK_RAM>',
help='Minimum amount of ram needed to boot image (in megabytes).')
@utils.arg('--location', metavar='<IMAGE_URL>',
help=('URL where the data for this image already resides.'
' For example, if the image data is stored in the filesystem'
' local to the glance server at \'/usr/share/image.tar.gz\','
' you would specify \'file:///usr/share/image.tar.gz\'.'))
@utils.arg('--checksum', metavar='<CHECKSUM>',
help='Hash of image data used Glance can use for verification.')
@utils.arg('--copy_from', metavar='<IMAGE_URL>',
help=('Similar to \'--location\' in usage, but this indicates that'
' the Glance server should immediately copy the data and'
' store it in its configured image store.'))
@utils.arg('--is_public', type=bool,
help='Make image accessible to the public.')
@utils.arg('--is_protected', type=bool,
help='Prevent image from being deleted.')
@utils.arg('--property', metavar="<key=value>", action='append', default=[],
help=("Arbitrary property to associate with image. "
"May be used multiple times."))
def do_image_update(gc, args):
# Filter out None values
fields = dict(filter(lambda x: x[1] is not None, vars(args).items()))
raw_properties = fields.pop('property')
fields['properties'] = {}
for datum in raw_properties:
key, value = datum.split('=', 1)
fields['properties'][key] = value
# Filter out values we can't use
UPDATE_PARAMS = glanceclient.v1.images.UPDATE_PARAMS
fields = dict(filter(lambda x: x[0] in UPDATE_PARAMS, fields.items()))
image = gc.images.create(**fields)
_image_show(image)
@utils.arg('id', metavar='<IMAGE_ID>', help='ID of image to delete.')
def do_image_delete(gc, args):
"""Delete a specific image."""

View File

@@ -1,4 +1,5 @@
import StringIO
import unittest
from tests.v1 import utils
@@ -43,7 +44,7 @@ class ImageManagerTest(unittest.TestCase):
expect = [('DELETE', '/v1/images/1', {}, None)]
self.assertEqual(self.api.calls, expect)
def test_create_no_data(self):
def test_create_without_data(self):
params = {
'id': '1',
'name': 'image-1',
@@ -82,9 +83,37 @@ class ImageManagerTest(unittest.TestCase):
self.assertEqual(image.min_disk, '10')
self.assertEqual(image.properties, {'a': 'b', 'c': 'd'})
def test_create_with_data(self):
image_data = StringIO.StringIO('XXX')
self.mgr.create(data=image_data)
expect = [('POST', '/v1/images', {}, image_data)]
self.assertEqual(self.api.calls, expect)
def test_update(self):
image = self.mgr.update('1', name='image-2')
expect_hdrs = {'x-image-meta-name': 'image-2'}
fields = {
'name': 'image-2',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': 1024,
'min_ram': 512,
'min_disk': 10,
'copy_from': 'http://example.com',
'properties': {'a': 'b', 'c': 'd'},
}
image = self.mgr.update('1', **fields)
expect_hdrs = {
'x-image-meta-name': 'image-2',
'x-image-meta-container_format': 'ovf',
'x-image-meta-disk_format': 'vhd',
'x-image-meta-owner': 'asdf',
'x-image-meta-size': '1024',
'x-image-meta-min_ram': '512',
'x-image-meta-min_disk': '10',
'x-glance-api-copy-from': 'http://example.com',
'x-image-meta-property-a': 'b',
'x-image-meta-property-c': 'd',
}
expect = [('PUT', '/v1/images/1', expect_hdrs, None)]
self.assertEqual(self.api.calls, expect)
self.assertEqual(image.id, '1')

View File

@@ -29,7 +29,6 @@ fixtures = {
'min_ram': '512',
'min_disk': '10',
'properties': {'a': 'b', 'c': 'd'},
}}),
},
'/v1/images/detail': {
@@ -53,12 +52,19 @@ fixtures = {
},
None),
'PUT': (
{
'x-image-meta-id': '1',
'x-image-meta-name': 'image-2',
'x-image-meta-property-arch': 'x86_64',
},
None),
{},
{'image': {
'id': '1',
'name': 'image-2',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': '1024',
'min_ram': '512',
'min_disk': '10',
'properties': {'a': 'b', 'c': 'd'},
}},
),
'DELETE': ({}, None),
},
'/v1/images/1/members': {