def assemble_dif(project_id, name, checksum, chunks, **kwargs): from sentry.models import ChunkFileState, debugfile, Project, \ set_assemble_status, BadDif from sentry.reprocessing import bump_reprocessing_revision with configure_scope() as scope: scope.set_tag("project", project_id) project = Project.objects.filter(id=project_id).get() set_assemble_status(project, checksum, ChunkFileState.ASSEMBLING) # Assemble the chunks into files rv = assemble_file(project, name, checksum, chunks, file_type='project.dif') # If not file has been created this means that the file failed to # assemble because of bad input data. Return. if rv is None: return file, temp_file = rv delete_file = True try: with temp_file: # We only permit split difs to hit this endpoint. The # client is required to split them up first or we error. try: result = debugfile.detect_dif_from_path(temp_file.name) except BadDif as e: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=e.args[0]) return if len(result) != 1: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail='Contained wrong number of ' 'architectures (expected one, got %s)' % len(result)) return dif_type, cpu, file_id, filename, data = result[0] dif, created = debugfile.create_dif_from_id( project, dif_type, cpu, file_id, data, os.path.basename(name), file=file) indicate_success = True delete_file = False if created: # Bump the reprocessing revision since the symbol has changed # and might resolve processing issues. If the file was not # created, someone else has created it and will bump the # revision instead. bump_reprocessing_revision(project) if indicate_success: set_assemble_status(project, checksum, ChunkFileState.OK) finally: if delete_file: file.delete()
def assemble_dif(project_id, name, checksum, chunks, debug_id=None, **kwargs): """ Assembles uploaded chunks into a ``ProjectDebugFile``. """ from sentry.models import BadDif, Project, debugfile from sentry.reprocessing import bump_reprocessing_revision with configure_scope() as scope: scope.set_tag("project", project_id) delete_file = False try: project = Project.objects.filter(id=project_id).get() set_assemble_status(AssembleTask.DIF, project_id, checksum, ChunkFileState.ASSEMBLING) # Assemble the chunks into a temporary file rv = assemble_file(AssembleTask.DIF, project, name, checksum, chunks, file_type="project.dif") # If not file has been created this means that the file failed to # assemble because of bad input data. In this case, assemble_file # has set the assemble status already. if rv is None: return file, temp_file = rv delete_file = True with temp_file: # We only permit split difs to hit this endpoint. The # client is required to split them up first or we error. try: result = debugfile.detect_dif_from_path(temp_file.name, name=name, debug_id=debug_id) except BadDif as e: set_assemble_status(AssembleTask.DIF, project_id, checksum, ChunkFileState.ERROR, detail=e.args[0]) return if len(result) != 1: detail = "Object contains %s architectures (1 expected)" % len( result) set_assemble_status(AssembleTask.DIF, project_id, checksum, ChunkFileState.ERROR, detail=detail) return dif, created = debugfile.create_dif_from_id(project, result[0], file=file) delete_file = False if created: # Bump the reprocessing revision since the symbol has changed # and might resolve processing issues. If the file was not # created, someone else has created it and will bump the # revision instead. bump_reprocessing_revision(project) except BaseException: set_assemble_status( AssembleTask.DIF, project_id, checksum, ChunkFileState.ERROR, detail="internal server error", ) logger.error("failed to assemble dif", exc_info=True) else: set_assemble_status(AssembleTask.DIF, project_id, checksum, ChunkFileState.OK, detail=serialize(dif)) finally: if delete_file: file.delete()
def assemble_dif(project_id, name, checksum, chunks, **kwargs): from sentry.models import ChunkFileState, debugfile, Project, \ ProjectDebugFile, set_assemble_status, BadDif from sentry.reprocessing import bump_reprocessing_revision project = Project.objects.filter(id=project_id).get() set_assemble_status(project, checksum, ChunkFileState.ASSEMBLING) # Assemble the chunks into files rv = assemble_file(project, name, checksum, chunks, file_type='project.dif') # If not file has been created this means that the file failed to # assemble because of bad input data. Return. if rv is None: return file, temp_file = rv delete_file = True try: with temp_file: # We only permit split difs to hit this endpoint. The # client is required to split them up first or we error. try: result = debugfile.detect_dif_from_path(temp_file.name) except BadDif as e: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=e.args[0]) return if len(result) != 1: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail='Contained wrong number of ' 'architectures (expected one, got %s)' % len(result)) return dif_type, cpu, file_id, filename, data = result[0] dif, created = debugfile.create_dif_from_id( project, dif_type, cpu, file_id, data, os.path.basename(name), file=file) indicate_success = True delete_file = False if created: # Bump the reprocessing revision since the symbol has changed # and might resolve processing issues. If the file was not # created, someone else has created it and will bump the # revision instead. bump_reprocessing_revision(project) # Try to generate caches from this DIF immediately. If this # fails, we can capture the error and report it to the uploader. # Also, we remove the file to prevent it from erroring again. error = ProjectDebugFile.difcache.generate_caches(project, dif, temp_file.name) if error is not None: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=error) indicate_success = False dif.delete() if indicate_success: set_assemble_status(project, checksum, ChunkFileState.OK) finally: if delete_file: file.delete()
def assemble_dif(project_id, name, checksum, chunks, **kwargs): from sentry.models import ChunkFileState, debugfile, Project, \ ProjectDebugFile, set_assemble_status, BadDif from sentry.reprocessing import bump_reprocessing_revision with configure_scope() as scope: scope.set_tag("project", project_id) project = Project.objects.filter(id=project_id).get() set_assemble_status(project, checksum, ChunkFileState.ASSEMBLING) # Assemble the chunks into files rv = assemble_file(project, name, checksum, chunks, file_type='project.dif') # If not file has been created this means that the file failed to # assemble because of bad input data. Return. if rv is None: return file, temp_file = rv delete_file = True try: with temp_file: # We only permit split difs to hit this endpoint. The # client is required to split them up first or we error. try: result = debugfile.detect_dif_from_path(temp_file.name, name=name) except BadDif as e: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=e.args[0]) return if len(result) != 1: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail='Contained wrong number of ' 'architectures (expected one, got %s)' % len(result)) return dif, created = debugfile.create_dif_from_id(project, result[0], file=file) indicate_success = True delete_file = False if created: # Bump the reprocessing revision since the symbol has changed # and might resolve processing issues. If the file was not # created, someone else has created it and will bump the # revision instead. bump_reprocessing_revision(project) # Try to generate caches from this DIF immediately. If this # fails, we can capture the error and report it to the uploader. # Also, we remove the file to prevent it from erroring again. error = ProjectDebugFile.difcache.generate_caches(project, dif, temp_file.name) if error is not None: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=error) indicate_success = False dif.delete() if indicate_success: set_assemble_status(project, checksum, ChunkFileState.OK, detail=serialize(dif)) finally: if delete_file: file.delete()
def assemble_dif(project_id, name, checksum, chunks, **kwargs): from sentry.models import ChunkFileState, debugfile, Project, \ ProjectDebugFile, set_assemble_status, BadDif from sentry.reprocessing import bump_reprocessing_revision project = Project.objects.filter(id=project_id).get() set_assemble_status(project, checksum, ChunkFileState.ASSEMBLING) # Assemble the chunks into files rv = assemble_file(project, name, checksum, chunks, file_type='project.dif') # If not file has been created this means that the file failed to # assemble because of bad input data. Return. if rv is None: return file, temp_file = rv delete_file = True try: with temp_file: # We only permit split difs to hit this endpoint. The # client is required to split them up first or we error. try: result = debugfile.detect_dif_from_path(temp_file.name) except BadDif as e: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=e.args[0]) return if len(result) != 1: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail='Contained wrong number of ' 'architectures (expected one, got %s)' % len(result)) return dif_type, cpu, file_id, filename = result[0] dif, created = debugfile.create_dif_from_id( project, dif_type, cpu, file_id, os.path.basename(name), file=file) delete_file = False bump_reprocessing_revision(project) indicate_success = True # If we need to write a symcache we can use the # `generate_symcache` method to attempt to write one. # This way we can also capture down the error if we need # to. if dif.supports_symcache: symcache, error = ProjectDebugFile.difcache.generate_symcache( project, dif, temp_file) if error is not None: set_assemble_status(project, checksum, ChunkFileState.ERROR, detail=error) indicate_success = False dif.delete() if indicate_success: set_assemble_status(project, checksum, ChunkFileState.OK) finally: if delete_file: file.delete()