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}
Ejemplo n.º 2
0
    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}
Ejemplo n.º 3
0
    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}
Ejemplo n.º 4
0
    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}