99from cliff .command import Command
1010import jinja2
1111from loguru import logger
12+ import requests
1213from yaml import safe_load , YAMLError
1314
1415from osism import utils
@@ -137,6 +138,24 @@ def get_parser(self, prog_name):
137138 default = None ,
138139 help = "SBOM container image (default: registry.osism.cloud/kolla/sbom:<version>)" ,
139140 )
141+ parser .add_argument (
142+ "--release" ,
143+ type = str ,
144+ default = None ,
145+ help = "OSISM release version (e.g., 9.4.0) to fetch SBOM version from" ,
146+ )
147+ parser .add_argument (
148+ "--release-repository-url" ,
149+ type = str ,
150+ default = "https://raw.githubusercontent.com/osism/release/main" ,
151+ help = "Base URL for the release repository (default: https://raw.githubusercontent.com/osism/release/main)" ,
152+ )
153+ parser .add_argument (
154+ "--sbom-image-base" ,
155+ type = str ,
156+ default = "registry.osism.cloud/kolla/release/sbom" ,
157+ help = "Base path for the SBOM container image (default: registry.osism.cloud/kolla/release/sbom)" ,
158+ )
140159 parser .add_argument (
141160 "--dry-run" ,
142161 default = False ,
@@ -224,15 +243,62 @@ def _extract_sbom_with_skopeo(self, image_ref: str) -> dict:
224243
225244 return sbom
226245
246+ def _get_kolla_version_from_release (
247+ self , release : str , release_repository_url : str
248+ ) -> str :
249+ """
250+ Fetch the Kolla SBOM version from the OSISM release repository.
251+
252+ Args:
253+ release: OSISM release version (e.g., '9.4.0')
254+ release_repository_url: Base URL for the release repository
255+
256+ Returns:
257+ Kolla SBOM version string (e.g., '0.20250928.0')
258+ """
259+ url = f"{ release_repository_url } /{ release } /base.yml"
260+ logger .info (f"Fetching release configuration from { url } " )
261+
262+ try :
263+ response = requests .get (url , timeout = 30 )
264+ response .raise_for_status ()
265+ except requests .exceptions .RequestException as e :
266+ raise RuntimeError (f"Failed to fetch release configuration: { e } " )
267+
268+ try :
269+ release_config = safe_load (response .text )
270+ except YAMLError as e :
271+ raise RuntimeError (f"Failed to parse release configuration: { e } " )
272+
273+ docker_images = release_config .get ("docker_images" , {})
274+ kolla_version = docker_images .get ("kolla" )
275+
276+ if kolla_version is None :
277+ raise RuntimeError (
278+ f"Kolla version not found in release { release } configuration"
279+ )
280+
281+ logger .info (f"Found Kolla version { kolla_version } for release { release } " )
282+ return kolla_version
283+
227284 def take_action (self , parsed_args ):
228285 sync_type = parsed_args .type
229286 openstack_version = parsed_args .openstack_version
230287 config_path = Path (parsed_args .configuration_path )
231288 dry_run = parsed_args .dry_run
289+ release = parsed_args .release
290+ release_repository_url = parsed_args .release_repository_url .rstrip ("/" )
291+ sbom_image_base = parsed_args .sbom_image_base
232292
233293 if sync_type == "kolla" :
234294 return self ._sync_kolla_versions (
235- openstack_version , config_path , parsed_args .sbom_image , dry_run
295+ openstack_version ,
296+ config_path ,
297+ parsed_args .sbom_image ,
298+ dry_run ,
299+ release ,
300+ release_repository_url ,
301+ sbom_image_base ,
236302 )
237303
238304 logger .error (f"Unknown sync type: { sync_type } " )
@@ -244,26 +310,42 @@ def _sync_kolla_versions(
244310 config_path : Path ,
245311 sbom_image : str | None ,
246312 dry_run : bool ,
313+ release : str | None ,
314+ release_repository_url : str ,
315+ sbom_image_base : str ,
247316 ) -> int :
248317 """Sync Kolla versions from SBOM container image."""
249318
250319 # Construct SBOM image reference if not provided
251320 if sbom_image is None :
252- # Strip 'v' prefix if present (v0.20251128.0 -> 0.20251128.0)
253- version_tag = openstack_version .lstrip ("v" )
254-
255- # Use kolla/release/sbom for release versions (contain date like 0.20251128.0)
256- # Use kolla/sbom for OpenStack versions (like 2025.1)
257- is_release_version = any (
258- len (part ) == 8 and part .startswith ("20" ) and part .isdigit ()
259- for part in version_tag .split ("." )
260- )
261-
262- if is_release_version :
263- sbom_image = f"registry.osism.cloud/kolla/release/sbom:{ version_tag } "
321+ # If release is specified, fetch the Kolla version from the release repository
322+ if release is not None :
323+ try :
324+ kolla_version = self ._get_kolla_version_from_release (
325+ release , release_repository_url
326+ )
327+ sbom_image = f"{ sbom_image_base } :{ kolla_version } "
328+ except RuntimeError as e :
329+ logger .error (str (e ))
330+ return 1
264331 else :
265- sbom_image = f"registry.osism.cloud/kolla/sbom:{ version_tag } "
332+ # Strip 'v' prefix if present (v0.20251128.0 -> 0.20251128.0)
333+ version_tag = openstack_version .lstrip ("v" )
334+
335+ # Use kolla/release/sbom for release versions (contain date like 0.20251128.0)
336+ # Use kolla/sbom for OpenStack versions (like 2025.1)
337+ is_release_version = any (
338+ len (part ) == 8 and part .startswith ("20" ) and part .isdigit ()
339+ for part in version_tag .split ("." )
340+ )
341+
342+ if is_release_version :
343+ sbom_image = f"{ sbom_image_base } :{ version_tag } "
344+ else :
345+ sbom_image = f"registry.osism.cloud/kolla/sbom:{ version_tag } "
266346
347+ if release is not None :
348+ logger .info (f"OSISM release: { release } " )
267349 logger .info (f"OpenStack version: { openstack_version } " )
268350 logger .info (f"Configuration path: { config_path } " )
269351 logger .info (f"SBOM image: { sbom_image } " )
0 commit comments