Merge lp:~vishvananda/nova/fix-describe-images into lp:~hudson-openstack/nova/trunk

Proposed by Vish Ishaya
Status: Merged
Approved by: Devin Carlen
Approved revision: 934
Merged at revision: 961
Proposed branch: lp:~vishvananda/nova/fix-describe-images
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 560 lines (+123/-122)
12 files modified
bin/nova-manage (+20/-20)
nova/api/ec2/cloud.py (+38/-16)
nova/api/openstack/servers.py (+1/-1)
nova/image/fake.py (+3/-3)
nova/image/glance.py (+4/-27)
nova/image/local.py (+13/-3)
nova/image/s3.py (+6/-36)
nova/image/service.py (+27/-0)
nova/tests/api/openstack/test_image_metadata.py (+0/-2)
nova/tests/api/openstack/test_servers.py (+7/-9)
nova/tests/image/test_glance.py (+4/-4)
nova/virt/libvirt_conn.py (+0/-1)
To merge this branch: bzr merge lp:~vishvananda/nova/fix-describe-images
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Brian Lamar (community) Needs Information
Devin Carlen (community) Approve
termie (community) Needs Fixing
Review via email: mp+55617@code.launchpad.net

Description of the change

Fixes issues with describe instances due to improperly set metadata.

 * Removes image['properties']['type']
 * Uses image['container_format'] to key display of type and create ec2 ids.
 * Defaults to 'ami' if container_format cannot be deduced. This allows
   bare images to show up in describe instances and be launched even though they
   are not officially in 'ami' format.
 * Changes nova-manage register to set proper container format
 * Fixes tests
 * Fixes _do_get_kernel_and_ramdisk in openstack api to only try to get them if it is a true 'ami'
 * Replaces 'owner_id' with 'project_id' since that is expected by glance code
 * Moves the filtering scheme to base image service so all services filter the same way

To post a comment you must log in.
Revision history for this message
termie (termie) wrote :

- _image_ec2_id's docstring needs punctuation.
- image_register's docstring needs the closing quotes moved down a bit.

why did we change the argument order of image_register? is that method being tested anywhere? it seems like a possible compat issue so it'd be nice to know how far reaching it is

review: Needs Fixing
Revision history for this message
Vish Ishaya (vishvananda) wrote :

On Mar 30, 2011, at 1:41 PM, termie wrote:

> Review: Needs Fixing
> - _image_ec2_id's docstring needs punctuation.

Fixed.

> - image_register's docstring needs the closing quotes moved down a bit.

The docstrings in nova manage are displayed to the user, so they are all in this format. I'll go ahead and change this one, but it needs a whole-file cleanup.

>
> why did we change the argument order of image_register? is that method being tested anywhere? it seems like a possible compat issue so it'd be nice to know how far reaching it is

The old ordering made it impossible to register images with no kernel and ramdisk and a different format, because there isn't a way to pass "None" through nova-manage.
No other code is using this. It is user-facing. We don't have tests for nova-manage, and this is something that should be addressed, but I'm not sure that it is in the scope of this patch.

> --
> https://code.launchpad.net/~vishvananda/nova/fix-describe-images/+merge/55617
> You are the owner of lp:~vishvananda/nova/fix-describe-images.

Revision history for this message
Devin Carlen (devcamcar) wrote :

nice, lgtm!

review: Approve
Revision history for this message
Brian Lamar (blamar) wrote :

I see the initialism 'AMI' being used in non-EC2-specific code (bin/nova-manage), is AMI being used here as an analogue for "some sort of machine image"? If so, is there any way to better indicate a generic machine image. Sometimes I look at the code and see abbreviations such as AMI/ARI/AKI and I assume we're talking about Amazon-specific images.

> (is_public == 'T')

Can this just be a boolean?

review: Needs Information
Revision history for this message
Vish Ishaya (vishvananda) wrote :

> I see the initialism 'AMI' being used in non-EC2-specific code (bin/nova-
> manage), is AMI being used here as an analogue for "some sort of machine
> image"? If so, is there any way to better indicate a generic machine image.
> Sometimes I look at the code and see abbreviations such as AMI/ARI/AKI and I
> assume we're talking about Amazon-specific images.

AMI is supposed to only be used for images that have a separate kernel and ramdisk. Nova-manage sets the type to ami if you specify kernel and ramdisk. Otherwise it assumes a bare image.

