Implement OS::Cinder::VolumeAttachment
This creates a new volume attachment resource with Cinder specific naming. Change-Id: Ie73b929925c58e47f3509d57dd385cbd4ea5a4c1
This commit is contained in:
parent
19dccd770c
commit
5a8f731eeb
@ -102,7 +102,7 @@ class Volume(resource.Resource):
|
||||
|
||||
if vol.status == 'in-use':
|
||||
logger.warn('cant delete volume when in-use')
|
||||
raise exception.Error("Volume in use")
|
||||
raise exception.Error('Volume in use')
|
||||
|
||||
self.cinder().volumes.delete(self.resource_id)
|
||||
except clients.cinderclient.exceptions.NotFound:
|
||||
@ -123,17 +123,18 @@ class VolumeAttachment(resource.Resource):
|
||||
'Required': True},
|
||||
'VolumeId': {'Type': 'String',
|
||||
'Required': True},
|
||||
'Device': {'Type': "String",
|
||||
'Device': {'Type': 'String',
|
||||
'Required': True,
|
||||
'AllowedPattern': '/dev/vd[b-z]'}}
|
||||
|
||||
def __init__(self, name, json_snippet, stack):
|
||||
super(VolumeAttachment, self).__init__(name, json_snippet, stack)
|
||||
_instance_property = 'InstanceId'
|
||||
_volume_property = 'VolumeId'
|
||||
_device_property = 'Device'
|
||||
|
||||
def handle_create(self):
|
||||
server_id = self.properties['InstanceId']
|
||||
volume_id = self.properties['VolumeId']
|
||||
dev = self.properties['Device']
|
||||
server_id = self.properties[self._instance_property]
|
||||
volume_id = self.properties[self._volume_property]
|
||||
dev = self.properties[self._device_property]
|
||||
inst = self.stack.clients.attach_volume_to_instance(server_id,
|
||||
volume_id,
|
||||
dev)
|
||||
@ -143,8 +144,8 @@ class VolumeAttachment(resource.Resource):
|
||||
return self.UPDATE_REPLACE
|
||||
|
||||
def handle_delete(self):
|
||||
server_id = self.properties['InstanceId']
|
||||
volume_id = self.properties['VolumeId']
|
||||
server_id = self.properties[self._instance_property]
|
||||
volume_id = self.properties[self._volume_property]
|
||||
self.stack.clients.detach_volume_from_instance(server_id, volume_id)
|
||||
|
||||
|
||||
@ -200,9 +201,24 @@ class CinderVolume(Volume):
|
||||
return unicode(getattr(vol, key))
|
||||
|
||||
|
||||
class CinderVolumeAttachment(VolumeAttachment):
|
||||
|
||||
properties_schema = {'instance_uuid': {'Type': 'String',
|
||||
'Required': True},
|
||||
'volume_id': {'Type': 'String',
|
||||
'Required': True},
|
||||
'mountpoint': {'Type': 'String',
|
||||
'Required': True}}
|
||||
|
||||
_instance_property = 'instance_uuid'
|
||||
_volume_property = 'volume_id'
|
||||
_device_property = 'mountpoint'
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
return {
|
||||
'AWS::EC2::Volume': Volume,
|
||||
'AWS::EC2::VolumeAttachment': VolumeAttachment,
|
||||
'OS::Cinder::Volume': CinderVolume,
|
||||
'OS::Cinder::VolumeAttachment': CinderVolumeAttachment,
|
||||
}
|
||||
|
@ -225,7 +225,6 @@ class VolumeTest(HeatTestCase):
|
||||
|
||||
# create script
|
||||
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
|
||||
#clients.OpenStackClients.cinder().MultipleTimes().AndReturn(self.fc)
|
||||
eventlet.sleep(1).MultipleTimes().AndReturn(None)
|
||||
self.fc.volumes.create_server_volume(
|
||||
device=u'/dev/vdc',
|
||||
@ -505,6 +504,61 @@ class VolumeTest(HeatTestCase):
|
||||
'The Referenced Attribute (DataVolume unknown) is incorrect.',
|
||||
str(error))
|
||||
|
||||
def test_cinder_attachment(self):
|
||||
fv = FakeVolume('creating', 'available')
|
||||
fva = FakeVolume('attaching', 'in-use')
|
||||
stack_name = 'test_volume_attach_stack'
|
||||
|
||||
# volume create
|
||||
clients.OpenStackClients.cinder().MultipleTimes().AndReturn(
|
||||
self.cinder_fc)
|
||||
self.cinder_fc.volumes.create(
|
||||
size=u'1', availability_zone='nova',
|
||||
display_description='%s.DataVolume' % stack_name,
|
||||
display_name='%s.DataVolume' % stack_name).AndReturn(fv)
|
||||
|
||||
# create script
|
||||
clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc)
|
||||
eventlet.sleep(1).MultipleTimes().AndReturn(None)
|
||||
self.fc.volumes.create_server_volume(
|
||||
device=u'/dev/vdc',
|
||||
server_id=u'WikiDatabase',
|
||||
volume_id=u'vol-123').AndReturn(fva)
|
||||
|
||||
self.cinder_fc.volumes.get('vol-123').AndReturn(fva)
|
||||
|
||||
# delete script
|
||||
fva = FakeVolume('in-use', 'available')
|
||||
self.fc.volumes.delete_server_volume('WikiDatabase',
|
||||
'vol-123').AndReturn(None)
|
||||
self.cinder_fc.volumes.get('vol-123').AndReturn(fva)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
t = template_format.parse(volume_template)
|
||||
t['Resources']['DataVolume']['Properties']['AvailabilityZone'] = 'nova'
|
||||
t['Resources']['MountPoint']['Properties'] = {
|
||||
'instance_uuid': {'Ref': 'WikiDatabase'},
|
||||
'volume_id': {'Ref': 'DataVolume'},
|
||||
'mountpoint': '/dev/vdc'
|
||||
}
|
||||
stack = parse_stack(t, stack_name=stack_name)
|
||||
|
||||
scheduler.TaskRunner(stack['DataVolume'].create)()
|
||||
self.assertEqual(fv.status, 'available')
|
||||
resource = vol.CinderVolumeAttachment('MountPoint',
|
||||
t['Resources']['MountPoint'],
|
||||
stack)
|
||||
self.assertEqual(resource.validate(), None)
|
||||
scheduler.TaskRunner(resource.create)()
|
||||
self.assertEqual(resource.state, vol.VolumeAttachment.CREATE_COMPLETE)
|
||||
|
||||
self.assertEqual(resource.handle_update({}), vol.Volume.UPDATE_REPLACE)
|
||||
|
||||
self.assertEqual(resource.delete(), None)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
|
||||
class FakeVolume:
|
||||
status = 'attaching'
|
||||
|
Loading…
Reference in New Issue
Block a user