art_apply: statvfs pre-flight is POSIX-only — Windows has no os.statvfs
Boulder's lock-in question caught it: the read-only pre-flight called os.statvfs unconditionally, which doesn't exist on Windows, and the AttributeError wasn't covered by the except OSError — the whole cover-art apply would have crashed for every Windows install (docker images are Linux, so the reporter was fine; the maintainer wasn't). getattr-guarded now: no statvfs -> skip the pre-flight, per-file EROFS detection (errno is cross-platform) still active. Test pins the no-statvfs path.
This commit is contained in:
parent
3c758635d5
commit
ece74250fb
2 changed files with 24 additions and 2 deletions
|
|
@ -126,10 +126,13 @@ def apply_art_to_album_files(
|
|||
# Pre-flight: if the mount is read-only, every save below would fail with
|
||||
# EROFS one by one (Tim's report: a wall of per-file warnings and a 777
|
||||
# chmod that couldn't help). statvfs asks the kernel without writing.
|
||||
# POSIX-only — Windows has no os.statvfs (and no ':ro' bind mounts);
|
||||
# there we skip straight to the per-file path, same as before this fix.
|
||||
probe_dir = folder or (os.path.dirname(paths[0]) if paths else None)
|
||||
if probe_dir:
|
||||
_statvfs = getattr(os, "statvfs", None)
|
||||
if probe_dir and _statvfs is not None:
|
||||
try:
|
||||
if os.statvfs(probe_dir).f_flag & os.ST_RDONLY:
|
||||
if _statvfs(probe_dir).f_flag & getattr(os, "ST_RDONLY", 1):
|
||||
logger.warning(
|
||||
"Art apply skipped: %s is on a READ-ONLY filesystem "
|
||||
"(docker ':ro' volume mount — chmod cannot fix this)",
|
||||
|
|
|
|||
|
|
@ -203,3 +203,22 @@ def test_apply_normal_failure_not_flagged_read_only(tmp_path, monkeypatch):
|
|||
|
||||
assert res['read_only_fs'] is False # EACCES is chmod-able, EROFS is not
|
||||
assert res['failed'] == 1
|
||||
|
||||
|
||||
def test_apply_works_without_statvfs_windows(tmp_path, monkeypatch):
|
||||
"""Windows has no os.statvfs — the pre-flight must vanish gracefully,
|
||||
not crash the apply (Boulder runs on Windows)."""
|
||||
f = tmp_path / 'a.mp3'
|
||||
f.write_bytes(b'')
|
||||
saved = []
|
||||
audio = SimpleNamespace(pictures=[], tags=None, add_tags=lambda: None,
|
||||
save=lambda: saved.append(True))
|
||||
monkeypatch.setattr(aa, 'get_mutagen_symbols', lambda: _fake_symbols(audio))
|
||||
monkeypatch.setattr(aa, 'embed_album_art_metadata', lambda *a, **k: True)
|
||||
monkeypatch.setattr(aa, 'download_cover_art', lambda *a, **k: None)
|
||||
monkeypatch.delattr(aa.os, 'statvfs', raising=False)
|
||||
|
||||
res = aa.apply_art_to_album_files([str(f)], {}, {}, folder=str(tmp_path))
|
||||
|
||||
assert res['embedded'] == 1 and saved == [True]
|
||||
assert res['read_only_fs'] is False
|
||||
|
|
|
|||
Loading…
Reference in a new issue