Example #1
0
def archive_builds_task(days=14, limit=200, include_cold=False, delete=False):
    """
    Find stale builds and remove build paths.

    :arg days: Find builds older than `days` days.
    :arg include_cold: If True, include builds that are already in cold storage
    :arg delete: If True, deletes BuildCommand objects after archiving them
    """
    max_date = datetime.now() - timedelta(days=days)
    queryset = Build.objects.exclude(commands__isnull=True)
    if not include_cold:
        queryset = queryset.exclude(cold_storage=True)
    queryset = queryset.filter(date__lt=max_date)[:limit]

    for build in queryset:
        data = BuildSerializer(build).data['commands']
        if data:
            for cmd in data:
                if len(cmd['output']) > MAX_BUILD_COMMAND_SIZE:
                    cmd['output'] = cmd['output'][-MAX_BUILD_COMMAND_SIZE:]
                    cmd['output'] = "... (truncated) ...\n\nCommand output too long. Truncated to last 1MB.\n\n" + cmd['output']  # noqa
                    log.warning('Truncating build command for build. build=%s', build.pk)
            output = BytesIO()
            output.write(json.dumps(data).encode('utf8'))
            output.seek(0)
            filename = '{date}/{id}.json'.format(date=str(build.date.date()), id=build.id)
            try:
                build_commands_storage.save(name=filename, content=output)
                build.cold_storage = True
                build.save()
                if delete:
                    build.commands.all().delete()
            except IOError:
                log.exception('Cold Storage save failure')
Example #2
0
def archive_builds_task(self, days=14, limit=200, delete=False):
    """
    Task to archive old builds to cold storage.

    :arg days: Find builds older than `days` days.
    :arg delete: If True, deletes BuildCommand objects after archiving them
    """
    if not settings.RTD_SAVE_BUILD_COMMANDS_TO_STORAGE:
        return

    lock_id = '{0}-lock'.format(self.name)
    with memcache_lock(lock_id, self.app.oid) as acquired:
        if not acquired:
            log.warning('Archive Builds Task still locked')
            return False

        max_date = timezone.now() - timezone.timedelta(days=days)
        queryset = (Build.objects.exclude(cold_storage=True).filter(
            date__lt=max_date).prefetch_related('commands').only(
                'date', 'cold_storage')[:limit])

        for build in queryset:
            commands = BuildCommandSerializer(build.commands, many=True).data
            if commands:
                for cmd in commands:
                    if len(cmd['output']) > MAX_BUILD_COMMAND_SIZE:
                        cmd['output'] = cmd['output'][-MAX_BUILD_COMMAND_SIZE:]
                        cmd['output'] = "... (truncated) ...\n\nCommand output too long. Truncated to last 1MB.\n\n" + cmd[
                            'output']  # noqa
                        log.warning('Truncating build command for build.',
                                    build_id=build.id)
                output = BytesIO(json.dumps(commands).encode('utf8'))
                filename = '{date}/{id}.json'.format(date=str(
                    build.date.date()),
                                                     id=build.id)
                try:
                    build_commands_storage.save(name=filename, content=output)
                    if delete:
                        build.commands.all().delete()
                except IOError:
                    log.exception('Cold Storage save failure')
                    continue

            build.cold_storage = True
            build.save()