Esempio n. 1
0
def get_build_logs(request_id):
    """
    Retrieve the logs for the build request.

    :param int request_id: the request ID that was passed in through the URL.
    :rtype: flask.Response
    :raise NotFound: if the request is not found or there are no logs for the request
    :raise Gone: if the logs for the build request have been removed due to expiration
    """
    request_log_dir = flask.current_app.config['IIB_REQUEST_LOGS_DIR']
    if not request_log_dir:
        raise NotFound()

    request = Request.query.get_or_404(request_id)
    log_file_path = os.path.join(request_log_dir, f'{request_id}.log')
    if not os.path.exists(log_file_path):
        expired = request.logs_expiration < datetime.utcnow()
        if expired:
            raise Gone(
                f'The logs for the build request {request_id} no longer exist')
        finalized = request.state.state_name in RequestStateMapping.get_final_states(
        )
        if finalized:
            raise NotFound()
        # The request may not have been initiated yet. Return empty logs until it's processed.
        return flask.Response('', mimetype='text/plain')

    with open(log_file_path) as f:
        return flask.Response(f.read(), mimetype='text/plain')
Esempio n. 2
0
def _get_batch_state_change_envelope(batch, new_batch=False):
    """
    Generate a batch state change ``Envelope`` object.

    No message will be generated if IIB is not configured to send batch state change messages or
    no batch state change message is needed .

    :param iib.web.models.Batch batch: the batch that changed states
    :param bool new_batch: if ``True``, a new batch message will be generated; if ``False``,
        IIB will generate a batch state change message if the batch is no longer ``in_progress``
    :return: the ``Envelope`` for the batch state change or ``None``
    :rtype: Envelope or None
    """
    batch_address = current_app.config.get(
        'IIB_MESSAGING_BATCH_STATE_DESTINATION')
    if not batch_address:
        current_app.logger.debug(
            'No batch state change message will be generated since the configuration '
            '"IIB_MESSAGING_BATCH_STATE_DESTINATION" is not set')
        return

    if new_batch:
        # Avoid querying the database for the batch state since we know it's a new batch
        batch_state = 'in_progress'
    else:
        batch_state = batch.state

    if new_batch or batch_state in RequestStateMapping.get_final_states():
        current_app.logger.debug(
            'Preparing to send a state change message for batch %d', batch.id)
        batch_username = getattr(batch.user, 'username', None)
        content = {
            'batch':
            batch.id,
            'annotations':
            batch.annotations,
            'requests': [{
                'id': request.id,
                'organization': getattr(request, 'organization', None),
                'request_type': request.type_name,
            } for request in batch.requests],
            'state':
            batch_state,
            'user':
            batch_username,
        }
        properties = {
            'batch': batch.id,
            'state': batch_state,
            'user': batch_username,
        }
        return json_to_envelope(batch_address, content, properties)
Esempio n. 3
0
File: api_v1.py Progetto: zanssa/iib
def get_build_logs(request_id):
    """
    Retrieve the logs for the build request.

    :param int request_id: the request ID that was passed in through the URL.
    :rtype: flask.Response
    :raise NotFound: if the request is not found or there are no logs for the request
    :raise Gone: if the logs for the build request have been removed due to expiration
    :raise ValidationError: if the request has not completed yet
    """
    request_log_dir = flask.current_app.config['IIB_REQUEST_LOGS_DIR']
    s3_bucket_name = flask.current_app.config['IIB_AWS_S3_BUCKET_NAME']
    if not s3_bucket_name and not request_log_dir:
        raise NotFound()

    request = Request.query.get_or_404(request_id)

    finalized = request.state.state_name in RequestStateMapping.get_final_states(
    )
    if not finalized:
        raise ValidationError(
            f'The request {request_id} is not complete yet.'
            ' logs will be available once the request is complete.')

    # If S3 bucket is configured, fetch the log file from the S3 bucket.
    # Else, check if logs are stored on the system itself and return them.
    # Otherwise, raise an IIBError.
    if s3_bucket_name:
        log_file = _get_artifact_file_from_s3_bucket(
            'request_logs',
            f'{request_id}.log',
            request_id,
            request.temporary_data_expiration,
            s3_bucket_name,
        )
        return flask.Response(log_file.read(), mimetype='text/plain')

    local_log_file_path = os.path.join(request_log_dir, f'{request_id}.log')
    if not os.path.exists(local_log_file_path):
        expired = request.temporary_data_expiration < datetime.utcnow()
        if expired:
            raise Gone(
                f'The logs for the build request {request_id} no longer exist')
        flask.current_app.logger.warning(
            ' Please make sure either an S3 bucket is configured or the logs are'
            ' stored locally in a directory by specifying IIB_REQUEST_LOGS_DIR'
        )
        raise IIBError(
            'IIB is done processing the request and could not find logs.')

    with open(local_log_file_path) as f:
        return flask.Response(f.read(), mimetype='text/plain')
