Skip to content

Commit f09ca43

Browse files
committed
Rework install log
1 parent a5d995b commit f09ca43

File tree

6 files changed

+51
-57
lines changed

6 files changed

+51
-57
lines changed

archinstall/lib/args.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
from archinstall.lib.models.packages import Repository
2323
from archinstall.lib.models.profile_model import ProfileConfiguration
2424
from archinstall.lib.models.users import Password, User
25-
from archinstall.lib.output import debug, error, warn
25+
from archinstall.lib.output import debug, error, logger, warn
2626
from archinstall.lib.plugins import load_plugin
27-
from archinstall.lib.storage import storage
2827
from archinstall.lib.translationhandler import Language, tr, translation_handler
2928
from archinstall.lib.utils.util import get_password
3029
from archinstall.tui.curses_menu import Tui
@@ -389,7 +388,7 @@ def _parse_args(self) -> Arguments:
389388
args.silent = False
390389

391390
if args.debug:
392-
warn(f'Warning: --debug mode will write certain credentials to {storage["LOG_PATH"]}/{storage["LOG_FILE"]}!')
391+
warn(f'Warning: --debug mode will write certain credentials to {logger.path}!')
393392

394393
if args.plugin:
395394
plugin_path = Path(args.plugin)

archinstall/lib/configuration.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
from .args import ArchConfig
1313
from .crypt import encrypt
1414
from .general import JSON, UNSAFE_JSON
15-
from .output import debug, warn
16-
from .storage import storage
15+
from .output import debug, logger, warn
1716
from .utils.util import get_password, prompt_dir
1817

1918

