-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define metadata.get_latest_konflux_build() #1271
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -21,6 +21,7 @@ | |||
import doozerlib | ||||
from artcommonlib import logutil, exectools, assertion | ||||
from artcommonlib.assembly import assembly_basis_event, assembly_metadata_config | ||||
from artcommonlib.konflux.konflux_build_record import KonfluxBuildRecord, KonfluxBuildOutcome, Engine | ||||
from artcommonlib.pushd import Dir | ||||
from artcommonlib.model import Missing, Model | ||||
from doozerlib.brew import BuildStates | ||||
|
@@ -401,11 +402,121 @@ async def get_latest_build(self, **kwargs): | |||
return await self.get_latest_brew_build_async(**kwargs) | ||||
|
||||
elif self.runtime.build_system == 'konflux': | ||||
raise NotImplementedError | ||||
return await self.get_latest_konflux_build(**kwargs) | ||||
locriandev marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
|
||||
else: | ||||
raise ValueError(f'Invalid value for --build-system: {self.runtime.build_system}') | ||||
|
||||
async def get_pinned_konflux_build(self, el_target: int): | ||||
""" | ||||
Return the assembly pinned NVR. | ||||
Under 'is' for RPMs, we expect 'el7' and/or 'el8', etc. For images, just 'nvr'. | ||||
""" | ||||
|
||||
is_config = self.config['is'] | ||||
|
||||
if self.meta_type == 'rpm': | ||||
if el_target is None: | ||||
raise ValueError( | ||||
f'Expected el_target to be set when querying a pinned RPM component {self.distgit_key}') | ||||
is_nvr = is_config[f'el{el_target}'] | ||||
if not is_nvr: | ||||
self.logger.warning('No pinned NVR found for RPM %s and target %s', self.rpm_name, el_target) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency with line 436, an error should be raised instead of returning none. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. default_return ( art-tools/doozer/doozerlib/metadata.py Line 485 in 27708d0
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah so for images we always pass in |
||||
return None | ||||
|
||||
else: | ||||
# The image metadata (or, more likely, the current assembly) has the image | ||||
# pinned. Return only the pinned NVR. When a child image is being rebased, | ||||
# it uses get_latest_build to find the parent NVR to use (if it is not | ||||
# included in the "-i" doozer argument). We need it to find the pinned NVR | ||||
# to place in its Dockerfile. | ||||
# Pinning also informs gen-payload when attempting to assemble a release. | ||||
is_nvr = is_config.nvr | ||||
if not is_nvr: | ||||
raise ValueError(f'Did not find nvr field in pinned Image component {self.distgit_key}') | ||||
|
||||
# strict means raise an exception if not found. | ||||
return await self.runtime.konflux_db.get_build_record_by_nvr(is_nvr, strict=True) | ||||
|
||||
async def get_latest_konflux_build(self, assembly: Optional[str] = None, | ||||
outcome: KonfluxBuildOutcome = KonfluxBuildOutcome.SUCCESS, | ||||
locriandev marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
el_target: Optional[int] = None, | ||||
honor_is: bool = True, | ||||
completed_before: Optional[datetime] = None, | ||||
extra_patterns: dict = {}, | ||||
**kwargs) -> Optional[KonfluxBuildRecord]: | ||||
""" | ||||
:param assembly: A non-default assembly name to search relative to. If not specified, runtime.assembly | ||||
will be used. If runtime.assembly is also None, the search will return true latest. | ||||
If the assembly parameter is set to '', this search will also return true latest. | ||||
:param outcome: one in KonfluxBuildOutcome[FAILURE, SUCCESS, PENDING] | ||||
:param el_target: specify 'el7', 'el8', etc. | ||||
For an RPM, leave as None if you want the true latest. | ||||
For an image, leaving as none will default to the RHEL version in the branch | ||||
associated with the metadata. | ||||
:param honor_is: If True, and an assembly component specifies 'is', that nvr will be returned. | ||||
:param completed_before: cut off timestamp for builds completion time | ||||
:param extra_patterns: e.g. {'release': 'b45ea65'} will result in adding "AND release LIKE '%b45ea65%'" to the query | ||||
""" | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm looking at the code for art-tools/doozer/doozerlib/metadata.py Line 412 in de3d8b7
We have params that are not used in this func, like component_name. Now that it's irrelevant, maybe we have a check that fails if the component name is different from what we determine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Overriding it to match something different from the metadata component name could be used in particular cases (e.g. olm bundles?) although I haven't found any occurrences of this. Either way, I feel this and other refactoring changes should be postponed as things are getting messy already and I want to limit changes to what's strictly needed for this task |
||||
assert self.runtime.konflux_db is not None, 'Konflux DB must be initialized with GCP credentials' | ||||
self.runtime.konflux_db.bind(KonfluxBuildRecord) | ||||
|
||||
# Is the component pinned in config? | ||||
if honor_is and self.config['is']: | ||||
if outcome != KonfluxBuildOutcome.SUCCESS: | ||||
# If this component is defined by 'is', history failures, etc, do not matter. | ||||
return None | ||||
Comment on lines
+467
to
+469
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here with a non-SUCCESS outcome (including None) and pinned by "is", this method always returns None. This seems to have inconsistent behaviors comparing to normal search. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've tried to follow the same pattern we already had here, do you see differences in behavior? |
||||
return await self.get_pinned_konflux_build(el_target=el_target) | ||||
|
||||
# If it's not pinned, fetch the build from the Konflux DB | ||||
base_search_params = { | ||||
'name': self.distgit_key if self.meta_type == 'image' else self.rpm_name, | ||||
'group': self.runtime.group, | ||||
'outcome': outcome, | ||||
'completed_before': completed_before, | ||||
'engine': self.runtime.build_system, | ||||
'extra_patterns': extra_patterns, | ||||
**kwargs | ||||
} | ||||
if self.meta_type == 'rpm': | ||||
# For RPMs, if rhel target is not set fetch true latest | ||||
if el_target: | ||||
base_search_params['el_target'] = el_target | ||||
else: | ||||
# For images, if rhel target is not set default to the rhel version in this group | ||||
base_search_params['el_target'] = el_target if el_target else f'el{self.branch_el_target()}' | ||||
|
||||
assembly = assembly if assembly else self.runtime.assembly | ||||
if not assembly: | ||||
# if assembly is '' (by parameter) or still None after runtime.assembly, get true latest | ||||
build_record = await self.runtime.konflux_db.get_latest_build(**base_search_params) | ||||
|
||||
else: | ||||
basis_event = assembly_basis_event(self.runtime.get_releases_config(), assembly=assembly) | ||||
if basis_event: | ||||
# If an assembly has a basis event, its latest images can only be sourced from | ||||
# "is:" or the stream assembly. We've already checked for "is" above. | ||||
assembly = 'stream' | ||||
|
||||
# Search by matching the assembly as well | ||||
build_record = await self.runtime.konflux_db.get_latest_build( | ||||
**base_search_params, | ||||
assembly=assembly, | ||||
) | ||||
|
||||
# If not builds were found and assembly != stream, look for 'stream' builds | ||||
if build_record is None and assembly != 'stream': | ||||
build_record = await self.runtime.konflux_db.get_latest_build( | ||||
**base_search_params, | ||||
assembly='stream', | ||||
) | ||||
|
||||
if not build_record: | ||||
self.logger.warning('No build found for %s in group and %s assembly %s', | ||||
self.distgit_key, self.runtime.group, self.runtime.assembly) | ||||
return build_record | ||||
|
||||
async def get_latest_brew_build_async(self, **kwargs): | ||||
return await asyncio.to_thread(self.get_latest_brew_build, **kwargs) | ||||
|
||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this behavior might do unexpected things, wondering why change this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is required to mimic the behavior of metadata.get_latest_build. Always defaulting to
stream
would make this impossible. I've also checked that we always pass in the assembly param when using the konflux_db function directly, so I don't see any risk in here.