def run(self, *args, **kwargs): if not settings.RTD_SAVE_BUILD_COMMANDS_TO_STORAGE: return lock_id = '{0}-lock'.format(self.name) days = kwargs.get('days', 14) limit = kwargs.get('limit', 5000) delete = kwargs.get('delete', True) with memcache_lock(lock_id, self.app.oid) as acquired: if acquired: archive_builds_task(days=days, limit=limit, delete=delete) else: log.warning('Archive Builds Task still locked')
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()