fix: service draait als uid 1000 (eddy), eigenaar van de exfat-SSD

Root was bad practice (oude staat); aiaiaiaiagent (uid 1001) kon geen
chmod/utime op de exfat-mount (uid=1000) -> elke copy2-kopie faalde met
EPERM (10-15, 0/68). Correcte laag is de identity-laag, niet de kopieer-
primitive: User=eddy (mount-eigenaar). copy2 behouden (timestamps op
doel). Matrix-secrets sherpa-token/eddy-report-room -> mode 640 group
eddy + traverse op /home/aiaiaiaiagent zodat de notificatie werkt.

Revert eerdere copyfile-workaround (dd46ad6/69d08ba): die maskeerde de
mismatch in plaats van de principal te aligneren.
This commit is contained in:
Eddy de Vink 2026-10-15 20:25:50 +02:00
commit 0461fbc074
3 changed files with 28 additions and 25 deletions

View file

@ -150,16 +150,16 @@ def ensure_free_space(needed_bytes, target_base):
def copy_file(src, dst, attempts=MAX_RETRIES, delay=RETRY_DELAY):
"""Copy src → dst with retry. Raises the last OSError when all attempts fail."""
# copy2 preserveert timestamps (os.utime) en mode (os.chmod) op het doel.
# Dat vereist eigenaarschap van het doelbestand: de exfat-mount draait als
# uid=1000 en álle bestanden op de SSD zijn eigendom van uid 1000. De unit
# draait daarom als User=eddy (uid 1000) — NIET als root, NIET als een
# andere gebruiker (chmod/utime → EPERM voor niet-eigenaars). Bestand →
# copyfile omwisselen zou deze invariant verbergen en opnieuw breken.
last_error = None
for attempt in range(1, attempts + 1):
try:
# copyfile (niet copy/copy2): die doen ook metadata-operaties op het
# doel — chmod en utime. Op exfat met mountuid=1000 zijn álle bestanden
# eigendom van uid 1000, en allow_utime=0022 + chmod-toestand weigeren
# dat voor de niet-eigenaar service-gebruiker (EPERM op elke kopie).
# copyfile schrijft alleen data; mode is op exfat altijd 0777 en het
# opnamemoment staat al in de bestandsnaam (YYYYMMDDHHMMSS).
shutil.copyfile(src, dst)
shutil.copy2(src, dst)
return
except OSError as e:
last_error = e