@@ -29,7 +28,7 @@ def __init__(self, config: ArchConfig):
2928
"""
3029

3130
self._config = config
32-
self._default_save_path = storage.get('LOG_PATH', Path('.'))
31+
self._default_save_path = logger.directory
3332
self._user_config_file = Path('user_configuration.json')
3433
self._user_creds_file = Path('user_credentials.json')
3534

archinstall/lib/general.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
from typing import Any, override
2020

2121
from .exceptions import RequirementError, SysCallError
22-
from .output import debug, error
23-
from .storage import storage
22+
from .output import debug, error, logger
2423

2524
# https://stackoverflow.com/a/43627833/929999
2625
_VT100_ESCAPE_REGEX = r'\x1B\[[?0-9;]*[a-zA-Z]'
@@ -415,7 +414,7 @@ def trace_log(self) -> bytes | None:
415414

416415

417416
def _append_log(file: str, content: str) -> None:
418-
path = Path(f'{storage["LOG_PATH"]}/{file}')
417+
path = logger.directory / file
419418

420419
change_perm = not path.exists()
421420

archinstall/lib/installer.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from .models.mirrors import MirrorConfiguration
4545
from .models.network_configuration import Nic
4646
from .models.users import User
47-
from .output import debug, error, info, log, warn
47+
from .output import debug, error, info, log, logger, warn
4848
from .pacman import Pacman
4949
from .pacman.config import PacmanConfig
5050
from .plugins import plugins
@@ -132,13 +132,12 @@ def __exit__(self, exc_type: type[BaseException] | None, exc_val, exc_tb: Traceb
132132

133133
# We avoid printing /mnt/<log path> because that might confuse people if they note it down
134134
# and then reboot, and a identical log file will be found in the ISO medium anyway.
135-
log_file = os.path.join(storage['LOG_PATH'], storage['LOG_FILE'])
136-
Tui.print(str(tr('[!] A log file has been created here: {}').format(log_file)))
135+
Tui.print(str(tr('[!] A log file has been created here: {}').format(logger.path)))
137136
Tui.print(tr('Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues'))
138137
raise exc_val
139138

140139
if not (missing_steps := self.post_install_check()):
141-
msg = f'Installation completed without any errors.\nLog files temporarily available at {storage["LOG_PATH"]}.\nYou may reboot when ready.\n'
140+
msg = f'Installation completed without any errors.\nLog files temporarily available at {logger.directory}.\nYou may reboot when ready.\n'
142141
log(msg, fg='green')
143142
self.sync_log_to_install_medium()
144143
return True
@@ -148,7 +147,7 @@ def __exit__(self, exc_type: type[BaseException] | None, exc_val, exc_tb: Traceb
148147
for step in missing_steps:
149148
warn(f' - {step}')
150149

151-
warn(f'Detailed error logs can be found at: {storage["LOG_PATH"]}')
150+
warn(f'Detailed error logs can be found at: {logger.directory}')
152151
warn('Submit this zip file as an issue to https://github.com/archlinux/archinstall/issues')
153152

154153
self.sync_log_to_install_medium()
@@ -456,13 +455,12 @@ def sync_log_to_install_medium(self) -> bool:
456455
# Copy over the install log (if there is one) to the install medium if
457456
# at least the base has been strapped in, otherwise we won't have a filesystem/structure to copy to.
458457
if self._helper_flags.get('base-strapped', False) is True:
459-
if filename := storage.get('LOG_FILE', None):
460-
absolute_logfile = os.path.join(storage.get('LOG_PATH', './'), filename)
458+
absolute_logfile = logger.path
461459

462-
if not os.path.isdir(f'{self.target}/{os.path.dirname(absolute_logfile)}'):
463-
os.makedirs(f'{self.target}/{os.path.dirname(absolute_logfile)}')
460+
if not os.path.isdir(f'{self.target}/{os.path.dirname(absolute_logfile)}'):
461+
os.makedirs(f'{self.target}/{os.path.dirname(absolute_logfile)}')
464462

465-
shutil.copy2(absolute_logfile, f'{self.target}/{absolute_logfile}')
463+
shutil.copy2(absolute_logfile, f'{self.target}/{absolute_logfile}')
466464

467465
return True
468466

archinstall/lib/output.py

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from pathlib import Path
99
from typing import TYPE_CHECKING, Any
1010

11-
from .storage import storage
1211
from .utils.unicode import unicode_ljust, unicode_rjust
1312

1413
if TYPE_CHECKING:
@@ -147,30 +146,46 @@ def log(message: str, level: int = logging.DEBUG) -> None:
147146
log_adapter.log(level, message)
148147

149148

150-
def _check_log_permissions() -> None:
151-
filename = storage.get('LOG_FILE', None)
152-
log_dir = storage.get('LOG_PATH', Path('./'))
149+
class Logger:
150+
def __init__(self, path: Path = Path('/var/log/archinstall')) -> None:
151+
self._path = path
153152

154-
if not filename:
155-
raise ValueError('No log file name defined')
153+
@property
154+
def path(self) -> Path:
155+
return self._path / 'install.log'
156156

157-
log_file = log_dir / filename
157+
@property
158+
def directory(self) -> Path:
159+
return self._path
158160

159-
try:
160-
log_dir.mkdir(exist_ok=True, parents=True)
161-
log_file.touch(exist_ok=True)
161+
def _check_permissions(self) -> None:
162+
log_file = self.path
162163

163-
with log_file.open('a') as fp:
164-
fp.write('')
165-
except PermissionError:
166-
# Fallback to creating the log file in the current folder
167-
fallback_dir = Path('./').absolute()
168-
fallback_log_file = fallback_dir / filename
164+
try:
165+
self._path.mkdir(exist_ok=True, parents=True)
166+
log_file.touch(exist_ok=True)
167+
168+
with log_file.open('a') as f:
169+
f.write('')
170+
except PermissionError:
171+
# Fallback to creating the log file in the current folder
172+
logger._path = Path('./').absolute()
173+
174+
warn(
175+
f'Not enough permission to place log file at {log_file},',
176+
'creating it in {logger.path} instead'
177+
)
178+
179+
def log(self, level: int, content: str) -> None:
180+
self._check_permissions()
169181

170-
fallback_log_file.touch(exist_ok=True)
182+
with self.path.open('a') as f:
183+
ts = _timestamp()
184+
level_name = logging.getLevelName(level)
185+
f.write(f'[{ts}] - {level_name} - {content}\n')
171186

172-
storage['LOG_PATH'] = fallback_dir
173-
warn(f'Not enough permission to place log file at {log_file}, creating it in {fallback_log_file} instead')
187+
188+
logger = Logger()
174189

175190

176191
def _supports_color() -> bool:
@@ -309,25 +324,15 @@ def log(
309324
reset: bool = False,
310325
font: list[Font] = [],
311326
) -> None:
312-
# leave this check here as we need to setup the logging
313-
# right from the beginning when the modules are loaded
314-
_check_log_permissions()
327+
text = ' '.join([str(x) for x in msgs])
315328

316-
text = orig_string = ' '.join([str(x) for x in msgs])
329+
logger.log(level, text)
317330

318331
# Attempt to colorize the output if supported
319332
# Insert default colors and override with **kwargs
320333
if _supports_color():
321334
text = _stylize_output(text, fg, bg, reset, font)
322335

323-
log_file = storage['LOG_PATH'] / storage['LOG_FILE']
324-
325-
with log_file.open('a') as fp:
326-
ts = _timestamp()
327-
level_name = logging.getLevelName(level)
328-
out = f'[{ts}] - {level_name} - {orig_string}\n'
329-
fp.write(out)
330-
331336
Journald.log(text, level=level)
332337

333338
if level != logging.DEBUG:

archinstall/lib/storage.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
# (4. Added the ~/.config directory as an additional option for future reasons)
66
#
77
# And Keeping this in dict ensures that variables are shared across imports.
8-
from pathlib import Path
98
from typing import TYPE_CHECKING, NotRequired, TypedDict
109

1110
if TYPE_CHECKING:
@@ -14,13 +13,8 @@
1413

1514

1615
class _StorageDict(TypedDict):
17-
LOG_FILE: Path
18-
LOG_PATH: Path
1916
active_boot: NotRequired['Boot | None']
2017
installation_session: NotRequired['Installer']
2118

2219

23-
storage: _StorageDict = {
24-
'LOG_FILE': Path('install.log'),
25-
'LOG_PATH': Path('/var/log/archinstall'),
26-
}
20+
storage: _StorageDict = {}

0 commit comments

Comments
 (0)