33import fnmatch
44import json
55import logging
6+ import os
67import re
78from typing import Dict , List , Optional , Set , cast
89from urllib .parse import quote
910
1011import koji
1112import requests
1213import yaml
13- from artcommonlib .konflux .konflux_build_record import KonfluxBuildRecord
14+ from artcommonlib .konflux .konflux_build_record import KonfluxBuildRecord , KonfluxBuildOutcome
1415from artcommonlib .konflux .konflux_db import KonfluxDb
1516
1617import artbotlib .exectools
1718
1819from . import util
19- from .constants import NIGHTLY_REGISTRY , QUAY_REGISTRY
20+ from .constants import GITHUB_API_REPO_URL , NIGHTLY_REGISTRY , QUAY_REGISTRY
2021from .rhcos import RHCOSBuildInfo , get_rhcos_build_id_from_pullspec
2122
2223logger = logging .getLogger (__name__ )
@@ -268,6 +269,46 @@ async def get_build_id():
268269 filename = '{}-{}.txt' .format (release_tag , data_type ))
269270
270271
272+ def get_image_names_for_group (major_minor : str ) -> List [str ]:
273+ """
274+ Fetch list of image names from ocp-build-data via GitHub API
275+ """
276+ github_token = os .environ .get ('GITHUB_PERSONAL_ACCESS_TOKEN' )
277+ if not github_token :
278+ raise ValueError ("GITHUB_PERSONAL_ACCESS_TOKEN environment variable is not set. "
279+ "This is required to fetch image lists from GitHub API." )
280+
281+ url = f"{ GITHUB_API_REPO_URL } /openshift-eng/ocp-build-data/contents/images?ref=openshift-{ major_minor } "
282+ headers = {"Authorization" : f"token { github_token } " }
283+
284+ logger .info ('Fetching image list from GitHub for openshift-%s' , major_minor )
285+ response = requests .get (url , headers = headers )
286+ response .raise_for_status ()
287+
288+ files = response .json ()
289+ image_names = [f ['name' ].removesuffix ('.yml' ) for f in files if f ['name' ].endswith ('.yml' )]
290+ logger .info ('Found %d images in openshift-%s' , len (image_names ), major_minor )
291+
292+ return image_names
293+
294+
295+ async def get_latest_konflux_builds_for_group (major_minor : str ) -> List [str ]:
296+ """Get latest Konflux build NVRs for all images in a group."""
297+ image_names = get_image_names_for_group (major_minor )
298+
299+ konflux_db = KonfluxDb ()
300+ konflux_db .bind (KonfluxBuildRecord )
301+
302+ builds = await konflux_db .get_latest_builds (
303+ names = image_names ,
304+ group = f"openshift-{ major_minor } " ,
305+ assembly = "stream" ,
306+ outcome = KonfluxBuildOutcome .SUCCESS
307+ )
308+ logger .info ('Found %d builds for openshift-%s' , len (builds ), major_minor )
309+ return [b .nvr for b in builds if b is not None ]
310+
311+
271312def latest_images_for_version (so , major_minor ):
272313 key = f'latest_images_built_for_version-{ major_minor } '
273314 image_nvrs = util .CACHE_TTL .get (key )
@@ -278,24 +319,17 @@ def latest_images_for_version(so, major_minor):
278319 so .say (f"Determining images for { major_minor } - this may take a few minutes..." )
279320
280321 try :
281- logger .info ('Determining images for %s' , major_minor )
282- rc , stdout , stderr = artbotlib .exectools .cmd_assert (
283- so , f"doozer --build-system=konflux --disable-gssapi --group openshift-{ major_minor } --assembly stream images:print "
284- f"'{{component}}-{{version}}-{{release}}' --show-base --show-non-release --short"
285- )
322+ logger .info ('Determining images for %s using Konflux DB' , major_minor )
323+ image_nvrs = asyncio .run (get_latest_konflux_builds_for_group (major_minor ))
286324
287- except Exception as e : # convert any exception into generic (cmd_assert already reports details to monitoring)
325+ except Exception as e :
288326 logger .error ('Failed retrieving latest images for %s: %s' , major_minor , e )
289- so .say (
290- f"Failed to retrieve latest images for version '{ major_minor } ': doozer could not find version '{ major_minor } '" )
327+ so .say (f"Failed to retrieve latest images for version '{ major_minor } ': { e } " )
291328 return []
292329
293- image_nvrs = [nvr .strip () for nvr in stdout .strip ().split ('\n ' )]
294330 logger .info ('Found image nvrs in %s:\n %s' , major_minor , '\n ' .join (image_nvrs ))
295331
296- # if there is no build for an image, doozer still prints it out like "component--".
297- # filter out those non-builds so we don't expect to find them later.
298- util .CACHE_TTL [key ] = image_nvrs = [nvr for nvr in image_nvrs if not nvr .endswith ('-' )]
332+ util .CACHE_TTL [key ] = image_nvrs
299333 return image_nvrs
300334
301335
0 commit comments