def create(self, req, server_id, body): """Attach a volume to an instance.""" context = req.environ['nova.context'] context.can(va_policies.POLICY_ROOT % 'create') volume_id = body['volumeAttachment']['volumeId'] device = body['volumeAttachment'].get('device') tag = body['volumeAttachment'].get('tag') delete_on_termination = body['volumeAttachment'].get( 'delete_on_termination', False) instance = common.get_instance(self.compute_api, context, server_id) if instance.vm_state in (vm_states.SHELVED, vm_states.SHELVED_OFFLOADED): _check_request_version(req, '2.20', 'attach_volume', server_id, instance.vm_state) try: supports_multiattach = common.supports_multiattach_volume(req) device = self.compute_api.attach_volume( context, instance, volume_id, device, tag=tag, supports_multiattach=supports_multiattach, delete_on_termination=delete_on_termination) except exception.VolumeNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except (exception.InstanceIsLocked, exception.DevicePathInUse, exception.MultiattachNotSupportedByVirtDriver) as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'attach_volume', server_id) except (exception.InvalidVolume, exception.InvalidDevicePath, exception.InvalidInput, exception.VolumeTaggedAttachNotSupported, exception.MultiattachNotSupportedOldMicroversion, exception.MultiattachToShelvedNotSupported) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) except exception.TooManyDiskDevices as e: raise exc.HTTPForbidden(explanation=e.format_message()) # The attach is async # NOTE(mriedem): It would be nice to use # _translate_attachment_summary_view here but that does not include # the 'device' key if device is None or the empty string which would # be a backward incompatible change. attachment = {} attachment['id'] = volume_id attachment['serverId'] = server_id attachment['volumeId'] = volume_id attachment['device'] = device if api_version_request.is_supported(req, '2.70'): attachment['tag'] = tag if api_version_request.is_supported(req, '2.79'): attachment['delete_on_termination'] = delete_on_termination return {'volumeAttachment': attachment}
def create(self, req, server_id, body): """Attach a volume to an instance.""" context = req.environ['nova.context'] context.can(va_policies.POLICY_ROOT % 'create') volume_id = body['volumeAttachment']['volumeId'] device = body['volumeAttachment'].get('device') tag = body['volumeAttachment'].get('tag') instance = common.get_instance(self.compute_api, context, server_id) if instance.vm_state in (vm_states.SHELVED, vm_states.SHELVED_OFFLOADED): _check_request_version(req, '2.20', 'attach_volume', server_id, instance.vm_state) try: supports_multiattach = common.supports_multiattach_volume(req) device = self.compute_api.attach_volume( context, instance, volume_id, device, tag=tag, supports_multiattach=supports_multiattach) except (exception.InstanceUnknownCell, exception.VolumeNotFound) as e: raise exc.HTTPNotFound(explanation=e.format_message()) except (exception.InstanceIsLocked, exception.DevicePathInUse, exception.MultiattachNotSupportedByVirtDriver, exception.MultiattachSupportNotYetAvailable) as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'attach_volume', server_id) except (exception.InvalidVolume, exception.InvalidDevicePath, exception.InvalidInput, exception.VolumeTaggedAttachNotSupported, exception.MultiattachNotSupportedOldMicroversion, exception.MultiattachToShelvedNotSupported) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) except exception.TooManyDiskDevices as e: raise exc.HTTPForbidden(explanation=e.format_message()) # The attach is async # NOTE(mriedem): It would be nice to use # _translate_attachment_summary_view here but that does not include # the 'device' key if device is None or the empty string which would # be a backward incompatible change. attachment = {} attachment['id'] = volume_id attachment['serverId'] = server_id attachment['volumeId'] = volume_id attachment['device'] = device if api_version_request.is_supported(req, '2.70'): attachment['tag'] = tag return {'volumeAttachment': attachment}
def create(self, req, server_id, body): """Attach a volume to an instance.""" context = req.environ['nova.context'] context.can(va_policies.POLICY_ROOT % 'create') volume_id = body['volumeAttachment']['volumeId'] device = body['volumeAttachment'].get('device') tag = body['volumeAttachment'].get('tag') instance = common.get_instance(self.compute_api, context, server_id) if instance.vm_state in (vm_states.SHELVED, vm_states.SHELVED_OFFLOADED): _check_request_version(req, '2.20', 'attach_volume', server_id, instance.vm_state) try: supports_multiattach = common.supports_multiattach_volume(req) device = self.compute_api.attach_volume( context, instance, volume_id, device, tag=tag, supports_multiattach=supports_multiattach) except (exception.InstanceUnknownCell, exception.VolumeNotFound) as e: raise exc.HTTPNotFound(explanation=e.format_message()) except (exception.InstanceIsLocked, exception.DevicePathInUse, exception.MultiattachNotSupportedByVirtDriver, exception.MultiattachSupportNotYetAvailable) as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'attach_volume', server_id) except (exception.InvalidVolume, exception.InvalidDevicePath, exception.InvalidInput, exception.VolumeTaggedAttachNotSupported, exception.MultiattachNotSupportedOldMicroversion, exception.MultiattachToShelvedNotSupported) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) except exception.TooManyDiskDevices as e: raise exc.HTTPForbidden(explanation=e.format_message()) # The attach is async attachment = {} attachment['id'] = volume_id attachment['serverId'] = server_id attachment['volumeId'] = volume_id attachment['device'] = device return {'volumeAttachment': attachment}
def create(self, req, server_id, body): """Attach a volume to an instance.""" context = req.environ['nova.context'] context.can(va_policies.POLICY_ROOT % 'create') volume_id = body['volumeAttachment']['volumeId'] device = body['volumeAttachment'].get('device') tag = body['volumeAttachment'].get('tag') instance = common.get_instance(self.compute_api, context, server_id) if instance.vm_state in (vm_states.SHELVED, vm_states.SHELVED_OFFLOADED): _check_request_version(req, '2.20', 'attach_volume', server_id, instance.vm_state) try: supports_multiattach = common.supports_multiattach_volume(req) device = self.compute_api.attach_volume( context, instance, volume_id, device, tag=tag, supports_multiattach=supports_multiattach) except (exception.InstanceUnknownCell, exception.VolumeNotFound) as e: raise exc.HTTPNotFound(explanation=e.format_message()) except (exception.InstanceIsLocked, exception.DevicePathInUse, exception.MultiattachNotSupportedByVirtDriver, exception.MultiattachSupportNotYetAvailable) as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'attach_volume', server_id) except (exception.InvalidVolume, exception.InvalidDevicePath, exception.InvalidInput, exception.TaggedAttachmentNotSupported, exception.MultiattachNotSupportedOldMicroversion, exception.MultiattachToShelvedNotSupported) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) # The attach is async attachment = {} attachment['id'] = volume_id attachment['serverId'] = server_id attachment['volumeId'] = volume_id attachment['device'] = device return {'volumeAttachment': attachment}