fix(iso): muzzle archinstall sync_log_to_install_medium on Py 3.14

Python 3.14 added pathlib.Path.copy() which refuses source==target with
OSError [Errno 22]. archinstall's sync_log_to_install_medium() calls
.copy() on install.log to itself at __exit__ time, because by then the
chroot mountpoint is already torn down and both source and target
resolve to the same /var/log/archinstall/install.log. The install
itself has already succeeded — the crash is in the log-sync cleanup.

Patch is a pre-start sed on the live ISO that replaces the offending
call with `None` (a no-op expression-statement keeping the same
indent level). Lives on furtka-webinstaller.service as ExecStartPre
so it runs before the first install attempt; idempotent, so service
restarts don't re-trigger anything. Never touches the installed
system — only the live ISO's site-packages tree.

Real fix is upstream in archinstall (guard the copy when source
and target resolve equal); this is a workaround until they ship it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Maksymilian Syrnicki 2026-04-16 15:17:19 +02:00
parent a6aa95e097
commit 661f51e91a

View file

@ -6,6 +6,14 @@ Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/furtka
# Python 3.14's new pathlib.Path.copy() refuses source==target paths, and
# archinstall's sync_log_to_install_medium() trips on that at __exit__
# because the chroot bindmount is already gone by the time it copies
# /var/log/archinstall/install.log. The install itself has already
# succeeded; this just means the log-sync step throws a misleading
# traceback. Neutralise the call on the live ISO (never runs on the
# target) so users don't see it. Idempotent — second run is a no-op.
ExecStartPre=/bin/sh -c 'sed -i "s|absolute_logfile\\.copy(logfile_target, preserve_metadata=True)|None # furtka patch: py3.14 Path.copy same-path workaround|" /usr/lib/python*/site-packages/archinstall/lib/installer.py || true'
ExecStart=/usr/bin/python -m flask --app app run --host 0.0.0.0 --port 5000
Restart=on-failure
RestartSec=3