Add volume bootable information to api response

If there is any glance metadata associated with a volume, we'll consider
the volume bootable. This will return the information for both /volumes
and /detail calls.

blueprint list-bootable-volumes

Change-Id: Id9dbe5cb648be62fb19bb8bd6a97d8eab05ec25a
This commit is contained in:
Mike Perez 2012-11-18 21:27:39 -08:00
parent 3f183070f7
commit 040d9309c5
4 changed files with 46 additions and 0 deletions

View File

@ -113,6 +113,11 @@ def _translate_volume_summary_view(context, vol, image_id=None):
else:
d['metadata'] = {}
if vol.get('volume_glance_metadata'):
d['bootable'] = 'true'
else:
d['bootable'] = 'false'
return d

View File

@ -213,6 +213,11 @@ class VolumeGlanceMetadata(BASE, CinderBase):
snapshot_id = Column(String(36), ForeignKey('snapshots.id'))
key = Column(String(255))
value = Column(Text)
volume = relationship(Volume, backref="volume_glance_metadata",
foreign_keys=volume_id,
primaryjoin='and_('
'VolumeGlanceMetadata.volume_id == Volume.id,'
'VolumeGlanceMetadata.deleted == False)')
class Quota(BASE, CinderBase):

View File

@ -188,6 +188,7 @@ def stub_volume(id, **kwargs):
'mountpoint': '/',
'status': 'fakestatus',
'attach_status': 'attached',
'bootable': 'false',
'name': 'vol name',
'display_name': 'displayname',
'display_description': 'displaydesc',

View File

@ -83,6 +83,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
@ -140,6 +141,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'image_id': 'c905cedb-7281-47e4-8a62-f26bc5fc4c77',
'snapshot_id': None,
@ -219,6 +221,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'device': '/',
}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
@ -247,6 +250,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'device': '/',
}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {"qos_max_iops": 2000},
@ -295,6 +299,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
@ -317,6 +322,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
@ -398,6 +404,7 @@ class VolumeApiTest(test.TestCase):
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
@ -420,6 +427,34 @@ class VolumeApiTest(test.TestCase):
'availability_zone': 'fakeaz',
'display_name': 'displayname',
'attachments': [],
'bootable': 'false',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},
'id': '1',
'created_at': datetime.datetime(1, 1, 1,
1, 1, 1),
'size': 1}}
self.assertEqual(res_dict, expected)
def test_volume_show_bootable(self):
def stub_volume_get(self, context, volume_id):
return (fakes.stub_volume(volume_id,
volume_glance_metadata=dict(foo='bar')))
self.stubs.Set(volume_api.API, 'get', stub_volume_get)
req = fakes.HTTPRequest.blank('/v1/volumes/1')
res_dict = self.controller.show(req, '1')
expected = {'volume': {'status': 'fakestatus',
'display_description': 'displaydesc',
'availability_zone': 'fakeaz',
'display_name': 'displayname',
'attachments': [{'device': '/',
'server_id': 'fakeuuid',
'id': '1',
'volume_id': '1'}],
'bootable': 'true',
'volume_type': 'vol_type_name',
'snapshot_id': None,
'metadata': {},