Fix SAM symlink crash and make prefetch-models.sh resilient per-step

download_sam_model.py crashed with an uncaught PermissionError when
data/models/ is root-owned (common after a prior Docker run) and a
non-root host user tries to recreate the convenience sam_model.pth
symlink — observed in the wild, and it aborted the whole prefetch run
before U2Net/BEN2/BiRefNet-HR were ever attempted. Worse, the same
unguarded symlink call sat inside the post-download try/except, so a
successful download could get deleted just because the symlink step
failed afterward. Wrapped symlink creation in a shared helper that
warns and continues instead of raising — the real model file already
satisfies entrypoint.sh's checks regardless of the symlink.

prefetch-models.sh now treats SAM, U2Net, and the HuggingFace models as
independent steps (one failing no longer aborts the rest) and prints a
summary of which steps failed, so a single run gives full diagnostic
signal instead of stopping at the first error.
This commit is contained in:
Claude
2026-06-18 16:33:17 +00:00
parent 3a977c7438
commit 851e255641
2 changed files with 50 additions and 29 deletions
+16 -11
View File
@@ -40,6 +40,20 @@ SAM_MODELS = {
}
}
def create_symlink(symlink_path: Path, target_name: str):
"""Best-effort convenience symlink. Never raises — a missing/stale
symlink is harmless (callers also check the real filename directly),
but data/models/ is often root-owned from a prior Docker run, which
makes unlink/symlink_to fail with PermissionError for other users."""
try:
if symlink_path.exists() or symlink_path.is_symlink():
symlink_path.unlink()
symlink_path.symlink_to(target_name)
print(f"Symlink created: {symlink_path} -> {target_name}")
except OSError as e:
print(f"(skipping symlink: {e})")
def download_with_progress(url: str, dest_path: Path):
"""Download file with progress indicator"""
print(f"Downloading to: {dest_path}")
@@ -88,12 +102,7 @@ def main():
print(f"\nModel already exists at: {dest_path}")
print("To re-download, delete the file first.")
# Create symlink for easy access
symlink_path = models_dir / 'sam_model.pth'
if symlink_path.exists() or symlink_path.is_symlink():
symlink_path.unlink()
symlink_path.symlink_to(dest_path.name)
print(f"Symlink created: {symlink_path} -> {dest_path.name}")
create_symlink(models_dir / 'sam_model.pth', dest_path.name)
return
print(f"\nDownloading SAM {model_type.upper()} ({model_info['size']})...")
@@ -103,17 +112,13 @@ def main():
try:
download_with_progress(model_info['url'], dest_path)
# Create symlink for easy access
symlink_path = models_dir / 'sam_model.pth'
if symlink_path.exists() or symlink_path.is_symlink():
symlink_path.unlink()
symlink_path.symlink_to(dest_path.name)
create_symlink(symlink_path, dest_path.name)
print()
print("=" * 60)
print("SUCCESS!")
print(f"Model saved to: {dest_path}")
print(f"Symlink: {symlink_path}")
print("=" * 60)
except Exception as e: