mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
fix: add proactive DB writability check before init_db writes
sqlite3.connect() opens read-only files without error — the failure only surfaces on the first write (INSERT). Add an upfront os.access() check on both the directory and file, with a clear error showing the owner and the exact chown command to fix it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -62,11 +62,49 @@ def get_db():
|
||||
raise
|
||||
|
||||
|
||||
def _check_db_writable(db_path: Path) -> None:
|
||||
"""Verify the database file and directory are writable, raising a clear
|
||||
error with fix instructions if they are not."""
|
||||
import os
|
||||
|
||||
# Check directory writability (needed for SQLite journal/WAL files)
|
||||
db_dir = db_path.parent
|
||||
if db_dir.exists() and not os.access(db_dir, os.W_OK):
|
||||
owner = _file_owner(db_dir)
|
||||
msg = (
|
||||
f"Database directory {db_dir} is not writable (owned by {owner}). "
|
||||
f"Fix with: sudo chown -R $(whoami) {db_dir}"
|
||||
)
|
||||
logger.error(msg)
|
||||
raise sqlite3.OperationalError(msg)
|
||||
|
||||
# Check file writability if it already exists
|
||||
if db_path.exists() and not os.access(db_path, os.W_OK):
|
||||
owner = _file_owner(db_path)
|
||||
msg = (
|
||||
f"Database {db_path} is not writable (owned by {owner}). "
|
||||
f"Fix with: sudo chown -R $(whoami) {db_dir}"
|
||||
)
|
||||
logger.error(msg)
|
||||
raise sqlite3.OperationalError(msg)
|
||||
|
||||
|
||||
def _file_owner(path: Path) -> str:
|
||||
"""Return the owner username of a file, or UID if lookup fails."""
|
||||
try:
|
||||
import pwd
|
||||
return pwd.getpwuid(path.stat().st_uid).pw_name
|
||||
except (ImportError, KeyError):
|
||||
return str(path.stat().st_uid)
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
"""Initialize the database schema."""
|
||||
db_path = get_db_path()
|
||||
logger.info(f"Initializing database at {db_path}")
|
||||
|
||||
_check_db_writable(db_path)
|
||||
|
||||
with get_db() as conn:
|
||||
# Settings table for key-value storage
|
||||
conn.execute('''
|
||||
|
||||
Reference in New Issue
Block a user