Skip to content

Commit

Permalink
Reduce the number of Koji build jobs related to a sidetag(s) release (#…
Browse files Browse the repository at this point in the history
…2588)

Reduce the number of Koji build jobs related to a sidetag(s) release

Fixes #2527.

Reviewed-by: Laura Barcziová
  • Loading branch information
softwarefactory-project-zuul[bot] authored Oct 22, 2024
2 parents d613336 + 5ec4c47 commit dd074f8
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 70 deletions.
34 changes: 34 additions & 0 deletions alembic/versions/adb6be5bc358_add_sidetag_and_nvr_fields_to_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Add sidetag and nvr fields to KojiBuildTargetModel
Revision ID: adb6be5bc358
Revises: f376be1907e1
Create Date: 2024-10-20 15:47:45.454965
"""

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision = "adb6be5bc358"
down_revision = "f376be1907e1"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"koji_build_targets",
sa.Column("sidetag", sa.String(), nullable=True),
)
op.add_column("koji_build_targets", sa.Column("nvr", sa.String(), nullable=True))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("koji_build_targets", "nvr")
op.drop_column("koji_build_targets", "sidetag")
# ### end Alembic commands ###
25 changes: 25 additions & 0 deletions packit_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,9 @@ class KojiBuildTargetModel(GroupAndTargetModelConnector, Base):
# metadata is reserved to sqlalch
data = Column(JSON)

sidetag = Column(String)
nvr = Column(String)

# it is a scratch build?
scratch = Column(Boolean)
koji_build_group_id = Column(Integer, ForeignKey("koji_build_groups.id"))
Expand Down Expand Up @@ -2705,6 +2708,8 @@ def create(
status: str,
scratch: bool,
koji_build_group: "KojiBuildGroupModel",
sidetag: Optional[str] = None,
nvr: Optional[str] = None,
) -> "KojiBuildTargetModel":
with sa_session_transaction(commit=True) as session:
build = cls()
Expand All @@ -2713,6 +2718,8 @@ def create(
build.web_url = web_url
build.target = target
build.scratch = scratch
build.sidetag = sidetag
build.nvr = nvr
session.add(build)

koji_build_group.koji_build_targets.append(build)
Expand All @@ -2734,6 +2741,24 @@ def __repr__(self):
f"build_submitted_time={self.build_submitted_time})"
)

@classmethod
def get_all_successful_or_in_progress_by_nvr(
cls,
nvr: str,
) -> set["KojiBuildTargetModel"]:
with sa_session_transaction() as session:
return set(
session.query(KojiBuildTargetModel)
.filter(
KojiBuildTargetModel.nvr == nvr,
KojiBuildTargetModel.scratch == False, # noqa
KojiBuildTargetModel.status.in_(
("queued", "pending", "retry", "running", "success"),
),
)
.all(),
)

@classmethod
def get_all_projects(cls) -> set["GitProjectModel"]:
"""Get all git projects with a successful downstream koji build."""
Expand Down
73 changes: 41 additions & 32 deletions packit_service/worker/handlers/distgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,12 +799,31 @@ def _get_or_create_koji_group_model(self) -> KojiBuildGroupModel:
)

for branch in self.get_branches():
sidetag = None
if self.job_config.sidetag_group:
# we need Kerberos ticket to create a new sidetag
self.packit_api.init_kerberos_ticket()
sidetag = SidetagHelper.get_or_create_sidetag(
self.job_config.sidetag_group,
branch,
)
# check if dependencies are satisfied within the sidetag
dependencies = set(self.job_config.dependencies or [])
if missing_dependencies := sidetag.get_missing_dependencies(
dependencies,
):
raise PackitException(
f"Missing dependencies for Koji build: {missing_dependencies}",
)

KojiBuildTargetModel.create(
task_id=None,
web_url=None,
target=branch,
status="queued",
scratch=self.job_config.scratch,
sidetag=sidetag.koji_name if sidetag else None,
nvr=self.packit_api.dg.get_nvr(branch),
koji_build_group=group,
)

Expand All @@ -814,12 +833,11 @@ def _get_or_create_koji_group_model(self) -> KojiBuildGroupModel:
def get_branches(self) -> list[str]:
"""Get a list of branch (names) to be built in koji"""

def is_already_triggered(self, branch: str) -> bool:
def is_already_triggered(self, nvr: str) -> bool:
"""
Check if the build was already triggered
(building or completed state).
"""
nvr = self.packit_api.dg.get_nvr(branch)
existing_build = self.koji_helper.get_build_info(nvr)

if existing_build:
Expand All @@ -836,9 +854,13 @@ def is_already_triggered(self, branch: str) -> bool:
return False

def run(self) -> TaskResults:
errors = {}
try:
group = self._get_or_create_koji_group_model()
except PackitException as ex:
logger.debug(f"Koji build failed to be submitted: {ex}")
return TaskResults(success=True, details={})

group = self._get_or_create_koji_group_model()
errors = {}
for koji_build_model in group.grouped_targets:
branch = koji_build_model.target

Expand All @@ -850,45 +872,32 @@ def run(self) -> TaskResults:
)
continue

if not self.job_config.scratch and self.is_already_triggered(branch):
logger.info(
f"Skipping downstream Koji build for branch {branch} "
f"that was already triggered.",
if not self.job_config.scratch:
existing_models = (
KojiBuildTargetModel.get_all_successful_or_in_progress_by_nvr(
koji_build_model.nvr,
)
)
koji_build_model.set_status("skipped")
continue
if existing_models - {koji_build_model} or self.is_already_triggered(
koji_build_model.nvr,
):
logger.info(
f"Skipping downstream Koji build {koji_build_model.nvr} "
f"for branch {branch} that was already triggered.",
)
koji_build_model.set_status("skipped")
continue

logger.debug(f"Running downstream Koji build for {branch}")
koji_build_model.set_status("pending")

try:
sidetag = None
if self.job_config.sidetag_group:
# we need Kerberos ticket to create a new sidetag
self.packit_api.init_kerberos_ticket()
sidetag = SidetagHelper.get_or_create_sidetag(
self.job_config.sidetag_group,
branch,
)
# skip submitting build for a branch if dependencies
# are not satisfied within a sidetag
dependencies = set(self.job_config.dependencies or [])
if missing_dependencies := sidetag.get_missing_dependencies(
dependencies,
):
logger.debug(
f"Skipping downstream Koji build for branch {branch}, "
f"missing dependencies: {missing_dependencies}",
)
koji_build_model.set_status("skipped")
continue

stdout = self.packit_api.build(
dist_git_branch=koji_build_model.target,
scratch=self.job_config.scratch,
nowait=True,
from_upstream=False,
koji_target=sidetag.koji_name if sidetag else None,
koji_target=koji_build_model.sidetag,
)
if stdout:
task_id, web_url = get_koji_task_id_and_url_from_stdout(stdout)
Expand Down
Loading

0 comments on commit dd074f8

Please sign in to comment.