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 707cf08009..b4a6921efd 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: @@ -407,9 +408,12 @@ 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() + debug(f'load mirrors: {self._fetched_remote}') + if not self._fetched_remote: self.load_local_mirrors() def load_remote_mirrors(self) -> bool: @@ -436,7 +440,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) 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 diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index f7d4efac4f..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) -> 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 @@ -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: