From a2ab1f98e0781042fa273c2424b2fe352d6f8d6e Mon Sep 17 00:00:00 2001 From: h8d13 Date: Thu, 25 Dec 2025 11:53:16 +0100 Subject: [PATCH 1/5] add explicit _fetched_remote bool --- archinstall/lib/mirrors.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 707cf08009..ffe6670def 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -407,9 +407,11 @@ def load_mirrors(self) -> None: from .args import arch_config_handler if arch_config_handler.args.offline: + self._fetched_remote = False self.load_local_mirrors() else: - if not self.load_remote_mirrors(): + self._fetched_remote = self.load_remote_mirrors() + if not self._fetched_remote: self.load_local_mirrors() def load_remote_mirrors(self) -> bool: From 003c37d4dc4f0a28697129bf11a51e8c3b169730 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Thu, 25 Dec 2025 14:49:38 +0100 Subject: [PATCH 2/5] Attempt 2 --- archinstall/lib/mirrors.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index ffe6670def..ec4ba3e3f4 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -384,6 +384,7 @@ def __init__( ) -> None: self._local_mirrorlist = local_mirrorlist self._status_mappings: dict[str, list[MirrorStatusEntryV3]] | None = None + self._fetched_remote: bool = False def _mappings(self) -> dict[str, list[MirrorStatusEntryV3]]: if self._status_mappings is None: @@ -438,7 +439,15 @@ def load_local_mirrors(self) -> None: def get_status_by_region(self, region: str, speed_sort: bool) -> list[MirrorStatusEntryV3]: mappings = self._mappings() region_list = mappings[region] - return sorted(region_list, key=lambda mirror: (mirror.score, mirror.speed)) + + # Only sort if we have remote mirror data with score/speed info + # Local mirrors lack this data and can be modified manually before-hand + # Or reflector potentially ran already + if self._fetched_remote and speed_sort: + # original return + return sorted(region_list, key=lambda mirror: (mirror.score, mirror.speed)) + # just return as-is without sorting? + return region_list def _parse_remote_mirror_list(self, mirrorlist: str) -> dict[str, list[MirrorStatusEntryV3]]: mirror_status = MirrorStatusListV3.model_validate_json(mirrorlist) From d8044a6d862adcf1473711d0cb5115b19b957ab8 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Thu, 25 Dec 2025 15:02:48 +0100 Subject: [PATCH 3/5] Adds about 15 seconds time-out to fetch_data_from_url with 3 retries (4, 5, 6) Then fallsback to fully local list --- archinstall/lib/networking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index f7d4efac4f..a89f0aa0ca 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -121,7 +121,7 @@ def enrich_iface_types(interfaces: list[str]) -> dict[str, str]: return result -def fetch_data_from_url(url: str, params: dict[str, str] | None = None) -> str: +def fetch_data_from_url(url: str, params: dict[str, str] | None = None, timeout: int = 3) -> str: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE @@ -133,7 +133,7 @@ def fetch_data_from_url(url: str, params: dict[str, str] | None = None) -> str: full_url = url try: - response = urlopen(full_url, context=ssl_context) + response = urlopen(full_url, context=ssl_context, timeout=timeout) data = response.read().decode('UTF-8') return data except URLError as e: From 943de1a13e804a82319339d37e60df4f68e6029e Mon Sep 17 00:00:00 2001 From: h8d13 Date: Sat, 27 Dec 2025 09:31:23 +0100 Subject: [PATCH 4/5] Feedbacks: 20 -> 30 Do not return early Add debug Remove new flag 60 second timeout for reflector --- archinstall/lib/installer.py | 13 ++++++++++--- archinstall/lib/mirrors.py | 1 + archinstall/lib/networking.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 93829ecc6b..ff2e3b1806 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -194,9 +194,16 @@ def _verify_service_stop(self) -> None: else: info(tr('Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)')) - info('Waiting for automatic mirror selection (reflector) to complete.') - while self._service_state('reflector') not in ('dead', 'failed', 'exited'): - time.sleep(1) + if not arch_config_handler.args.offline: + info('Waiting for automatic mirror selection (reflector) to complete.') + for _ in range(60): + if self._service_state('reflector') in ('dead', 'failed', 'exited'): + break + time.sleep(1) + else: + warn('Reflector did not complete within 60 seconds, continuing anyway...') + else: + info('Skipped reflector...') # info('Waiting for pacman-init.service to complete.') # while self._service_state('pacman-init') not in ('dead', 'failed', 'exited'): diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index ec4ba3e3f4..b4a6921efd 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -412,6 +412,7 @@ def load_mirrors(self) -> None: self.load_local_mirrors() else: self._fetched_remote = self.load_remote_mirrors() + debug(f'load mirrors: {self._fetched_remote}') if not self._fetched_remote: self.load_local_mirrors() diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index a89f0aa0ca..c06c0346b2 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -121,7 +121,7 @@ def enrich_iface_types(interfaces: list[str]) -> dict[str, str]: return result -def fetch_data_from_url(url: str, params: dict[str, str] | None = None, timeout: int = 3) -> str: +def fetch_data_from_url(url: str, params: dict[str, str] | None = None, timeout: int = 30) -> str: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE From afa7b2a46bc79d1cf19ec363575f2645a9f31d57 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Sat, 27 Dec 2025 11:01:05 +0100 Subject: [PATCH 5/5] Clean up install logs by hiding mirror scores behind --verbose --- archinstall/lib/models/mirrors.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/archinstall/lib/models/mirrors.py b/archinstall/lib/models/mirrors.py index 9c5e841b5a..a013eb0a71 100644 --- a/archinstall/lib/models/mirrors.py +++ b/archinstall/lib/models/mirrors.py @@ -105,10 +105,13 @@ def validate_score(cls, value: float) -> int | None: @model_validator(mode='after') def debug_output(self) -> 'MirrorStatusEntryV3': + from ..args import arch_config_handler + self._hostname, *port = urllib.parse.urlparse(self.url).netloc.split(':', 1) self._port = int(port[0]) if port and len(port) >= 1 else None - debug(f'Loaded mirror {self._hostname}' + (f' with current score of {self.score}' if self.score else '')) + if arch_config_handler.args.verbose: + debug(f'Loaded mirror {self._hostname}' + (f' with current score of {self.score}' if self.score else '')) return self