Example #1
0
    def post(self, job: Job):
        """
        Create a new artifact for the given job.
        """
        # dont bother storing artifacts for aborted jobs
        if job.result == Result.aborted:
            return self.error('job was aborted', status=410)

        try:
            file = request.files['file']
        except KeyError:
            return self.respond({'file': 'Missing data for required field.'}, status=403)

        result = self.schema_from_request(artifact_schema)
        artifact = result.data
        artifact.job_id = job.id
        artifact.project_id = job.project_id
        artifact.organization_id = job.organization_id

        if not artifact.name:
            artifact.name = file.filename

        if not artifact.name:
            return self.respond({'name': 'Missing data for required field.'}, status=403)

        try:
            db.session.add(artifact)
            db.session.flush()
        except IntegrityError:
            db.session.rollback()
            exists = True
        else:
            exists = False

        if exists:
            # XXX(dcramer): this is more of an error but we make an assumption
            # that this happens because it was already sent
            return self.error('An artifact with this name already exists', 204)

        artifact.file.save(
            request.files['file'],
            '{0}/{1}/{2}_{3}'.format(
                job.id.hex[:4], job.id.hex[4:], artifact.id.hex, artifact.name
            ),
        )
        db.session.add(artifact)
        db.session.commit()

        process_artifact.delay(artifact_id=artifact.id)

        return self.respond_with_schema(artifact_schema, artifact, 201)
Example #2
0
    def post(self, job: Job):
        """
        Create a new artifact for the given job.

        File can either be passed via standard multi-part form-data, or as a JSON value:

        >>> {
        >>>   "name": "junit.xml",
        >>>   "file": <base64-encoded string>
        >>> }
        """
        # dont bother storing artifacts for aborted jobs
        if job.result == Result.aborted:
            return self.error('job was aborted', status=410)

        if request.content_type == 'application/json':
            # file must be base64 encoded
            file_data = request.json.get('file')
            if not file_data:
                return self.respond({'file': 'Missing file content.'}, status=403)
            file = FileStorage(BytesIO(b64decode(file_data)),
                               request.json.get('name'))
        else:
            try:
                file = request.files['file']
            except KeyError:
                return self.respond({'file': 'Missing data for required field.'}, status=403)

        result = self.schema_from_request(artifact_schema)
        artifact = result.data
        artifact.job_id = job.id
        artifact.repository_id = job.repository_id
        artifact.status = Status.queued

        if not artifact.name:
            artifact.name = file.filename

        if not artifact.name:
            return self.respond({'name': 'Missing data for required field.'}, status=403)

        try:
            db.session.add(artifact)
            db.session.flush()
        except IntegrityError:
            db.session.rollback()
            exists = True
        else:
            exists = False

        if exists:
            # XXX(dcramer): this is more of an error but we make an assumption
            # that this happens because it was already sent
            return self.error('An artifact with this name already exists', 204)

        artifact.file.save(
            file,
            '{0}/{1}/{2}_{3}'.format(
                job.id.hex[:4], job.id.hex[4:], artifact.id.hex, artifact.name
            ),
        )
        db.session.add(artifact)
        db.session.commit()

        process_artifact.delay(artifact_id=artifact.id)

        return self.respond_with_schema(artifact_schema, artifact, 201)