To clients of the ec2 api, all images are displayed as ami's because there isn't really another image type shown there.

I hope that makes it clearer

>
> > (is_public == 'T')

nova-manage command line processing doesn't really support conversion to boolean, so this does the conversion to boolean from the text passed on the command line.
>
> Can this just be a boolean?

Revision history for this message
Rick Harris (rconradharris) wrote :

Looks good, thanks Vish.

review: Approve
Revision history for this message
Devin Carlen (devcamcar) wrote :

Looks like termie's concerns were addressed, so going to approve this.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (50.5 KiB)

The attempt to merge lp:~vishvananda/nova/fix-describe-images into lp:nova failed. Below is the output from the failed tests.

AccountsTest
    test_account_create OK
    test_account_delete OK
    test_account_update OK
    test_get_account OK
AdminAPITest
    test_admin_disabled OK
    test_admin_enabled OK
APITest
    test_exceptions_are_converted_to_faults OK
Test
    test_authorize_token OK
    test_authorize_user OK
    test_bad_token OK
    test_bad_user_bad_key OK
    test_bad_user_good_key OK
    test_no_user OK
    test_token_expiry OK
TestFunctional
    test_token_doesnotexist OK
    test_token_expiry OK
TestLimiter
    test_authorize_token OK
LimiterTest
    test_limiter_custom_max_limit OK
    test_limiter_limit_and_offset OK
    test_limiter_limit_medium OK
    test_limiter_limit_over_max OK
    test_limiter_limit_zero OK
    test_limiter_negative_limit OK
    test_limiter_negative_offset OK
    test_limiter_nothing OK
    test_limiter_offset_bad OK
    test_limiter_offset_blank OK
    test_limiter_offset_medium OK
    test_limiter_offset_over_max OK
    test_limiter_offset_zero OK
ActionExtensionTest
    test_extended_action OK
    test_invalid_action OK
    test_invalid_action_body OK
ExtensionControllerTest
    test_get_by_alias OK
    test_index OK
ExtensionManagerTest
    test_get_resources OK
ResourceExtensionTest
    test_get_resources OK
    test_get_resources_with_controller OK
    test_no_extension_present OK
ResponseExtensionTest
    test_get_resources_with_mgr OK
    test_get_resources_with_stub_mgr OK
TestFaults
    test_400_fault_json OK
    test_400_fault_xml ...

933. By Vish Ishaya

merged trunk

934. By Vish Ishaya

fix tests from moving access check into update and delete

Revision history for this message
Vish Ishaya (vishvananda) wrote :

My bad, forgot to update tests on my last change. Should be working now.

On Apr 7, 2011, at 3:38 PM, OpenStack Hudson wrote:

