fix: always clean up temp archive on failure and fix justfile data dir path

- Wrap download/verify/extract in try/finally so .download-*.tmp is
  always deleted, even on mid-download or extraction failures
- Fix justfile build-server-cuda to use sh.voicebox.app (production path)
This commit is contained in:
Jamie Pine
2026-03-17 09:15:23 -07:00
parent 7bd72ea9f7
commit 81864e831a
2 changed files with 50 additions and 46 deletions
+49 -45
View File
@@ -167,60 +167,64 @@ async def _download_and_extract_archive(
except Exception as e: except Exception as e:
raise RuntimeError(f"{label}: failed to fetch checksum from {sha256_url}") from e raise RuntimeError(f"{label}: failed to fetch checksum from {sha256_url}") from e
# Stream download # Stream download, verify, and extract — always clean up temp file
downloaded = 0 downloaded = 0
async with client.stream("GET", url) as response: try:
response.raise_for_status() async with client.stream("GET", url) as response:
with open(temp_path, "wb") as f: response.raise_for_status()
async for chunk in response.aiter_bytes(chunk_size=1024 * 1024): with open(temp_path, "wb") as f:
f.write(chunk) async for chunk in response.aiter_bytes(chunk_size=1024 * 1024):
downloaded += len(chunk) f.write(chunk)
progress.update_progress( downloaded += len(chunk)
PROGRESS_KEY, progress.update_progress(
current=progress_offset + downloaded, PROGRESS_KEY,
total=total_size, current=progress_offset + downloaded,
filename=f"Downloading {label}", total=total_size,
status="downloading", filename=f"Downloading {label}",
) status="downloading",
)
# Verify integrity # Verify integrity
if expected_sha: if expected_sha:
progress.update_progress(
PROGRESS_KEY,
current=progress_offset + downloaded,
total=total_size,
filename=f"Verifying {label}...",
status="downloading",
)
sha256 = hashlib.sha256()
with open(temp_path, "rb") as f:
while True:
data = f.read(1024 * 1024)
if not data:
break
sha256.update(data)
actual = sha256.hexdigest()
if actual != expected_sha:
raise ValueError(
f"{label} integrity check failed: expected {expected_sha[:16]}..., got {actual[:16]}..."
)
logger.info(f"{label}: integrity verified")
# Extract (use data filter for path traversal protection on Python 3.12+)
progress.update_progress( progress.update_progress(
PROGRESS_KEY, PROGRESS_KEY,
current=progress_offset + downloaded, current=progress_offset + downloaded,
total=total_size, total=total_size,
filename=f"Verifying {label}...", filename=f"Extracting {label}...",
status="downloading", status="downloading",
) )
sha256 = hashlib.sha256() with tarfile.open(temp_path, "r:gz") as tar:
with open(temp_path, "rb") as f: if sys.version_info >= (3, 12):
while True: tar.extractall(path=dest_dir, filter="data")
data = f.read(1024 * 1024) else:
if not data: tar.extractall(path=dest_dir)
break
sha256.update(data) logger.info(f"{label}: extracted to {dest_dir}")
actual = sha256.hexdigest() finally:
if actual != expected_sha: if temp_path.exists():
temp_path.unlink() temp_path.unlink()
raise ValueError(f"{label} integrity check failed: expected {expected_sha[:16]}..., got {actual[:16]}...")
logger.info(f"{label}: integrity verified")
# Extract (use data filter for path traversal protection on Python 3.12+)
progress.update_progress(
PROGRESS_KEY,
current=progress_offset + downloaded,
total=total_size,
filename=f"Extracting {label}...",
status="downloading",
)
with tarfile.open(temp_path, "r:gz") as tar:
if sys.version_info >= (3, 12):
tar.extractall(path=dest_dir, filter="data")
else:
tar.extractall(path=dest_dir)
temp_path.unlink()
logger.info(f"{label}: extracted to {dest_dir}")
return downloaded return downloaded
+1 -1
View File
@@ -208,7 +208,7 @@ build-server-cuda: _ensure-venv
$env:PATH = "{{ venv_bin }};$env:PATH"; \ $env:PATH = "{{ venv_bin }};$env:PATH"; \
& "{{ python }}" backend/build_binary.py --cuda; \ & "{{ python }}" backend/build_binary.py --cuda; \
if ($LASTEXITCODE -ne 0) { throw "build_binary.py --cuda failed with exit code $LASTEXITCODE" }; \ if ($LASTEXITCODE -ne 0) { throw "build_binary.py --cuda failed with exit code $LASTEXITCODE" }; \
$dest = "$env:APPDATA/com.voicebox.app/backends/cuda"; \ $dest = "$env:APPDATA/sh.voicebox.app/backends/cuda"; \
if (Test-Path $dest) { Remove-Item -Recurse -Force $dest }; \ if (Test-Path $dest) { Remove-Item -Recurse -Force $dest }; \
New-Item -ItemType Directory -Path $dest -Force | Out-Null; \ New-Item -ItemType Directory -Path $dest -Force | Out-Null; \
Copy-Item "backend/dist/voicebox-server-cuda/*" $dest -Recurse -Force; \ Copy-Item "backend/dist/voicebox-server-cuda/*" $dest -Recurse -Force; \