Move Pacman out of init (#4150)
* Move pacman out of init * Update archinstall/lib/pacman/pacman.py Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> * Update archinstall/lib/pacman/pacman.py Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> --------- Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>
This commit is contained in:
parent
28f7aec2af
commit
2421e538a8
|
|
@ -49,8 +49,8 @@ from .models.mirrors import MirrorConfiguration
|
||||||
from .models.network import Nic
|
from .models.network import Nic
|
||||||
from .models.users import User
|
from .models.users import User
|
||||||
from .output import debug, error, info, log, logger, warn
|
from .output import debug, error, info, log, logger, warn
|
||||||
from .pacman import Pacman
|
|
||||||
from .pacman.config import PacmanConfig
|
from .pacman.config import PacmanConfig
|
||||||
|
from .pacman.pacman import Pacman
|
||||||
from .plugins import plugins
|
from .plugins import plugins
|
||||||
|
|
||||||
# Any package that the Installer() is responsible for (optional and the default ones)
|
# Any package that the Installer() is responsible for (optional and the default ones)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ from urllib.request import urlopen
|
||||||
|
|
||||||
from .exceptions import DownloadTimeout, SysCallError
|
from .exceptions import DownloadTimeout, SysCallError
|
||||||
from .output import debug, error, info
|
from .output import debug, error, info
|
||||||
from .pacman import Pacman
|
from .pacman.pacman import Pacman
|
||||||
|
|
||||||
|
|
||||||
class DownloadTimer:
|
class DownloadTimer:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from functools import lru_cache
|
||||||
from ..exceptions import SysCallError
|
from ..exceptions import SysCallError
|
||||||
from ..models.packages import AvailablePackage, LocalPackage, Repository
|
from ..models.packages import AvailablePackage, LocalPackage, Repository
|
||||||
from ..output import debug
|
from ..output import debug
|
||||||
from ..pacman import Pacman
|
from ..pacman.pacman import Pacman
|
||||||
|
|
||||||
|
|
||||||
# TODO: This shouldn't be living in here but there are too many
|
# TODO: This shouldn't be living in here but there are too many
|
||||||
|
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from collections.abc import Callable
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from archinstall.lib.translationhandler import tr
|
|
||||||
|
|
||||||
from ..exceptions import RequirementError
|
|
||||||
from ..general import SysCommand
|
|
||||||
from ..output import error, info, warn
|
|
||||||
from ..plugins import plugins
|
|
||||||
from .config import PacmanConfig
|
|
||||||
|
|
||||||
|
|
||||||
class Pacman:
|
|
||||||
def __init__(self, target: Path, silent: bool = False):
|
|
||||||
self.synced = False
|
|
||||||
self.silent = silent
|
|
||||||
self.target = target
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def run(args: str, default_cmd: str = 'pacman') -> SysCommand:
|
|
||||||
"""
|
|
||||||
A centralized function to call `pacman` from.
|
|
||||||
It also protects us from colliding with other running pacman sessions (if used locally).
|
|
||||||
The grace period is set to 10 minutes before exiting hard if another pacman instance is running.
|
|
||||||
"""
|
|
||||||
pacman_db_lock = Path('/var/lib/pacman/db.lck')
|
|
||||||
|
|
||||||
if pacman_db_lock.exists():
|
|
||||||
warn(tr('Pacman is already running, waiting maximum 10 minutes for it to terminate.'))
|
|
||||||
|
|
||||||
started = time.time()
|
|
||||||
while pacman_db_lock.exists():
|
|
||||||
time.sleep(0.25)
|
|
||||||
|
|
||||||
if time.time() - started > (60 * 10):
|
|
||||||
error(tr('Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall.'))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return SysCommand(f'{default_cmd} {args}')
|
|
||||||
|
|
||||||
def ask(self, error_message: str, bail_message: str, func: Callable, *args, **kwargs) -> None: # type: ignore[no-untyped-def, type-arg]
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
func(*args, **kwargs)
|
|
||||||
break
|
|
||||||
except Exception as err:
|
|
||||||
error(f'{error_message}: {err}')
|
|
||||||
if not self.silent and input('Would you like to re-try this download? (Y/n): ').lower().strip() in 'y':
|
|
||||||
continue
|
|
||||||
raise RequirementError(f'{bail_message}: {err}')
|
|
||||||
|
|
||||||
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',
|
|
||||||
)
|
|
||||||
self.synced = True
|
|
||||||
|
|
||||||
def strap(self, packages: str | list[str]) -> None:
|
|
||||||
self.sync()
|
|
||||||
if isinstance(packages, str):
|
|
||||||
packages = [packages]
|
|
||||||
|
|
||||||
for plugin in plugins.values():
|
|
||||||
if hasattr(plugin, 'on_pacstrap'):
|
|
||||||
if result := plugin.on_pacstrap(packages):
|
|
||||||
packages = result
|
|
||||||
|
|
||||||
info(f'Installing packages: {packages}')
|
|
||||||
|
|
||||||
self.ask(
|
|
||||||
'Could not strap in packages',
|
|
||||||
'Pacstrap failed. See /var/log/archinstall/install.log or above message for error details',
|
|
||||||
SysCommand,
|
|
||||||
f'pacstrap -C /etc/pacman.conf -K {self.target} {" ".join(packages)} --noconfirm --needed',
|
|
||||||
peek_output=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'Pacman',
|
|
||||||
'PacmanConfig',
|
|
||||||
]
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from collections.abc import Callable
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from archinstall.lib.translationhandler import tr
|
||||||
|
|
||||||
|
from ..exceptions import RequirementError
|
||||||
|
from ..general import SysCommand
|
||||||
|
from ..output import error, info, warn
|
||||||
|
from ..plugins import plugins
|
||||||
|
|
||||||
|
|
||||||
|
class Pacman:
|
||||||
|
def __init__(self, target: Path, silent: bool = False):
|
||||||
|
self.synced = False
|
||||||
|
self.silent = silent
|
||||||
|
self.target = target
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def run(args: str, default_cmd: str = 'pacman') -> SysCommand:
|
||||||
|
"""
|
||||||
|
A centralized function to call `pacman` from.
|
||||||
|
It also protects us from colliding with other running pacman sessions (if used locally).
|
||||||
|
The grace period is set to 10 minutes before exiting hard if another pacman instance is running.
|
||||||
|
"""
|
||||||
|
pacman_db_lock = Path('/var/lib/pacman/db.lck')
|
||||||
|
|
||||||
|
if pacman_db_lock.exists():
|
||||||
|
warn(tr('Pacman is already running, waiting maximum 10 minutes for it to terminate.'))
|
||||||
|
|
||||||
|
started = time.time()
|
||||||
|
while pacman_db_lock.exists():
|
||||||
|
time.sleep(0.25)
|
||||||
|
|
||||||
|
if time.time() - started > (60 * 10):
|
||||||
|
error(tr('Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall.'))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
return SysCommand(f'{default_cmd} {args}')
|
||||||
|
|
||||||
|
def ask(self, error_message: str, bail_message: str, func: Callable, *args, **kwargs) -> None: # type: ignore[no-untyped-def, type-arg]
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
break
|
||||||
|
except Exception as err:
|
||||||
|
error(f'{error_message}: {err}')
|
||||||
|
if not self.silent and input('Would you like to re-try this download? (Y/n): ').lower().strip() in 'y':
|
||||||
|
continue
|
||||||
|
raise RequirementError(f'{bail_message}: {err}')
|
||||||
|
|
||||||
|
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',
|
||||||
|
)
|
||||||
|
self.synced = True
|
||||||
|
|
||||||
|
def strap(self, packages: str | list[str]) -> None:
|
||||||
|
self.sync()
|
||||||
|
if isinstance(packages, str):
|
||||||
|
packages = [packages]
|
||||||
|
|
||||||
|
for plugin in plugins.values():
|
||||||
|
if hasattr(plugin, 'on_pacstrap'):
|
||||||
|
if result := plugin.on_pacstrap(packages):
|
||||||
|
packages = result
|
||||||
|
|
||||||
|
info(f'Installing packages: {packages}')
|
||||||
|
|
||||||
|
self.ask(
|
||||||
|
'Could not strap in packages',
|
||||||
|
'Pacstrap failed. See /var/log/archinstall/install.log or above message for error details',
|
||||||
|
SysCommand,
|
||||||
|
f'pacstrap -C /etc/pacman.conf -K {self.target} {" ".join(packages)} --noconfirm --needed',
|
||||||
|
peek_output=True,
|
||||||
|
)
|
||||||
|
|
@ -16,7 +16,7 @@ from archinstall.lib.packages.packages import check_version_upgrade
|
||||||
|
|
||||||
from .lib.hardware import SysInfo
|
from .lib.hardware import SysInfo
|
||||||
from .lib.output import debug, error, info, warn
|
from .lib.output import debug, error, info, warn
|
||||||
from .lib.pacman import Pacman
|
from .lib.pacman.pacman import Pacman
|
||||||
from .lib.translationhandler import tr
|
from .lib.translationhandler import tr
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue