Refuse to write to an unmounted volume and stop if the disk disappears

This commit is contained in:
Justin Oros
2026-09-26 21:37:39 -07:00
parent df5bcbb185
commit 4c4e7eb8a8
+24 -1
View File
@@ -304,7 +304,19 @@ def published_root(s):
return resolve_storage(s["storage_dir"]) / "published" return resolve_storage(s["storage_dir"]) / "published"
def volume_ready(path):
parts = Path(path).resolve().parts
if len(parts) >= 3 and parts[1] == "Volumes":
mount = Path("/Volumes") / parts[2]
if not os.path.ismount(str(mount)):
return False, str(mount)
return True, ""
def writable(root): def writable(root):
ok, mount = volume_ready(root)
if not ok:
raise ValueError(f"The volume {mount} is not mounted. Connect the disk, or pick a different folder in Settings")
try: try:
root.mkdir(parents=True, exist_ok=True) root.mkdir(parents=True, exist_ok=True)
probe = root / ".write_test" probe = root / ".write_test"
@@ -491,6 +503,15 @@ def sweep_temp(temp, max_age_hours=1):
logger.info("Cleaned %d old items from the temp folder", removed) logger.info("Cleaned %d old items from the temp folder", removed)
def check_storage_alive(s):
root = resolve_storage(s["storage_dir"])
ok, mount = volume_ready(root)
if not ok:
raise RuntimeError(f"The volume {mount} is no longer mounted, the disk may have unmounted. Nothing more was written")
if not root.is_dir():
raise RuntimeError(f"The storage folder {root} disappeared, the disk may have unmounted")
def prepare_storage(s): def prepare_storage(s):
root = validate_storage(s["storage_dir"]) root = validate_storage(s["storage_dir"])
free = free_gb(root) free = free_gb(root)
@@ -1889,6 +1910,7 @@ def run_job(s):
anatomy_flags.append(i) anatomy_flags.append(i)
for i, scene in enumerate(script["scenes"], 1): for i, scene in enumerate(script["scenes"], 1):
check_storage_alive(s)
path = job_dir / f"clip_{i:02d}.mp4" path = job_dir / f"clip_{i:02d}.mp4"
clips.append(path) clips.append(path)
verdict = "pass" verdict = "pass"
@@ -1949,6 +1971,7 @@ def run_job(s):
compliance["anatomy_note"] = anatomy_note compliance["anatomy_note"] = anatomy_note
prior = "; ".join(compliance.get("reviewer_notes", [])) prior = "; ".join(compliance.get("reviewer_notes", []))
update_history(job_id, notes=(prior + "; " if prior else "") + anatomy_note) update_history(job_id, notes=(prior + "; " if prior else "") + anatomy_note)
check_storage_alive(s)
set_stage("stitching video", step=3 + n * 2) set_stage("stitching video", step=3 + n * 2)
final = job_dir / "final.mp4" final = job_dir / "final.mp4"
concat_clips(clips, final, s["aspect_ratio"]) concat_clips(clips, final, s["aspect_ratio"])
@@ -2014,7 +2037,7 @@ def run_loop():
except Cancelled: except Cancelled:
break break
except Exception as e: except Exception as e:
if "has expired" in str(e): if "has expired" in str(e) or "not mounted" in str(e) or "unmounted" in str(e):
logger.error("%s", e) logger.error("%s", e)
else: else:
logger.exception("Job failed: %s", e) logger.exception("Job failed: %s", e)