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.encryption_menu import DiskEncryptionMenu
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 .args import ArchConfig
@ -29,9 +30,11 @@ from .models.bootloader import Bootloader
from .models.locale import LocaleConfiguration
from .models.mirrors import MirrorConfiguration
from .models.network_configuration import NetworkConfiguration, NicType
from .models.packages import Repository
from .models.profile_model import ProfileConfiguration
from .models.users import Password, User
from .output import FormattedOutput
from .pacman.config import PacmanConfig
from .translationhandler import Language, translation_handler
from .utils.util import get_password
@ -168,7 +171,7 @@ class GlobalMenu(AbstractMenu[None]):
),
MenuItem(
text=str(_('Additional packages')),
action=ask_additional_packages_to_install,
action=self._select_additional_packages,
value=[],
preview_action=self._prev_additional_pkgs,
key='packages'
@ -536,6 +539,20 @@ class GlobalMenu(AbstractMenu[None]):
profile_config = ProfileMenu(preset=current_profile).run()
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]:
preset = [] if preset is None else 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:
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
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 .output import debug, error, info, log, warn
from .pacman import Pacman
from .pacman.config import Config
from .pacman.config import PacmanConfig
from .plugins import plugins
from .storage import storage
@ -847,7 +847,7 @@ class Installer:
debug(f'Optional repositories: {optional_repositories}')
# 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.apply()

View File

@ -178,9 +178,14 @@ def ask_additional_packages_to_install(
preset: list[str] = [],
repositories: set[Repository] = set()
) -> list[str]:
Tui.print(str(_('Loading packages...')), clear_screen=True)
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))
package_groups = PackageGroup.from_available_packages(packages)

View File

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

View File

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