diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 60aa8937..7eab1946 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -1,3 +1,4 @@ +import time import json import pathlib from dataclasses import dataclass, field @@ -6,7 +7,7 @@ from typing import Dict, Any, List, Optional, TYPE_CHECKING from .menu import AbstractSubMenu, Selector, MenuSelectionType, Menu, ListManager, TextInput from .networking import fetch_data_from_url -from .output import warn, FormattedOutput +from .output import FormattedOutput, debug from .storage import storage from .models.mirrors import MirrorStatusListV3, MirrorStatusEntryV3 @@ -324,17 +325,22 @@ def _parse_mirror_list(mirrorlist: str) -> Dict[str, List[MirrorStatusEntryV3]]: def list_mirrors() -> Dict[str, List[MirrorStatusEntryV3]]: - regions: Dict[str, List[MirrorStatusEntryV3]] = {} - - if storage['arguments']['offline']: - with pathlib.Path('/etc/pacman.d/mirrorlist').open('r') as fp: - mirrorlist = fp.read() - else: + if not storage['arguments']['offline']: url = "https://archlinux.org/mirrors/status/json/" - try: - mirrorlist = fetch_data_from_url(url) - except ValueError as err: - warn(f'Could not fetch an active mirror-list: {err}') - return regions + attempts = 3 - return _parse_mirror_list(mirrorlist) + for attempt_nr in range(attempts): + try: + mirrorlist = fetch_data_from_url(url) + return _parse_mirror_list(mirrorlist) + except Exception as e: + debug(f'Error while fetching mirror list: {e}') + time.sleep(attempt_nr + 1) + + debug('Unable to fetch mirror list remotely, falling back to local mirror list') + + # we'll use the local mirror list if the offline flag is set + # or if fetching the mirror list remotely failed + with pathlib.Path('/etc/pacman.d/mirrorlist').open('r') as fp: + mirrorlist = fp.read() + return _parse_mirror_list(mirrorlist) diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index 11f1ac39..5ac9f0ec 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -133,8 +133,10 @@ def fetch_data_from_url(url: str, params: Optional[dict] = None) -> str: response = urlopen(full_url, context=ssl_context) data = response.read().decode('UTF-8') return data - except URLError: - raise ValueError(f'Unable to fetch data from url: {url}') + except URLError as e: + raise ValueError(f'Unable to fetch data from url: {url}\n{e}') + except Exception as e: + raise ValueError(f'Unexpected error when parsing response: {e}') def calc_checksum(icmp_packet) -> int: