2525from openstack .compute .v2 .server import Server
2626from openstack .exceptions import (
2727 ConflictException ,
28+ DuplicateResource ,
2829 OpenStackCloudException ,
2930 ResourceFailure ,
3031 ResourceNotFound ,
@@ -679,6 +680,15 @@ def get_active_image_by_os_version_and_slurm_version(
679680
680681 return backup_image
681682
683+ def _get_newest_image (self , images : list [Image ]) -> Image :
684+ """Return the newest image from a list based on created_at timestamp."""
685+ if not images :
686+ raise ImageNotFoundException (
687+ message = "No images provided to _get_newest_image" ,
688+ name_or_id = "unknown" ,
689+ )
690+ return max (images , key = lambda img : img .created_at )
691+
682692 def get_image (
683693 self ,
684694 name_or_id : str ,
@@ -691,7 +701,29 @@ def get_image(
691701
692702 logger .info (f"Get Image { name_or_id } " )
693703
694- image : Image | None = self .openstack_connection .get_image (name_or_id = name_or_id )
704+ try :
705+ image = self .openstack_connection .get_image (name_or_id = name_or_id )
706+ except DuplicateResource :
707+ logger .warning (
708+ f"Multiple images found with name '{ name_or_id } '. "
709+ "Fetching all images and filtering manually to select the newest one."
710+ )
711+ # In newest openstacksdk, list_images() has no name filter — must filter manually
712+ all_images = list (self .openstack_connection .list_images ())
713+ matching_images = [img for img in all_images if img .name == name_or_id ]
714+
715+ if not matching_images :
716+ logger .error (
717+ f"Unexpected: No images found matching name '{ name_or_id } ' after listing all images, "
718+ "despite DuplicateResource being raised. This may indicate a race condition or SDK inconsistency."
719+ )
720+ image = None
721+ else :
722+ logger .info (
723+ f"Found { len (matching_images )} image(s) with name '{ name_or_id } '. "
724+ "Selecting the newest one based on created_at."
725+ )
726+ image = self ._get_newest_image (matching_images )
695727
696728 # --- Image not found ---
697729 if image is None :
0 commit comments