Esempio n. 4
0
def get_related_bundles(request_id):
    """
    Retrieve the related bundle images from the bundle CSV for a regenerate-bundle request.

    :param int request_id: the request ID that was passed in through the URL.
    :rtype: flask.Response
    :raise NotFound: if the request is not found or there are no related bundles for the request
    :raise Gone: if the related bundles for the build request have been removed due to expiration
    """
    request_related_bundles_dir = flask.current_app.config['IIB_REQUEST_RELATED_BUNDLES_DIR']
    if not request_related_bundles_dir:
        raise NotFound()

    request = Request.query.get_or_404(request_id)
    if request.type != RequestTypeMapping.regenerate_bundle.value:
        raise ValidationError(
            f'The request {request_id} is of type {request.type_name}. '
            'This endpoint is only valid for requests of type regenerate-bundle.'
        )

    finalized = request.state.state_name in RequestStateMapping.get_final_states()
    if not finalized:
        raise ValidationError(
            f'The request {request_id} is not complete yet.'
            ' related_bundles will be available once the request is complete.'
        )

    related_bundles_file_path = os.path.join(
        request_related_bundles_dir, f'{request_id}_related_bundles.json'
    )
    if not os.path.exists(related_bundles_file_path):
        expired = request.temporary_data_expiration < datetime.utcnow()
        if expired:
            raise Gone(f'The related_bundles for the build request {request_id} no longer exist')
        raise IIBError(
            'IIB is done processing the request and cannot find related_bundles. Please make '
            f'sure the iib_organizaiton_customizations for organization {request.organization}'
            ' has related_bundles customization type set'
        )

    with open(related_bundles_file_path) as f:
        return flask.Response(f.read(), mimetype='application/json')
Esempio n. 5
0
File: api_v1.py Progetto: zanssa/iib
def get_related_bundles(request_id):
    """
    Retrieve the related bundle images from the bundle CSV for a regenerate-bundle request.

    :param int request_id: the request ID that was passed in through the URL.
    :rtype: flask.Response
    :raise NotFound: if the request is not found or there are no related bundles for the request
    :raise Gone: if the related bundles for the build request have been removed due to expiration
    :raise ValidationError: if the request is of invalid type or is not completed yet
    """
    request_related_bundles_dir = flask.current_app.config[
        'IIB_REQUEST_RELATED_BUNDLES_DIR']
    s3_bucket_name = flask.current_app.config['IIB_AWS_S3_BUCKET_NAME']
    if not s3_bucket_name and not request_related_bundles_dir:
        raise NotFound()

    request = Request.query.get_or_404(request_id)
    if request.type != RequestTypeMapping.regenerate_bundle.value:
        raise ValidationError(
            f'The request {request_id} is of type {request.type_name}. '
            'This endpoint is only valid for requests of type regenerate-bundle.'
        )

    finalized = request.state.state_name in RequestStateMapping.get_final_states(
    )
    if not finalized:
        raise ValidationError(
            f'The request {request_id} is not complete yet.'
            ' related_bundles will be available once the request is complete.')

    # If S3 bucket is configured, fetch the related bundles file from the S3 bucket.
    # Else, check if related bundles are stored on the system itself and return them.
    # Otherwise, raise an IIBError.
    if s3_bucket_name:
        log_file = _get_artifact_file_from_s3_bucket(
            'related_bundles',
            f'{request_id}_related_bundles.json',
            request_id,
            request.temporary_data_expiration,
            s3_bucket_name,
        )
        return flask.Response(log_file.read(), mimetype='application/json')

    related_bundles_file_path = os.path.join(
        request_related_bundles_dir, f'{request_id}_related_bundles.json')
    if not os.path.exists(related_bundles_file_path):
        expired = request.temporary_data_expiration < datetime.utcnow()
        if expired:
            raise Gone(
                f'The related_bundles for the build request {request_id} no longer exist'
            )
        if request.organization:
            raise IIBError(
                'IIB is done processing the request and cannot find related_bundles. Please make '
                f'sure the iib_organization_customizations for organization {request.organization}'
                ' has related_bundles customization type set')
        flask.current_app.logger.warning(
            ' Please make sure either an S3 bucket is configured or the logs are'
            ' stored locally in a directory by specifying IIB_REQUEST_LOGS_DIR'
        )
        raise IIBError(
            'IIB is done processing the request and could not find related_bundles.'
        )

    with open(related_bundles_file_path) as f:
        return flask.Response(f.read(), mimetype='application/json')