Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions archinstall/lib/switch_mirror.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from pathlib import Path

from archinstall.lib.installer import Installer
from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
from archinstall.lib.mirror.mirror_menu import MirrorMenu
from archinstall.lib.output import debug, error, info, warn
from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.components import tui

def switch_mirror_sources() -> bool:
info(tr('Switching mirror sources.'))
mirror_list_handler = MirrorListHandler()

try:
mirror_configuration = tui.run(lambda: MirrorMenu(mirror_list_handler).run())
except Exception as e:
error(tr('Could not open mirror configuration menu.'))
debug(f'Failed to switch mirror sources: {e}')
return False

if mirror_configuration is None:
warn(tr('Mirror source selection cancelled.'))
return False

try:
installer = Installer(
Path('/'),
DiskLayoutConfiguration(DiskLayoutType.Pre_mount, mountpoint=Path('/')),
)
installer.set_mirrors(mirror_list_handler, mirror_configuration, on_target=False)
info(tr('Mirror sources have been updated.'))
return True
except Exception as e:
error(tr('Failed to update the local mirror list.'))
debug(f'Failed to update the mirror list: {e}')
return False
35 changes: 30 additions & 5 deletions archinstall/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
from archinstall.lib.disk.utils import disk_layouts
from archinstall.lib.hardware import SysInfo
from archinstall.lib.network.wifi_handler import WifiHandler
from archinstall.lib.networking import ping
from archinstall.lib.output import debug, error, info, warn
from archinstall.lib.packages.util import check_version_upgrade
from archinstall.lib.pacman.pacman import Pacman
from archinstall.lib.translationhandler import tr
from archinstall.lib.switch_mirror import switch_mirror_sources
from archinstall.lib.utils.util import running_from_iso
from archinstall.lib.networking import ping
from archinstall.lib.menu.helpers import Confirmation
from archinstall.tui.ui.components import tui


Expand All @@ -32,8 +34,7 @@ def _log_sys_info() -> None:
# For support reasons, we'll log the disk layout pre installation to match against post-installation layout
debug(f'Disk states before installing:\n{disk_layouts()}')


def _check_online(wifi_handler: WifiHandler | None = None) -> bool:
def check_online(wifi_handler: WifiHandler | None = None) -> bool:
try:
ping('1.1.1.1')
except OSError as ex:
Expand All @@ -45,12 +46,31 @@ def _check_online(wifi_handler: WifiHandler | None = None) -> bool:

return True

SLOW_ARCH_DB_SYNC_THRESHOLD_SECONDS = 1

def _fetch_arch_db() -> bool:
def _confirm_switch_mirror_sources(elapsed_seconds: float) -> bool:
if not sys.stdin.isatty():
return False

header = tr('Refreshing repositories is taking a long time ({} seconds). Would you like to switch mirror sources?').format(int(elapsed_seconds))
try:
result = tui.run(lambda: Confirmation(header).show())
return result.get_value() is True
except Exception:
return False


def _fetch_arch_db(retry: bool = False) -> bool:
info('Fetching Arch Linux package database...')
started = time.time()
try:
Pacman.run('-Sy')
except Exception as e:
elapsed = time.time() - started
if not retry and elapsed > SLOW_ARCH_DB_SYNC_THRESHOLD_SECONDS:
if _confirm_switch_mirror_sources(elapsed) and switch_mirror_sources():
return _fetch_arch_db(retry=True)

error('Failed to sync Arch Linux package database.')
if 'could not resolve host' in str(e).lower():
error('Most likely due to a missing network connection or DNS issue.')
Expand All @@ -60,6 +80,11 @@ def _fetch_arch_db() -> bool:
debug(f'Failed to sync Arch Linux package database: {e}')
return False

elapsed = time.time() - started
if not retry and elapsed > SLOW_ARCH_DB_SYNC_THRESHOLD_SECONDS:
if _confirm_switch_mirror_sources(elapsed) and switch_mirror_sources():
return _fetch_arch_db(retry=True)

return True


Expand Down Expand Up @@ -103,7 +128,7 @@ def run() -> int:
else:
wifi_handler = None

if not _check_online(wifi_handler):
if not check_online(wifi_handler):
return 0

if not _fetch_arch_db():
Expand Down