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

@ -85,22 +85,22 @@ class CopyFileTest(unittest.TestCase):
self.assertEqual(os.path.getsize(self.dst), 100)
def test_retries_then_succeeds(self):
real_copy = dashcam.shutil.copyfile
real_copy2 = dashcam.shutil.copy2
calls = {"n": 0}
def flaky(s, d):
calls["n"] += 1
if calls["n"] < 3:
raise OSError(errno.EIO, "I/O error")
real_copy(s, d)
real_copy2(s, d)
with mock.patch.object(dashcam.shutil, "copyfile", side_effect=flaky):
with mock.patch.object(dashcam.shutil, "copy2", side_effect=flaky):
dashcam.copy_file(self.src, self.dst, attempts=3, delay=0)
self.assertEqual(calls["n"], 3)
self.assertEqual(os.path.getsize(self.dst), 100)
def test_raises_after_exhausting_attempts(self):
with mock.patch.object(dashcam.shutil, "copyfile", side_effect=OSError(errno.EIO, "I/O error")):
with mock.patch.object(dashcam.shutil, "copy2", side_effect=OSError(errno.EIO, "I/O error")):
with self.assertRaises(OSError):
dashcam.copy_file(self.src, self.dst, attempts=2, delay=0)
@ -155,11 +155,11 @@ class TransferFilesTest(unittest.TestCase):
def test_verification_mismatch_counts_as_error_and_keeps_source(self):
files = [self._make("20260622050346_0000001F.MP4", 100)]
def bad_copy(s, d):
def bad_copy2(s, d):
with open(d, "wb") as f:
f.write(b"0" * 50)
with mock.patch.object(dashcam.shutil, "copyfile", side_effect=bad_copy), mock.patch.object(
with mock.patch.object(dashcam.shutil, "copy2", side_effect=bad_copy2), mock.patch.object(
dashcam.time, "sleep"
):
ok, errors = dashcam.transfer_files(files, self.src, self.base)
@ -172,7 +172,7 @@ class TransferFilesTest(unittest.TestCase):
for i in range(dashcam.MAX_CONSECUTIVE_ERRORS + 3)
]
with mock.patch.object(
dashcam.shutil, "copyfile", side_effect=OSError(errno.EIO, "I/O error")
dashcam.shutil, "copy2", side_effect=OSError(errno.EIO, "I/O error")
), mock.patch.object(dashcam.time, "sleep"):
with self.assertRaises(dashcam.TransferAborted) as ctx:
dashcam.transfer_files(files, self.src, self.base)