diff --git a/zuul/driver/sql/sqlreporter.py b/zuul/driver/sql/sqlreporter.py index d225fd794a..4b70e4eb64 100644 --- a/zuul/driver/sql/sqlreporter.py +++ b/zuul/driver/sql/sqlreporter.py @@ -147,13 +147,18 @@ class SQLReporter(BaseReporter): else: self.log.exception("Unable to create build") - def reportBuildEnd(self, build, tenant, final): + def reportBuildEnd(self, build, tenant, final, + missing_buildset_okay=False): for retry_count in range(self.retry_count): try: with self.connection.getSession() as db: db_build = db.getBuild(tenant=tenant, uuid=build.uuid) if not db_build: db_build = self._createBuild(db, build) + if not db_build: + if missing_buildset_okay: + return + raise Exception("Unable to create build in DB") end_time = build.end_time or time.time() end = datetime.datetime.fromtimestamp( diff --git a/zuul/scheduler.py b/zuul/scheduler.py index 7b18d9e78f..6fc6cad676 100644 --- a/zuul/scheduler.py +++ b/zuul/scheduler.py @@ -2947,13 +2947,22 @@ class Scheduler(threading.Thread): ) self._cleanupCompletedBuild(build) - # This usually happens when we have already canceled a - # build and reported stats for it, so don't send stats in - # this case. + # If we have not reported start for this build, we don't + # need to report end. If we haven't reported start, we + # won't have a build record in the DB, so we would + # normally create one and attach it to a buildset, but we + # don't know the buildset, and we don't have enough + # information to construct a buildset record from scratch. + # Indicate that is acceptable in this situation, so we + # don't throw an exception. In other words: if we don't + # have a build record in the DB here, the + # "missing_buildset_okay" flag will cause reportBuildEnd + # to do nothing. try: self.sql.reportBuildEnd( build, tenant=pipeline.tenant.name, - final=True) + final=True, + missing_buildset_okay=True) except Exception: log.exception("Error reporting build completion to DB:")