Reinit keyring automatically when pacman sync fails with GPGME error

Instead of skipping mirror configuration when wkd-sync fails, catch
the GPGME error at the point where it actually occurs - during
pacman -Syy. If the sync fails with a keyring-related error, reinit
the keyring with pacman-key --init/--populate and retry the sync.
This commit is contained in:
Softer 2026-06-06 16:42:02 +03:00
parent cf478a0b73
commit 490e71f3ae
3 changed files with 43 additions and 25 deletions

View File

@ -131,7 +131,6 @@ class Installer:
self._zram_enabled = False
self._disable_fstrim = False
self._keyring_synced = True
self.pacman = Pacman(self.target, silent)
@ -230,8 +229,7 @@ class Installer:
time.sleep(1)
if self._service_state('archlinux-keyring-wkd-sync.service') == 'failed':
self._keyring_synced = False
warn('archlinux-keyring-wkd-sync failed, custom mirror configuration will be skipped')
warn('archlinux-keyring-wkd-sync failed, keyring may need reinit during pacman sync')
def _verify_boot_part(self) -> None:
"""
@ -251,10 +249,6 @@ class Installer:
f'Please resize it to at least 200MiB and re-run the installation.',
)
@property
def keyring_synced(self) -> bool:
return self._keyring_synced
def sanity_check(
self,
offline: bool = False,

View File

@ -4,8 +4,8 @@ from collections.abc import Callable
from pathlib import Path
from archinstall.lib.command import SysCommand
from archinstall.lib.exceptions import RequirementError
from archinstall.lib.log import error, info, warn
from archinstall.lib.exceptions import RequirementError, SysCallError
from archinstall.lib.log import debug, error, info, warn
from archinstall.lib.pathnames import PACMAN_CONF
from archinstall.lib.plugins import plugins
from archinstall.lib.translationhandler import tr
@ -53,15 +53,45 @@ class Pacman:
def sync(self) -> None:
if self.synced:
return
self.ask(
'Could not sync a new package database',
'Could not sync mirrors',
self.run,
'-Syy',
default_cmd='pacman',
)
try:
self.run('-Syy', default_cmd='pacman')
except SysCallError as err:
if b'GPGME' in err.worker_log or b'keyring' in err.worker_log.lower():
warn('Pacman sync failed with keyring error, attempting keyring reinit')
self._reinit_keyring()
self.ask(
'Could not sync a new package database after keyring reinit',
'Could not sync mirrors',
self.run,
'-Syy',
default_cmd='pacman',
)
else:
self.ask(
'Could not sync a new package database',
'Could not sync mirrors',
self.run,
'-Syy',
default_cmd='pacman',
)
self.synced = True
@staticmethod
def _reinit_keyring() -> None:
try:
SysCommand('killall gpg-agent')
except SysCallError as err:
debug(f'killall gpg-agent failed (may not be running): {err}')
try:
SysCommand('pacman-key --init')
SysCommand('pacman-key --populate archlinux')
debug('Keyring reinitialized successfully')
except SysCallError as err:
debug(f'Keyring reinit failed: {err}')
def strap(self, packages: str | list[str]) -> None:
self.sync()
if isinstance(packages, str):

View File

@ -12,7 +12,7 @@ from archinstall.lib.disk.utils import disk_layouts
from archinstall.lib.general.general_menu import PostInstallationAction, select_post_installation
from archinstall.lib.global_menu import GlobalMenu
from archinstall.lib.installer import Installer, accessibility_tools_in_use, run_custom_user_commands
from archinstall.lib.log import debug, error, info, warn
from archinstall.lib.log import debug, error, info
from archinstall.lib.menu.util import delayed_warning
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
from archinstall.lib.models import Bootloader
@ -98,10 +98,7 @@ def perform_installation(
installation.generate_key_files()
if mirror_config := config.mirror_config:
if installation.keyring_synced:
installation.set_mirrors(mirror_list_handler, mirror_config, on_target=False)
else:
warn('Skipping custom mirror configuration due to keyring sync failure')
installation.set_mirrors(mirror_list_handler, mirror_config, on_target=False)
installation.minimal_installation(
optional_repositories=optional_repositories,
@ -112,10 +109,7 @@ def perform_installation(
)
if mirror_config := config.mirror_config:
if installation.keyring_synced:
installation.set_mirrors(mirror_list_handler, mirror_config, on_target=True)
else:
warn('Skipping target mirror configuration due to keyring sync failure')
installation.set_mirrors(mirror_list_handler, mirror_config, on_target=True)
if config.swap and config.swap.enabled:
installation.setup_swap(algo=config.swap.algorithm)