@@ -2971,6 +2971,7 @@ def main():
29712971 cpu_specified = False
29722972 serial_user_specified = False
29732973 vnc_user_specified = False
2974+ arch_specified = False
29742975
29752976
29762977 script_home = os .path .dirname (os .path .abspath (__file__ ))
@@ -3002,6 +3003,7 @@ def main():
30023003 i += 1
30033004 elif arg == "--arch" :
30043005 config ['arch' ] = args [i + 1 ].lower ()
3006+ arch_specified = True
30053007 i += 1
30063008 elif arg == "--mem" :
30073009 config ['mem' ] = args [i + 1 ]
@@ -3246,6 +3248,29 @@ def get_releases(repo_slug):
32463248 debuglog (config ['debug' ], "Candidate URL (xz) exists!" )
32473249 use_this_builder = True
32483250 found_zst_link = candidate_url_xz
3251+ elif config ['arch' ] == "aarch64" and not arch_specified :
3252+ # Fallback to x86_64 if aarch64 failed and arch was not user-specified
3253+ log ("No aarch64 image found for {} {} in {}. Trying x86_64 fallback..." .format (config ['os' ], config ['release' ], search_repo ))
3254+ config ['arch' ] = "" # Empty string means x86_64 in anyvm
3255+ # Sync VM arch for debug logging later
3256+ debuglog (config ['debug' ], "Fallback to x86_64 due to missing aarch64 asset" )
3257+ target_zst_fallback = "{}-{}.qcow2.zst" .format (config ['os' ], config ['release' ])
3258+ candidate_url_fallback = "https://github.com/{}/releases/download/{}/{}" .format (search_repo , tag , target_zst_fallback )
3259+ debuglog (config ['debug' ], "Checking fallback x86_64 URL: {}" .format (candidate_url_fallback ))
3260+ if check_url_exists (candidate_url_fallback , config ['debug' ]):
3261+ debuglog (config ['debug' ], "Fallback x86_64 URL exists!" )
3262+ use_this_builder = True
3263+ found_zst_link = candidate_url_fallback
3264+ else :
3265+ target_xz_fallback = target_zst_fallback .replace ('.zst' , '.xz' )
3266+ candidate_url_xz_fallback = "https://github.com/{}/releases/download/{}/{}" .format (search_repo , tag , target_xz_fallback )
3267+ debuglog (config ['debug' ], "Checking fallback x86_64 URL (xz): {}" .format (candidate_url_xz_fallback ))
3268+ if check_url_exists (candidate_url_xz_fallback , config ['debug' ]):
3269+ debuglog (config ['debug' ], "Fallback x86_64 URL (xz) exists!" )
3270+ use_this_builder = True
3271+ found_zst_link = candidate_url_xz_fallback
3272+ else :
3273+ debuglog (config ['debug' ], "Candidate URL not found (including fallback), falling back to full search" )
32493274 else :
32503275 debuglog (config ['debug' ], "Candidate URL not found, falling back to full search" )
32513276 else :
@@ -3302,31 +3327,37 @@ def get_releases(repo_slug):
33023327 published_at = ""
33033328 # Find release version if not provided
33043329 if not config ['release' ]:
3305- for r in releases_data :
3306- #log(r)
3307- for asset in r .get ('assets' , []):
3308- u = asset .get ('browser_download_url' , '' )
3309- #log(u)
3310- if u .endswith ("qcow2.zst" ) or u .endswith ("qcow2.xz" ):
3311- if config ['arch' ] and config ['arch' ] != "x86_64" and config ['arch' ] not in u :
3312- continue
3313- # Extract version roughly
3314- filename = u .split ('/' )[- 1 ]
3315- filename = removesuffix (filename , ".qcow2.zst" )
3316- filename = removesuffix (filename , ".qcow2.xz" )
3317- parts = filename .split ('-' )
3318- if len (parts ) > 1 :
3319- ver = parts [1 ]
3320- debuglog (config ['debug' ], "Candidate release found: {} from asset {}" .format (ver , filename ))
3321- if published_at and published_at > r .get ('published_at' , '' ):
3330+ def find_latest_release (data , arch ):
3331+ p_at = ""
3332+ found_v = ""
3333+ for r in data :
3334+ for asset in r .get ('assets' , []):
3335+ u = asset .get ('browser_download_url' , '' )
3336+ if u .endswith ("qcow2.zst" ) or u .endswith ("qcow2.xz" ):
3337+ if arch and arch != "x86_64" and arch not in u :
33223338 continue
3323- if not published_at :
3324- published_at = r .get ('published_at' , '' )
3325- config ['release' ] = ver
3326- elif cmp_version (ver , config ['release' ]) > 0 :
3327- published_at = r .get ('published_at' , '' )
3328- config ['release' ] = ver
3329- debuglog (config ['debug' ],"Updated latest release to: " + config ['release' ])
3339+ filename = u .split ('/' )[- 1 ]
3340+ filename = removesuffix (filename , ".qcow2.zst" )
3341+ filename = removesuffix (filename , ".qcow2.xz" )
3342+ parts = filename .split ('-' )
3343+ if len (parts ) > 1 :
3344+ ver = parts [1 ]
3345+ debuglog (config ['debug' ], "Candidate release found: {} from asset {}" .format (ver , filename ))
3346+ if p_at and p_at > r .get ('published_at' , '' ):
3347+ continue
3348+ if not p_at or cmp_version (ver , found_v ) > 0 :
3349+ p_at = r .get ('published_at' , '' )
3350+ found_v = ver
3351+ return found_v , p_at
3352+
3353+ config ['release' ], published_at = find_latest_release (releases_data , config ['arch' ])
3354+
3355+ if not config ['release' ] and config ['arch' ] == "aarch64" and not arch_specified :
3356+ debuglog (config ['debug' ], "No aarch64 release found, searching for x86_64 fallback release..." )
3357+ config ['release' ], published_at = find_latest_release (releases_data , "" )
3358+ if config ['release' ]:
3359+ log ("No aarch64 release found for {}. Falling back to x86_64." .format (config ['os' ]))
3360+ config ['arch' ] = ""
33303361
33313362
33323363 log ("Using release: " + config ['release' ])
@@ -3360,6 +3391,26 @@ def find_image_link(releases, target_zst, target_xz):
33603391 releases_data = repo_releases
33613392 zst_link = link
33623393 break
3394+
3395+ # If still no link and we are on aarch64 and it wasn't specified, fallback to x86_64 full search
3396+ if not zst_link and config ['arch' ] == "aarch64" and not arch_specified :
3397+ log ("No aarch64 image found in any repository. Trying x86_64 fallback search..." )
3398+ config ['arch' ] = "" # x86_64
3399+ target_zst_fallback = "{}-{}.qcow2.zst" .format (config ['os' ], config ['release' ])
3400+ target_xz_fallback = "{}-{}.qcow2.xz" .format (config ['os' ], config ['release' ])
3401+
3402+ searched = set ()
3403+ for repo in search_repos :
3404+ if repo in searched :
3405+ continue
3406+ searched .add (repo )
3407+ repo_releases = releases_data if repo == builder_repo else get_releases (repo )
3408+ link = find_image_link (repo_releases , target_zst_fallback , target_xz_fallback )
3409+ if link :
3410+ builder_repo = repo
3411+ releases_data = repo_releases
3412+ zst_link = link
3413+ break
33633414
33643415 if not zst_link :
33653416 fatal ("Cannot find the image link." )
0 commit comments