When I try to set a property on a glance image by POSTing to the OS API at /images/<id>/metadata, the location field is set to Null. I've put the relevant bit of the registry log below.
I've tried looking through the glance code, and I can't see exactly how this is happening. I strongly suspect it's all my fault though, as I was the one that originally filed the bug that said that the location field shouldn't be publicly visible - my guess is that it's being zeroed out somewhere and then set back. Karma :-)
2012-01-04 02:43:20 DEBUG [glance.registry.api.v1.images] Updating image 31cc48af-c5f2-ea38-dcb4-aa0fe111b213 with metadata: {u'status': u'active', u'name': u'image-1325644992887', u'deleted': False, u'checksum': u'3cb82d3c9b570e95deee6f10fca0285f', u'min_ram': u'0', u'disk_format': u'raw', u'id': u'31cc48af-c5f2-ea38-dcb4-aa0fe111b213', u'location': None, u'container_format': u'bare', u'min_disk': u'0', u'is_public': True, u'properties': {u'platformlayerid': u'org.platformlayer.ids.ProjectId [fathomdb]/org.platformlayer.ids.ServiceType [imagefactory]/org.platformlayer.ids.ItemType [diskImageRecipe]/76725505-4652-40db-a70e-1efb634f74fc'}, u'size': 404346423}
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] BEGIN (implicit)
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] SELECT images.created_at AS images_created_at, images.updated_at AS images_updated_at, images.deleted_at AS images_deleted_at, images.deleted AS images_deleted, images.id AS images_id, images.name AS images_name, images.disk_format AS images_disk_format, images.container_format AS images_container_format, images.size AS images_size, images.status AS images_status, images.is_public AS images_is_public, images.location AS images_location, images.checksum AS images_checksum, images.min_disk AS images_min_disk, images.min_ram AS images_min_ram, images.owner AS images_owner, image_properties_1.created_at AS image_properties_1_created_at, image_properties_1.updated_at AS image_properties_1_updated_at, image_properties_1.deleted_at AS image_properties_1_deleted_at, image_properties_1.deleted AS image_properties_1_deleted, image_properties_1.id AS image_properties_1_id, image_properties_1.image_id AS image_properties_1_image_id, image_properties_1.name AS image_properties_1_name, image_properties_1.value AS image_properties_1_value, image_members_1.created_at AS image_members_1_created_at, image_members_1.updated_at AS image_members_1_updated_at, image_members_1.deleted_at AS image_members_1_deleted_at, image_members_1.deleted AS image_members_1_deleted, image_members_1.id AS image_members_1_id, image_members_1.image_id AS image_members_1_image_id, image_members_1.member AS image_members_1_member, image_members_1.can_share AS image_members_1_can_share
FROM images LEFT OUTER JOIN image_properties AS image_properties_1 ON images.id = image_properties_1.image_id LEFT OUTER JOIN image_members AS image_members_1 ON images.id = image_members_1.image_id
WHERE images.id = ?
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] (u'31cc48af-c5f2-ea38-dcb4-aa0fe111b213',)
2012-01-04 02:43:20 DEBUG [sqlalchemy.engine.base.Engine] Col ('images_created_at', 'images_updated_at', 'images_deleted_at', 'images_deleted', 'images_id', 'images_name', 'images_disk_format', 'images_container_format', 'images_size', 'images_status', 'images_is_public', 'images_location', 'images_checksum', 'images_min_disk', 'images_min_ram', 'images_owner', 'image_properties_1_created_at', 'image_properties_1_updated_at', 'image_properties_1_deleted_at', 'image_properties_1_deleted', 'image_properties_1_id', 'image_properties_1_image_id', 'image_properties_1_name', 'image_properties_1_value', 'image_members_1_created_at', 'image_members_1_updated_at', 'image_members_1_deleted_at', 'image_members_1_deleted', 'image_members_1_id', 'image_members_1_image_id', 'image_members_1_member', 'image_members_1_can_share')
2012-01-04 02:43:20 DEBUG [sqlalchemy.engine.base.Engine] Row (u'2012-01-04 02:43:12.977819', u'2012-01-04 02:43:20.102921', None, 0, u'31cc48af-c5f2-ea38-dcb4-aa0fe111b213', u'image-1325644992887', u'raw', u'bare', 404346423, u'active', 1, u'file:///var/lib/glance/images/31cc48af-c5f2-ea38-dcb4-aa0fe111b213', u'3cb82d3c9b570e95deee6f10fca0285f', 0, 0, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None)
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] UPDATE images SET updated_at=?, location=?, min_disk=?, min_ram=? WHERE images.id = ?
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] ('2012-01-04 02:43:20.423022', None, u'0', u'0', u'31cc48af-c5f2-ea38-dcb4-aa0fe111b213')
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] INSERT INTO image_properties (created_at, updated_at, deleted_at, deleted, image_id, name, value) VALUES (?, ?, ?, ?, ?, ?, ?)
2012-01-04 02:43:20 INFO [sqlalchemy.engine.base.Engine] ('2012-01-04 02:43:20.424064', '2012-01-04 02:43:20.424068', None, 0, u'31cc48af-c5f2-ea38-dcb4-aa0fe111b213', u'platformlayerid', u'org.platformlayer.ids.ProjectId [fathomdb]/org.platformlayer.ids.ServiceType [imagefactory]/org.platformlayer.ids.ItemType [diskImageRecipe]/76725505-4652-40db-a70e-1efb634f74fc')
Aha.... I think the root problem is here, in nova, in nova/image/ glance. py
The metadata update fetches all the metadata, merges in the values, and then posts that to glance (which is not the strictly correct in terms of concurrent updates, but anyway...)
The problem is that the fetch returns 'Location' of None.
https:/ /github. com/openstack/ nova/blob/ master/ nova/image/ glance. py#L437
def _limit_ attributes( image_meta) : ATTRIBUTES = ['size', 'location', 'disk_format',
'container_ format' , 'checksum', 'id',
'name' , 'created_at', 'updated_at',
'deleted_ at', 'deleted', 'status',
'min_ disk', 'min_ram', 'is_public']
output[ attr] = image_meta. get(attr)
IMAGE_
output = {}
for attr in IMAGE_ATTRIBUTES:
output[ 'properties' ] = image_meta. get('properties ', {})
return output
That sets ['location'] to None; which then gets passed to the glance registry, which then updates the location to None.