Fix 3412 - Take optional repositories into account (#3427)

This commit is contained in:
Daniel Girtler 2025-05-04 00:06:27 +10:00 committed by GitHub
parent 9a939d8378
commit 4023cfe2ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 70 additions and 29 deletions

View File

@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, override
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
from archinstall.lib.packages import list_available_packages
from archinstall.tui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from .args import ArchConfig from .args import ArchConfig
@ -29,9 +30,11 @@ from .models.bootloader import Bootloader
from .models.locale import LocaleConfiguration from .models.locale import LocaleConfiguration
from .models.mirrors import MirrorConfiguration from .models.mirrors import MirrorConfiguration
from .models.network_configuration import NetworkConfiguration, NicType from .models.network_configuration import NetworkConfiguration, NicType
from .models.packages import Repository
from .models.profile_model import ProfileConfiguration from .models.profile_model import ProfileConfiguration
from .models.users import Password, User from .models.users import Password, User
from .output import FormattedOutput from .output import FormattedOutput
from .pacman.config import PacmanConfig
from .translationhandler import Language, translation_handler from .translationhandler import Language, translation_handler
from .utils.util import get_password from .utils.util import get_password
@ -168,7 +171,7 @@ class GlobalMenu(AbstractMenu[None]):
), ),
MenuItem( MenuItem(
text=str(_('Additional packages')), text=str(_('Additional packages')),
action=ask_additional_packages_to_install, action=self._select_additional_packages,
value=[], value=[],
preview_action=self._prev_additional_pkgs, preview_action=self._prev_additional_pkgs,
key='packages' key='packages'
@ -536,6 +539,20 @@ class GlobalMenu(AbstractMenu[None]):
profile_config = ProfileMenu(preset=current_profile).run() profile_config = ProfileMenu(preset=current_profile).run()
return profile_config return profile_config
def _select_additional_packages(self, preset: list[str]) -> list[str]:
config: MirrorConfiguration | None = self._item_group.find_by_key('mirror_config').value
repositories: set[Repository] = set()
if config:
repositories = set(config.optional_repositories)
packages = ask_additional_packages_to_install(
preset,
repositories=repositories
)
return packages
def _create_user_account(self, preset: list[User] | None = None) -> list[User]: def _create_user_account(self, preset: list[User] | None = None) -> list[User]:
preset = [] if preset is None else preset preset = [] if preset is None else preset
users = ask_for_additional_users(defined_users=preset) users = ask_for_additional_users(defined_users=preset)
@ -543,6 +560,17 @@ class GlobalMenu(AbstractMenu[None]):
def _mirror_configuration(self, preset: MirrorConfiguration | None = None) -> MirrorConfiguration | None: def _mirror_configuration(self, preset: MirrorConfiguration | None = None) -> MirrorConfiguration | None:
mirror_configuration = MirrorMenu(preset=preset).run() mirror_configuration = MirrorMenu(preset=preset).run()
if mirror_configuration:
if mirror_configuration.optional_repositories:
# reset the package list cache in case the repository selection has changed
list_available_packages.cache_clear()
# enable the repositories in the config
pacman_config = PacmanConfig(None)
pacman_config.enable(mirror_configuration.optional_repositories)
pacman_config.apply()
return mirror_configuration return mirror_configuration
def _prev_mirror_config(self, item: MenuItem) -> str | None: def _prev_mirror_config(self, item: MenuItem) -> str | None:

View File

@ -44,7 +44,7 @@ from .models.network_configuration import Nic
from .models.users import User from .models.users import User
from .output import debug, error, info, log, warn from .output import debug, error, info, log, warn
from .pacman import Pacman from .pacman import Pacman
from .pacman.config import Config from .pacman.config import PacmanConfig
from .plugins import plugins from .plugins import plugins
from .storage import storage from .storage import storage
@ -847,7 +847,7 @@ class Installer:
debug(f'Optional repositories: {optional_repositories}') debug(f'Optional repositories: {optional_repositories}')
# This action takes place on the host system as pacstrap copies over package repository lists. # This action takes place on the host system as pacstrap copies over package repository lists.
pacman_conf = Config(self.target) pacman_conf = PacmanConfig(self.target)
pacman_conf.enable(optional_repositories) pacman_conf.enable(optional_repositories)
pacman_conf.apply() pacman_conf.apply()

View File

@ -178,9 +178,14 @@ def ask_additional_packages_to_install(
preset: list[str] = [], preset: list[str] = [],
repositories: set[Repository] = set() repositories: set[Repository] = set()
) -> list[str]: ) -> list[str]:
Tui.print(str(_('Loading packages...')), clear_screen=True)
repositories |= {Repository.Core, Repository.Extra} repositories |= {Repository.Core, Repository.Extra}
respos_text = ', '.join([r.value for r in repositories])
output = str(_('Repositories: {}')).format(respos_text) + '\n'
output += str(_('Loading packages...'))
Tui.print(output, clear_screen=True)
packages = list_available_packages(tuple(repositories)) packages = list_available_packages(tuple(repositories))
package_groups = PackageGroup.from_available_packages(packages) package_groups = PackageGroup.from_available_packages(packages)

View File

@ -7,7 +7,7 @@ from ..exceptions import RequirementError
from ..general import SysCommand from ..general import SysCommand
from ..output import error, info, warn from ..output import error, info, warn
from ..plugins import plugins from ..plugins import plugins
from .config import Config from .config import PacmanConfig
if TYPE_CHECKING: if TYPE_CHECKING:
from archinstall.lib.translationhandler import DeferredTranslation from archinstall.lib.translationhandler import DeferredTranslation
@ -89,6 +89,6 @@ class Pacman:
__all__ = [ __all__ = [
'Config',
'Pacman', 'Pacman',
'PacmanConfig',
] ]

View File

@ -5,10 +5,13 @@ from shutil import copy2
from ..models.packages import Repository from ..models.packages import Repository
class Config: class PacmanConfig:
def __init__(self, target: Path): def __init__(self, target: Path | None):
self.path = Path("/etc") / "pacman.conf" self._config_path = Path("/etc") / "pacman.conf"
self.chroot_path = target / "etc" / "pacman.conf"
if target:
self._config_remote_path = target / "etc" / "pacman.conf"
self._repositories: list[Repository] = [] self._repositories: list[Repository] = []
def enable(self, repo: Repository | list[Repository]) -> None: def enable(self, repo: Repository | list[Repository]) -> None:
@ -21,26 +24,31 @@ class Config:
if not self._repositories: if not self._repositories:
return return
if Repository.Testing in self._repositories: repos_to_enable = []
if Repository.Multilib in self._repositories: for repo in self._repositories:
repos_pattern = f'({Repository.Multilib.value}|.+-{Repository.Testing.value})' if repo == Repository.Testing:
repos_to_enable.extend(['core-testing', 'extra-testing', 'multilib-testing'])
else: else:
repos_pattern = f'(?!{Repository.Multilib.value}).+-{Repository.Testing.value}' repos_to_enable.append(repo.value)
else:
repos_pattern = Repository.Multilib.value
pattern = re.compile(rf"^#\s*\[{repos_pattern}\]$") content = self._config_path.read_text().splitlines(keepends=True)
lines = iter(self.path.read_text().splitlines(keepends=True))
with open(self.path, 'w') as f: for row, line in enumerate(content):
for line in lines: # Check if this is a commented repository section that needs to be enabled
if pattern.match(line): match = re.match(r'^#\s*\[(.*)\]', line)
# Uncomment this line and the next.
f.write(line.lstrip('#')) if match and match.group(1) in repos_to_enable:
f.write(next(lines).lstrip('#')) # uncomment the repository section line, properly removing # and any spaces
else: content[row] = re.sub(r'^#\s*', '', line)
f.write(line)
# also uncomment the next line (Include statement) if it exists and is commented
if row + 1 < len(content) and content[row + 1].lstrip().startswith('#'):
content[row + 1] = re.sub(r'^#\s*', '', content[row + 1])
# Write the modified content back to the file
with open(self._config_path, 'w') as f:
f.writelines(content)
def persist(self) -> None: def persist(self) -> None:
if self._repositories: if self._repositories and self._config_remote_path:
copy2(self.path, self.chroot_path) copy2(self._config_path, self._config_remote_path)