Skip to content
Merged
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
30 changes: 29 additions & 1 deletion archinstall/lib/global_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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
Expand All @@ -29,9 +30,11 @@
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

Expand Down Expand Up @@ -168,7 +171,7 @@ def _get_menu_options(self) -> list[MenuItem]:
),
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'
Expand Down Expand Up @@ -536,13 +539,38 @@ def _select_profile(self, current_profile: ProfileConfiguration | 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)
return users

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:
Expand Down
4 changes: 2 additions & 2 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
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

Expand Down Expand Up @@ -847,7 +847,7 @@ def minimal_installation(
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()

Expand Down
9 changes: 7 additions & 2 deletions archinstall/lib/interactions/general_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions archinstall/lib/pacman/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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
Expand Down Expand Up @@ -89,6 +89,6 @@ def strap(self, packages: str | list[str]) -> None:


__all__ = [
'Config',
'Pacman',
'PacmanConfig',
]
56 changes: 32 additions & 24 deletions archinstall/lib/pacman/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
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:
Expand All @@ -21,26 +24,31 @@ def apply(self) -> None:
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

pattern = re.compile(rf"^#\s*\[{repos_pattern}\]$")
lines = iter(self.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)
repos_to_enable.append(repo.value)

content = self._config_path.read_text().splitlines(keepends=True)

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)