Rework install log (#3550)

This commit is contained in:
codefiles 2025-05-30 09:08:02 -04:00 committed by GitHub
parent a5d995b546
commit 1dccfe6c33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 51 additions and 57 deletions

View File

@ -22,9 +22,8 @@ from archinstall.lib.models.network_configuration import NetworkConfiguration
from archinstall.lib.models.packages import Repository
from archinstall.lib.models.profile_model import ProfileConfiguration
from archinstall.lib.models.users import Password, User
from archinstall.lib.output import debug, error, warn
from archinstall.lib.output import debug, error, logger, warn
from archinstall.lib.plugins import load_plugin
from archinstall.lib.storage import storage
from archinstall.lib.translationhandler import Language, tr, translation_handler
from archinstall.lib.utils.util import get_password
from archinstall.tui.curses_menu import Tui
@ -389,7 +388,7 @@ class ArchConfigHandler:
args.silent = False
if args.debug:
warn(f'Warning: --debug mode will write certain credentials to {storage["LOG_PATH"]}/{storage["LOG_FILE"]}!')
warn(f'Warning: --debug mode will write certain credentials to {logger.path}!')
if args.plugin:
plugin_path = Path(args.plugin)

View File

@ -12,8 +12,7 @@ from archinstall.tui.types import Alignment, FrameProperties, Orientation, Previ
from .args import ArchConfig
from .crypt import encrypt
from .general import JSON, UNSAFE_JSON
from .output import debug, warn
from .storage import storage
from .output import debug, logger, warn
from .utils.util import get_password, prompt_dir
@ -29,7 +28,7 @@ class ConfigurationOutput:
"""
self._config = config
self._default_save_path = storage.get('LOG_PATH', Path('.'))
self._default_save_path = logger.directory
self._user_config_file = Path('user_configuration.json')
self._user_creds_file = Path('user_credentials.json')

View File

@ -19,8 +19,7 @@ from shutil import which
from typing import Any, override
from .exceptions import RequirementError, SysCallError
from .output import debug, error
from .storage import storage
from .output import debug, error, logger
# https://stackoverflow.com/a/43627833/929999
_VT100_ESCAPE_REGEX = r'\x1B\[[?0-9;]*[a-zA-Z]'
@ -415,7 +414,7 @@ class SysCommand:
def _append_log(file: str, content: str) -> None:
path = Path(f'{storage["LOG_PATH"]}/{file}')
path = logger.directory / file
change_perm = not path.exists()

View File

@ -44,7 +44,7 @@ from .models.locale import LocaleConfiguration
from .models.mirrors import MirrorConfiguration
from .models.network_configuration import Nic
from .models.users import User
from .output import debug, error, info, log, warn
from .output import debug, error, info, log, logger, warn
from .pacman import Pacman
from .pacman.config import PacmanConfig
from .plugins import plugins
@ -132,13 +132,12 @@ class Installer:
# We avoid printing /mnt/<log path> because that might confuse people if they note it down
# and then reboot, and a identical log file will be found in the ISO medium anyway.
log_file = os.path.join(storage['LOG_PATH'], storage['LOG_FILE'])
Tui.print(str(tr('[!] A log file has been created here: {}').format(log_file)))
Tui.print(str(tr('[!] A log file has been created here: {}').format(logger.path)))
Tui.print(tr('Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues'))
raise exc_val
if not (missing_steps := self.post_install_check()):
msg = f'Installation completed without any errors.\nLog files temporarily available at {storage["LOG_PATH"]}.\nYou may reboot when ready.\n'
msg = f'Installation completed without any errors.\nLog files temporarily available at {logger.directory}.\nYou may reboot when ready.\n'
log(msg, fg='green')
self.sync_log_to_install_medium()
return True
@ -148,7 +147,7 @@ class Installer:
for step in missing_steps:
warn(f' - {step}')
warn(f'Detailed error logs can be found at: {storage["LOG_PATH"]}')
warn(f'Detailed error logs can be found at: {logger.directory}')
warn('Submit this zip file as an issue to https://github.com/archlinux/archinstall/issues')
self.sync_log_to_install_medium()
@ -456,13 +455,12 @@ class Installer:
# Copy over the install log (if there is one) to the install medium if
# at least the base has been strapped in, otherwise we won't have a filesystem/structure to copy to.
if self._helper_flags.get('base-strapped', False) is True:
if filename := storage.get('LOG_FILE', None):
absolute_logfile = os.path.join(storage.get('LOG_PATH', './'), filename)
absolute_logfile = logger.path
if not os.path.isdir(f'{self.target}/{os.path.dirname(absolute_logfile)}'):
os.makedirs(f'{self.target}/{os.path.dirname(absolute_logfile)}')
if not os.path.isdir(f'{self.target}/{os.path.dirname(absolute_logfile)}'):
os.makedirs(f'{self.target}/{os.path.dirname(absolute_logfile)}')
shutil.copy2(absolute_logfile, f'{self.target}/{absolute_logfile}')
shutil.copy2(absolute_logfile, f'{self.target}/{absolute_logfile}')
return True

View File

@ -8,7 +8,6 @@ from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING, Any
from .storage import storage
from .utils.unicode import unicode_ljust, unicode_rjust
if TYPE_CHECKING:
@ -147,30 +146,46 @@ class Journald:
log_adapter.log(level, message)
def _check_log_permissions() -> None:
filename = storage.get('LOG_FILE', None)
log_dir = storage.get('LOG_PATH', Path('./'))
class Logger:
def __init__(self, path: Path = Path('/var/log/archinstall')) -> None:
self._path = path
if not filename:
raise ValueError('No log file name defined')
@property
def path(self) -> Path:
return self._path / 'install.log'
log_file = log_dir / filename
@property
def directory(self) -> Path:
return self._path
try:
log_dir.mkdir(exist_ok=True, parents=True)
log_file.touch(exist_ok=True)
def _check_permissions(self) -> None:
log_file = self.path
with log_file.open('a') as fp:
fp.write('')
except PermissionError:
# Fallback to creating the log file in the current folder
fallback_dir = Path('./').absolute()
fallback_log_file = fallback_dir / filename
try:
self._path.mkdir(exist_ok=True, parents=True)
log_file.touch(exist_ok=True)
fallback_log_file.touch(exist_ok=True)
with log_file.open('a') as f:
f.write('')
except PermissionError:
# Fallback to creating the log file in the current folder
logger._path = Path('./').absolute()
storage['LOG_PATH'] = fallback_dir
warn(f'Not enough permission to place log file at {log_file}, creating it in {fallback_log_file} instead')
warn(
f'Not enough permission to place log file at {log_file},',
'creating it in {logger.path} instead'
)
def log(self, level: int, content: str) -> None:
self._check_permissions()
with self.path.open('a') as f:
ts = _timestamp()
level_name = logging.getLevelName(level)
f.write(f'[{ts}] - {level_name} - {content}\n')
logger = Logger()
def _supports_color() -> bool:
@ -309,25 +324,15 @@ def log(
reset: bool = False,
font: list[Font] = [],
) -> None:
# leave this check here as we need to setup the logging
# right from the beginning when the modules are loaded
_check_log_permissions()
text = ' '.join([str(x) for x in msgs])
text = orig_string = ' '.join([str(x) for x in msgs])
logger.log(level, text)
# Attempt to colorize the output if supported
# Insert default colors and override with **kwargs
if _supports_color():
text = _stylize_output(text, fg, bg, reset, font)
log_file = storage['LOG_PATH'] / storage['LOG_FILE']
with log_file.open('a') as fp:
ts = _timestamp()
level_name = logging.getLevelName(level)
out = f'[{ts}] - {level_name} - {orig_string}\n'
fp.write(out)
Journald.log(text, level=level)
if level != logging.DEBUG:

View File

@ -5,7 +5,6 @@
# (4. Added the ~/.config directory as an additional option for future reasons)
#
# And Keeping this in dict ensures that variables are shared across imports.
from pathlib import Path
from typing import TYPE_CHECKING, NotRequired, TypedDict
if TYPE_CHECKING:
@ -14,13 +13,8 @@ if TYPE_CHECKING:
class _StorageDict(TypedDict):
LOG_FILE: Path
LOG_PATH: Path
active_boot: NotRequired['Boot | None']
installation_session: NotRequired['Installer']
storage: _StorageDict = {
'LOG_FILE': Path('install.log'),
'LOG_PATH': Path('/var/log/archinstall'),
}
storage: _StorageDict = {}