mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-05 06:45:09 +00:00
fix(backup): restore over existing files on hosts without os.chown (#592)
_copy_file() replaces each restored file and then carries the previous owner across with os.chown. On Windows os.chown does not exist and st_uid/st_gid are 0 rather than absent, so the ownership branch always ran and raised AttributeError. That is not an OSError, so it escaped every per-section handler in restore_backup(): a restore over any existing config aborted at config.json and restored nothing. Skip the ownership step where os.chown is missing, as auto_update_setup.py already does. No change on POSIX. test_restore_over_a_file_the_user_cannot_write simulates root-owned files with chmod 0o444; on Windows that sets the read-only attribute, which blocks any rename over the file, so it is skipped there. The modes the app writes (0o644/0o640/0o600) replace fine on Windows. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -530,12 +530,15 @@ def _copy_file(src: Path, dst: Path) -> None:
|
||||
os.chmod(tmp_path, existing_mode)
|
||||
else:
|
||||
shutil.copymode(src, tmp_path)
|
||||
if existing_owner is not None:
|
||||
if existing_owner is not None and hasattr(os, 'chown'):
|
||||
# Replacing a file creates a new inode owned by whoever is running,
|
||||
# which would silently move a root-owned config to the web user.
|
||||
# Carry the previous owner across when the OS permits it — only
|
||||
# root can hand a file to another user, so this is best-effort and
|
||||
# a plain restore as the web user simply keeps its own ownership.
|
||||
# os.chown does not exist on Windows (where st_uid/st_gid are just
|
||||
# 0); looking it up there raises AttributeError, which no caller
|
||||
# catches, so every restore over an existing file aborted.
|
||||
try:
|
||||
os.chown(tmp_path, existing_owner[0], existing_owner[1])
|
||||
except (OSError, PermissionError):
|
||||
|
||||
Reference in New Issue
Block a user