> The proposal to merge lp:~vishvananda/nova/fix-describe-images into lp:nova has been updated.
>
> Status: Approved => Needs review
>
> For more details, see:
> https://code.launchpad.net/~vishvananda/nova/fix-describe-images/+merge/55617
> --
> https://code.launchpad.net/~vishvananda/nova/fix-describe-images/+merge/55617
> You are the owner of lp:~vishvananda/nova/fix-describe-images.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/nova-manage'
2--- bin/nova-manage 2011-04-04 20:17:04 +0000
3+++ bin/nova-manage 2011-04-07 23:45:54 +0000
4@@ -894,20 +894,17 @@
5 def __init__(self, *args, **kwargs):
6 self.image_service = utils.import_object(FLAGS.image_service)
7
8- def _register(self, image_type, disk_format, container_format,
9+ def _register(self, container_format, disk_format,
10 path, owner, name=None, is_public='T',
11 architecture='x86_64', kernel_id=None, ramdisk_id=None):
12- meta = {'is_public': True,
13+ meta = {'is_public': (is_public == 'T'),
14 'name': name,
15+ 'container_format': container_format,
16 'disk_format': disk_format,
17- 'container_format': container_format,
18 'properties': {'image_state': 'available',
19- 'owner_id': owner,
20- 'type': image_type,
21+ 'project_id': owner,
22 'architecture': architecture,
23- 'image_location': 'local',
24- 'is_public': (is_public == 'T')}}
25- print image_type, meta
26+ 'image_location': 'local'}}
27 if kernel_id:
28 meta['properties']['kernel_id'] = int(kernel_id)
29 if ramdisk_id:
30@@ -932,16 +929,18 @@
31 ramdisk_id = self.ramdisk_register(ramdisk, owner, None,
32 is_public, architecture)
33 self.image_register(image, owner, name, is_public,
34- architecture, kernel_id, ramdisk_id)
35+ architecture, 'ami', 'ami',
36+ kernel_id, ramdisk_id)
37
38 def image_register(self, path, owner, name=None, is_public='T',
39- architecture='x86_64', kernel_id=None, ramdisk_id=None,
40- disk_format='ami', container_format='ami'):
41+ architecture='x86_64', container_format='bare',
42+ disk_format='raw', kernel_id=None, ramdisk_id=None):
43 """Uploads an image into the image_service
44 arguments: path owner [name] [is_public='T'] [architecture='x86_64']
45+ [container_format='bare'] [disk_format='raw']
46 [kernel_id=None] [ramdisk_id=None]
47- [disk_format='ami'] [container_format='ami']"""
48- return self._register('machine', disk_format, container_format, path,
49+ """
50+ return self._register(container_format, disk_format, path,
51 owner, name, is_public, architecture,
52 kernel_id, ramdisk_id)
53
54@@ -950,7 +949,7 @@
55 """Uploads a kernel into the image_service
56 arguments: path owner [name] [is_public='T'] [architecture='x86_64']
57 """
58- return self._register('kernel', 'aki', 'aki', path, owner, name,
59+ return self._register('aki', 'aki', path, owner, name,
60 is_public, architecture)
61
62 def ramdisk_register(self, path, owner, name=None, is_public='T',
63@@ -958,7 +957,7 @@
64 """Uploads a ramdisk into the image_service
65 arguments: path owner [name] [is_public='T'] [architecture='x86_64']
66 """
67- return self._register('ramdisk', 'ari', 'ari', path, owner, name,
68+ return self._register('ari', 'ari', path, owner, name,
69 is_public, architecture)
70
71 def _lookup(self, old_image_id):
72@@ -975,16 +974,17 @@
73 'ramdisk': 'ari'}
74 container_format = mapping[old['type']]
75 disk_format = container_format
76+ if container_format == 'ami' and not old.get('kernelId'):
77+ container_format = 'bare'
78+ disk_format = 'raw'
79 new = {'disk_format': disk_format,
80 'container_format': container_format,
81- 'is_public': True,
82+ 'is_public': old['isPublic'],
83 'name': old['imageId'],
84 'properties': {'image_state': old['imageState'],
85- 'owner_id': old['imageOwnerId'],
86+ 'project_id': old['imageOwnerId'],
87 'architecture': old['architecture'],
88- 'type': old['type'],
89- 'image_location': old['imageLocation'],
90- 'is_public': old['isPublic']}}
91+ 'image_location': old['imageLocation']}}
92 if old.get('kernelId'):
93 new['properties']['kernel_id'] = self._lookup(old['kernelId'])
94 if old.get('ramdiskId'):
95
96=== modified file 'nova/api/ec2/cloud.py'
97--- nova/api/ec2/cloud.py 2011-04-07 19:52:14 +0000
98+++ nova/api/ec2/cloud.py 2011-04-07 23:45:54 +0000
99@@ -154,7 +154,7 @@
100 floating_ip = db.instance_get_floating_address(ctxt,
101 instance_ref['id'])
102 ec2_id = ec2utils.id_to_ec2_id(instance_ref['id'])
103- image_ec2_id = self._image_ec2_id(instance_ref['image_id'], 'machine')
104+ image_ec2_id = self._image_ec2_id(instance_ref['image_id'], 'ami')
105 data = {
106 'user-data': base64.b64decode(instance_ref['user_data']),
107 'meta-data': {
108@@ -184,7 +184,7 @@
109 for image_type in ['kernel', 'ramdisk']:
110 if '%s_id' % image_type in instance_ref:
111 ec2_id = self._image_ec2_id(instance_ref['%s_id' % image_type],
112- image_type)
113+ self._image_type(image_type))
114 data['meta-data']['%s-id' % image_type] = ec2_id
115
116 if False: # TODO(vish): store ancestor ids
117@@ -875,13 +875,27 @@
118 self.compute_api.update(context, instance_id=instance_id, **kwargs)
119 return True
120
121- _type_prefix_map = {'machine': 'ami',
122- 'kernel': 'aki',
123- 'ramdisk': 'ari'}
124-
125- def _image_ec2_id(self, image_id, image_type='machine'):
126- prefix = self._type_prefix_map[image_type]
127- template = prefix + '-%08x'
128+ @staticmethod
129+ def _image_type(image_type):
130+ """Converts to a three letter image type.
131+
132+ aki, kernel => aki
133+ ari, ramdisk => ari
134+ anything else => ami
135+
136+ """
137+ if image_type == 'kernel':
138+ return 'aki'
139+ if image_type == 'ramdisk':
140+ return 'ari'
141+ if image_type not in ['aki', 'ari']:
142+ return 'ami'
143+ return image_type
144+
145+ @staticmethod
146+ def _image_ec2_id(image_id, image_type='ami'):
147+ """Returns image ec2_id using id and three letter type."""
148+ template = image_type + '-%08x'
149 return ec2utils.id_to_ec2_id(int(image_id), template=template)
150
151 def _get_image(self, context, ec2_id):
152@@ -894,27 +908,34 @@
153 def _format_image(self, image):
154 """Convert from format defined by BaseImageService to S3 format."""
155 i = {}
156- image_type = image['properties'].get('type')
157+ image_type = self._image_type(image.get('container_format'))
158 ec2_id = self._image_ec2_id(image.get('id'), image_type)
159 name = image.get('name')
160 i['imageId'] = ec2_id
161 kernel_id = image['properties'].get('kernel_id')
162 if kernel_id:
163- i['kernelId'] = self._image_ec2_id(kernel_id, 'kernel')
164+ i['kernelId'] = self._image_ec2_id(kernel_id, 'aki')
165 ramdisk_id = image['properties'].get('ramdisk_id')
166 if ramdisk_id:
167- i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ramdisk')
168+ i['ramdiskId'] = self._image_ec2_id(ramdisk_id, 'ari')
169 i['imageOwnerId'] = image['properties'].get('owner_id')
170 if name:
171 i['imageLocation'] = "%s (%s)" % (image['properties'].
172 get('image_location'), name)
173 else:
174 i['imageLocation'] = image['properties'].get('image_location')
175- i['imageState'] = image['properties'].get('image_state')
176+ # NOTE(vish): fallback status if image_state isn't set
177+ state = image.get('status')
178+ if state == 'active':
179+ state = 'available'
180+ i['imageState'] = image['properties'].get('image_state', state)
181 i['displayName'] = name
182 i['description'] = image.get('description')
183- i['imageType'] = image_type
184- i['isPublic'] = str(image['properties'].get('is_public', '')) == 'True'
185+ display_mapping = {'aki': 'kernel',
186+ 'ari': 'ramdisk',
187+ 'ami': 'machine'}
188+ i['imageType'] = display_mapping.get(image_type)
189+ i['isPublic'] = image.get('is_public') == True
190 i['architecture'] = image['properties'].get('architecture')
191 return i
192
193@@ -946,8 +967,9 @@
194 image_location = kwargs['name']
195 metadata = {'properties': {'image_location': image_location}}
196 image = self.image_service.create(context, metadata)
197+ image_type = self._image_type(image.get('container_format'))
198 image_id = self._image_ec2_id(image['id'],
199- image['properties']['type'])
200+ image_type)
201 msg = _("Registered image %(image_location)s with"
202 " id %(image_id)s") % locals()
203 LOG.audit(msg, context=context)
204
205=== modified file 'nova/api/openstack/servers.py'
206--- nova/api/openstack/servers.py 2011-04-07 23:04:43 +0000
207+++ nova/api/openstack/servers.py 2011-04-07 23:45:54 +0000
208@@ -565,7 +565,7 @@
209 _("Cannot build from image %(image_id)s, status not active") %
210 locals())
211
212- if image_meta['properties']['disk_format'] != 'ami':
213+ if image_meta.get('container_format') != 'ami':
214 return None, None
215
216 try:
217
218=== modified file 'nova/image/fake.py'
219--- nova/image/fake.py 2011-03-30 02:11:12 +0000
220+++ nova/image/fake.py 2011-04-07 23:45:54 +0000
221@@ -44,10 +44,10 @@
222 'created_at': timestamp,
223 'updated_at': timestamp,
224 'status': 'active',
225- 'type': 'machine',
226+ 'container_format': 'ami',
227+ 'disk_format': 'raw',
228 'properties': {'kernel_id': FLAGS.null_kernel,
229- 'ramdisk_id': FLAGS.null_kernel,
230- 'disk_format': 'ami'}
231+ 'ramdisk_id': FLAGS.null_kernel}
232 }
233 self.create(None, image)
234 super(FakeImageService, self).__init__()
235
236=== modified file 'nova/image/glance.py'
237--- nova/image/glance.py 2011-03-29 16:06:52 +0000
238+++ nova/image/glance.py 2011-04-07 23:45:54 +0000
239@@ -151,6 +151,8 @@
240
241 :raises NotFound if the image does not exist.
242 """
243+ # NOTE(vish): show is to check if image is available
244+ self.show(context, image_id)
245 try:
246 image_meta = self.client.update_image(image_id, image_meta, data)
247 except glance_exception.NotFound:
248@@ -165,6 +167,8 @@
249
250 :raises NotFound if the image does not exist.
251 """
252+ # NOTE(vish): show is to check if image is available
253+ self.show(context, image_id)
254 try:
255 result = self.client.delete_image(image_id)
256 except glance_exception.NotFound:
257@@ -186,33 +190,6 @@
258 image_meta = _convert_timestamps_to_datetimes(image_meta)
259 return image_meta
260
261- @staticmethod
262- def _is_image_available(context, image_meta):
263- """
264- Images are always available if they are public or if the user is an
265- admin.
266-
267- Otherwise, we filter by project_id (if present) and then fall-back to
268- images owned by user.
269- """
270- # FIXME(sirp): We should be filtering by user_id on the Glance side
271- # for security; however, we can't do that until we get authn/authz
272- # sorted out. Until then, filtering in Nova.
273- if image_meta['is_public'] or context.is_admin:
274- return True
275-
276- properties = image_meta['properties']
277-
278- if context.project_id and ('project_id' in properties):
279- return str(properties['project_id']) == str(project_id)
280-
281- try:
282- user_id = properties['user_id']
283- except KeyError:
284- return False
285-
286- return str(user_id) == str(context.user_id)
287-
288
289 # utility functions
290 def _convert_timestamps_to_datetimes(image_meta):
291
292=== modified file 'nova/image/local.py'
293--- nova/image/local.py 2011-03-23 05:50:53 +0000
294+++ nova/image/local.py 2011-04-07 23:45:54 +0000
295@@ -84,7 +84,10 @@
296 def show(self, context, image_id):
297 try:
298 with open(self._path_to(image_id)) as metadata_file:
299- return json.load(metadata_file)
300+ image_meta = json.load(metadata_file)
301+ if not self._is_image_available(context, image_meta):
302+ raise exception.NotFound
303+ return image_meta
304 except (IOError, ValueError):
305 raise exception.NotFound
306
307@@ -119,10 +122,15 @@
308 image_path = self._path_to(image_id, None)
309 if not os.path.exists(image_path):
310 os.mkdir(image_path)
311- return self.update(context, image_id, metadata, data)
312+ return self._store(context, image_id, metadata, data)
313
314 def update(self, context, image_id, metadata, data=None):
315 """Replace the contents of the given image with the new data."""
316+ # NOTE(vish): show is to check if image is available
317+ self.show(context, image_id)
318+ return self._store(context, image_id, metadata, data)
319+
320+ def _store(self, context, image_id, metadata, data=None):
321 metadata['id'] = image_id
322 try:
323 if data:
324@@ -140,9 +148,11 @@
325
326 def delete(self, context, image_id):
327 """Delete the given image.
328- Raises OSError if the image does not exist.
329+ Raises NotFound if the image does not exist.
330
331 """
332+ # NOTE(vish): show is to check if image is available
333+ self.show(context, image_id)
334 try:
335 shutil.rmtree(self._path_to(image_id, None))
336 except (IOError, ValueError):
337
338=== modified file 'nova/image/s3.py'
339--- nova/image/s3.py 2011-03-30 00:23:09 +0000
340+++ nova/image/s3.py 2011-04-07 23:45:54 +0000
341@@ -46,6 +46,7 @@
342
343
344 class S3ImageService(service.BaseImageService):
345+ """Wraps an existing image service to support s3 based register"""
346 def __init__(self, service=None, *args, **kwargs):
347 if service == None:
348 service = utils.import_object(FLAGS.image_service)
349@@ -58,52 +59,23 @@
350 return image
351
352 def delete(self, context, image_id):
353- # FIXME(vish): call to show is to check filter
354- self.show(context, image_id)
355 self.service.delete(context, image_id)
356
357 def update(self, context, image_id, metadata, data=None):
358- # FIXME(vish): call to show is to check filter
359- self.show(context, image_id)
360 image = self.service.update(context, image_id, metadata, data)
361 return image
362
363 def index(self, context):
364- images = self.service.index(context)
365- # FIXME(vish): index doesn't filter so we do it manually
366- return self._filter(context, images)
367+ return self.service.index(context)
368
369 def detail(self, context):
370- images = self.service.detail(context)
371- # FIXME(vish): detail doesn't filter so we do it manually
372- return self._filter(context, images)
373-
374- @classmethod
375- def _is_visible(cls, context, image):
376- return (context.is_admin
377- or context.project_id == image['properties']['owner_id']
378- or image['properties']['is_public'] == 'True')
379-
380- @classmethod
381- def _filter(cls, context, images):
382- filtered = []
383- for image in images:
384- if not cls._is_visible(context, image):
385- continue
386- filtered.append(image)
387- return filtered
388+ return self.service.detail(context)
389
390 def show(self, context, image_id):
391- image = self.service.show(context, image_id)
392- if not self._is_visible(context, image):
393- raise exception.NotFound
394- return image
395+ return self.service.show(context, image_id)
396
397 def show_by_name(self, context, name):
398- image = self.service.show_by_name(context, name)
399- if not self._is_visible(context, image):
400- raise exception.NotFound
401- return image
402+ return self.service.show(context, name)
403
404 @staticmethod
405 def _conn(context):
406@@ -167,7 +139,7 @@
407 arch = 'x86_64'
408
409 properties = metadata['properties']
410- properties['owner_id'] = context.project_id
411+ properties['project_id'] = context.project_id
412 properties['architecture'] = arch
413
414 if kernel_id:
415@@ -176,8 +148,6 @@
416 if ramdisk_id:
417 properties['ramdisk_id'] = ec2utils.ec2_id_to_id(ramdisk_id)
418
419- properties['is_public'] = False
420- properties['type'] = image_type
421 metadata.update({'disk_format': image_format,
422 'container_format': image_format,
423 'status': 'queued',
424
425=== modified file 'nova/image/service.py'
426--- nova/image/service.py 2011-03-24 21:13:55 +0000
427+++ nova/image/service.py 2011-04-07 23:45:54 +0000
428@@ -136,6 +136,33 @@
429 """
430 raise NotImplementedError
431
432+ @staticmethod
433+ def _is_image_available(context, image_meta):
434+ """
435+ Images are always available if they are public or if the user is an
436+ admin.
437+
438+ Otherwise, we filter by project_id (if present) and then fall-back to
439+ images owned by user.
440+ """
441+ # FIXME(sirp): We should be filtering by user_id on the Glance side
442+ # for security; however, we can't do that until we get authn/authz
443+ # sorted out. Until then, filtering in Nova.
444+ if image_meta['is_public'] or context.is_admin:
445+ return True
446+
447+ properties = image_meta['properties']
448+
449+ if context.project_id and ('project_id' in properties):
450+ return str(properties['project_id']) == str(context.project_id)
451+
452+ try:
453+ user_id = properties['user_id']
454+ except KeyError:
455+ return False
456+
457+ return str(user_id) == str(context.user_id)
458+
459 @classmethod
460 def _translate_to_base(cls, metadata):
461 """Return a metadata dictionary that is BaseImageService compliant.
462
463=== modified file 'nova/tests/api/openstack/test_image_metadata.py'
464--- nova/tests/api/openstack/test_image_metadata.py 2011-03-25 13:28:36 +0000
465+++ nova/tests/api/openstack/test_image_metadata.py 2011-04-07 23:45:54 +0000
466@@ -45,7 +45,6 @@
467 'is_public': True,
468 'deleted_at': None,
469 'properties': {
470- 'type': 'ramdisk',
471 'key1': 'value1',
472 'key2': 'value2'
473 },
474@@ -62,7 +61,6 @@
475 'is_public': True,
476 'deleted_at': None,
477 'properties': {
478- 'type': 'ramdisk',
479 'key1': 'value1',
480 'key2': 'value2'
481 },
482
483=== modified file 'nova/tests/api/openstack/test_servers.py'
484--- nova/tests/api/openstack/test_servers.py 2011-04-07 23:04:43 +0000
485+++ nova/tests/api/openstack/test_servers.py 2011-04-07 23:45:54 +0000
486@@ -1643,29 +1643,27 @@
487
488 def test_not_ami(self):
489 """Anything other than ami should return no kernel and no ramdisk"""
490- image_meta = {'id': 1, 'status': 'active',
491- 'properties': {'disk_format': 'vhd'}}
492+ image_meta = {'id': 1, 'status': 'active', 'container_format': 'vhd'}
493 kernel_id, ramdisk_id = self._get_k_r(image_meta)
494 self.assertEqual(kernel_id, None)
495 self.assertEqual(ramdisk_id, None)
496
497 def test_ami_no_kernel(self):
498 """If an ami is missing a kernel it should raise NotFound"""
499- image_meta = {'id': 1, 'status': 'active',
500- 'properties': {'disk_format': 'ami', 'ramdisk_id': 1}}
501+ image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami',
502+ 'properties': {'ramdisk_id': 1}}
503 self.assertRaises(exception.NotFound, self._get_k_r, image_meta)
504
505 def test_ami_no_ramdisk(self):
506 """If an ami is missing a ramdisk it should raise NotFound"""
507- image_meta = {'id': 1, 'status': 'active',
508- 'properties': {'disk_format': 'ami', 'kernel_id': 1}}
509+ image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami',
510+ 'properties': {'kernel_id': 1}}
511 self.assertRaises(exception.NotFound, self._get_k_r, image_meta)
512
513 def test_ami_kernel_ramdisk_present(self):
514 """Return IDs if both kernel and ramdisk are present"""
515- image_meta = {'id': 1, 'status': 'active',
516- 'properties': {'disk_format': 'ami', 'kernel_id': 1,
517- 'ramdisk_id': 2}}
518+ image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami',
519+ 'properties': {'kernel_id': 1, 'ramdisk_id': 2}}
520 kernel_id, ramdisk_id = self._get_k_r(image_meta)
521 self.assertEqual(kernel_id, 1)
522 self.assertEqual(ramdisk_id, 2)
523
524=== modified file 'nova/tests/image/test_glance.py'
525--- nova/tests/image/test_glance.py 2011-03-28 17:47:18 +0000
526+++ nova/tests/image/test_glance.py 2011-04-07 23:45:54 +0000
527@@ -209,17 +209,17 @@
528 self.assertDateTimesEmpty(image_meta)
529
530 def test_update_handles_datetimes(self):
531+ self.client.images = {'image1': self._make_datetime_fixture()}
532 self.client.update_response = self._make_datetime_fixture()
533- dummy_id = 'dummy_id'
534 dummy_meta = {}
535- image_meta = self.service.update(self.context, 'dummy_id', dummy_meta)
536+ image_meta = self.service.update(self.context, 'image1', dummy_meta)
537 self.assertDateTimesFilled(image_meta)
538
539 def test_update_handles_none_datetimes(self):
540+ self.client.images = {'image1': self._make_datetime_fixture()}
541 self.client.update_response = self._make_none_datetime_fixture()
542- dummy_id = 'dummy_id'
543 dummy_meta = {}
544- image_meta = self.service.update(self.context, 'dummy_id', dummy_meta)
545+ image_meta = self.service.update(self.context, 'image1', dummy_meta)
546 self.assertDateTimesEmpty(image_meta)
547
548 def _make_datetime_fixture(self):
549
550=== modified file 'nova/virt/libvirt_conn.py'
551--- nova/virt/libvirt_conn.py 2011-04-07 21:48:29 +0000
552+++ nova/virt/libvirt_conn.py 2011-04-07 23:45:54 +0000
553@@ -424,7 +424,6 @@
554 'container_format': base['container_format'],
555 'is_public': False,
556 'properties': {'architecture': base['architecture'],
557- 'type': base['type'],
558 'name': '%s.%s' % (base['name'], image_id),
559 'kernel_id': instance['kernel_id'],
560 'image_location': 'snapshot',