11import os
22import json
3+ import re
34import subprocess
45from typing import Dict , Any
6+ from distutils .version import LooseVersion
57
68from ci_utils .common .logger import get_logger
79
@@ -134,4 +136,81 @@ def run_cmd(session, cmd, check=True, timeout=3600, source_bashrc=False):
134136 logger .error (f"Failure Output: { out } " )
135137 raise RuntimeError (err )
136138 logger .info (f"[REMOTE] Command output for { cmd_to_run } with return code { code } : Output: { out .strip ()} \n { err .strip ()} \n " )
137- return out .strip (), code
139+ return out .strip (), code
140+
141+ # -----------------------
142+ # Identify the matching Qcow image from the list of available images
143+ # -----------------------
144+ def identify_matching_qcow_image (session ,centos_arch , centos_version , image_base_url , backend_type = "gpfs" , version_constraints = None ):
145+ """
146+ Identify the matching Qcow image from the list of available images
147+ Args:
148+ centos_arch (str): CentOS architecture (x86_64, aarch64)
149+ centos_version (str): CentOS version (9, 8, 7)
150+ image_base_url (str): Base URL of the image list
151+ backend_type (str): Backend type (gpfs, pjdfs)
152+ Returns:
153+ str: Matching Qcow image name
154+ """
155+ logger .info (f"[STEP]: Identifying matching Qcow image for CentOS { centos_version } { centos_arch } { backend_type } with version constraints { version_constraints } " )
156+ run_cmd (session , "systemctl enable --now libvirtd" )
157+ run_cmd (session , "dnf install -y libguestfs-tools-c" )
158+ available_images = run_cmd (
159+ session ,
160+ rf"curl -s { image_base_url } | grep -oP 'CentOS-Stream-GenericCloud-{ centos_arch } -{ centos_version } .*?\.qcow2(?=\")'"
161+ )
162+
163+ logger .info (f"[INFO] Available images: { available_images } " )
164+
165+ # Parse available_images output into a list (assuming it's a string with newlines)
166+ # Note: available_images is a tuple (output, code) from run_cmd, so we need to extract the output
167+ images_list = available_images [0 ].strip ().split ('\n ' ) if isinstance (available_images , tuple ) else available_images .strip ().split ('\n ' )
168+ images_list = [img for img in images_list if img .strip ()] # Remove empty strings
169+
170+ # Create the destination directory if it doesn't exist
171+ run_cmd (session , "mkdir -p /var/lib/libguestfs/images/" )
172+
173+ # Iterate from the last image backwards
174+ for image_name in reversed (images_list ):
175+ image_name = image_name .strip ()
176+ if not image_name :
177+ continue
178+
179+ logger .info (f"Processing image: { image_name } " )
180+
181+ # wget operation with baseurl + image name
182+ image_url = f"{ image_base_url .rstrip ('/' )} /{ image_name } "
183+ run_cmd (session , f"wget -q { image_url } " )
184+
185+ # Move the downloaded image to /var/lib/libguestfs/images/
186+ run_cmd (session , f"mv { image_name } /var/lib/libguestfs/images/" )
187+
188+ # chmod 644 on all qcow2 images in the directory
189+ run_cmd (session , "chmod 644 /var/lib/libguestfs/images/*.qcow2" )
190+
191+ # Check kernel version using guestfish
192+ image_path = f"/var/lib/libguestfs/images/{ image_name } "
193+ kernel_version , _ = run_cmd (session , f'virt-ls -a "{ image_path } " /usr/lib/modules/' )
194+ logger .info (f"[INFO] Kernel version for { image_name } : { kernel_version } " )
195+
196+ if version_constraints :
197+
198+ kernel_ver_str = kernel_version [0 ].strip () if isinstance (kernel_version , tuple ) else kernel_version .strip ()
199+
200+ # Normalize both versions
201+ kernel_normalized = re .match (r"(\d+\.\d+\.\d+-\d+)" , kernel_ver_str ).group (1 )
202+ constraint_normalized = re .match (r"(\d+\.\d+\.\d+-\d+)" , version_constraints ).group (1 )
203+
204+ logger .info (f"[INFO] Comparing kernel { kernel_ver_str } (normalized: { kernel_normalized } ) with constraint { version_constraints } (normalized: { constraint_normalized } )" )
205+
206+ # Use LooseVersion for comparison
207+ if LooseVersion (kernel_normalized ) <= LooseVersion (constraint_normalized ):
208+ logger .info (f"[INFO] Kernel version meets constraint. Returning image URL: { image_url } " )
209+ return image_url
210+ else :
211+ logger .info (f"[INFO] Kernel version does NOT meet constraint, trying next image" )
212+ run_cmd (session , f"rm -f { image_path } " )
213+ continue
214+ else :
215+ logger .info (f"[INFO] No version constraints specified, returning image URL: { image_url } " )
216+ return image_url
0 commit comments