diff --git a/data/database.py b/data/database.py index 28fb2ff8e..ce60de5a6 100644 --- a/data/database.py +++ b/data/database.py @@ -200,7 +200,7 @@ class User(BaseModel): # If we are deleting a robot account, only execute the subset of queries necessary. if self.robot: # For all the model dependencies, only delete those that allow robots. - for query, fk in self.dependencies(search_nullable=True): + for query, fk in reversed(list(self.dependencies(search_nullable=True))): if isinstance(fk, QuayUserField) and fk.allows_robots: model = fk.model_class @@ -395,7 +395,8 @@ class RepositoryBuildTrigger(BaseModel): private_key = TextField(null=True) config = TextField(default='{}') write_token = ForeignKeyField(AccessToken, null=True) - pull_robot = QuayUserField(allows_robots=True, null=True, related_name='triggerpullrobot') + pull_robot = QuayUserField(allows_robots=True, null=True, related_name='triggerpullrobot', + robot_null_delete=True) class EmailConfirmation(BaseModel): @@ -545,7 +546,8 @@ class RepositoryBuild(BaseModel): started = DateTimeField(default=datetime.now) display_name = CharField() trigger = ForeignKeyField(RepositoryBuildTrigger, null=True, index=True) - pull_robot = QuayUserField(null=True, related_name='buildpullrobot') + pull_robot = QuayUserField(null=True, related_name='buildpullrobot', allows_robots=True, + robot_null_delete=True) logs_archived = BooleanField(default=False) queue_id = CharField(null=True, index=True) diff --git a/test/test_api_usage.py b/test/test_api_usage.py index 4ec4348dd..35e1518a6 100644 --- a/test/test_api_usage.py +++ b/test/test_api_usage.py @@ -2308,7 +2308,14 @@ class TestOrgRobots(ApiTestCase): repo = model.get_repository(ORGANIZATION, ORG_REPO) user = model.get_user(ADMIN_ACCESS_USER) pull_robot = model.get_user(membername) - model.create_build_trigger(repo, 'fakeservice', 'sometoken', user, pull_robot=pull_robot) + trigger = model.create_build_trigger(repo, 'fakeservice', 'sometoken', user, pull_robot=pull_robot) + + # Add a fake build of the fake build trigger. + token = model.create_access_token(repo, 'write', kind='build-worker', + friendly_name='Repository Build Token') + + build = model.create_repository_build(repo, token, {}, 'fake-dockerfile', 'fake-name', trigger, + pull_robot_name=membername) # Add some log entries for the robot. model.log_action('pull_repo', ORGANIZATION, performer=pull_robot, repository=repo) @@ -2317,6 +2324,9 @@ class TestOrgRobots(ApiTestCase): self.deleteResponse(OrgRobot, params=dict(orgname=ORGANIZATION, robot_shortname='bender')) + # Verify the build is still present. + self.assertIsNotNone(model.get_repository_build(build.uuid)) + # All the above records should now be deleted, along with the robot. We verify a few of the # critical ones below.