Updated feature / fix
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# YakPanel - Environment
|
# YakPanel - Environment (this file lives next to app/ — loaded from backend/ always, not shell CWD)
|
||||||
SECRET_KEY=change-this-in-production
|
SECRET_KEY=change-this-in-production
|
||||||
# Resolved against backend directory (see app/core/database.py), safe when CWD is not backend/
|
# Resolved to backend/data/default.db (see app/core/database.py)
|
||||||
DATABASE_URL=sqlite+aiosqlite:///./data/default.db
|
DATABASE_URL=sqlite+aiosqlite:///./data/default.db
|
||||||
REDIS_URL=redis://localhost:6379/0
|
REDIS_URL=redis://localhost:6379/0
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
"""YakPanel - Configuration"""
|
"""YakPanel - Configuration"""
|
||||||
import os
|
import os
|
||||||
from typing import Any
|
|
||||||
from pydantic_settings import BaseSettings
|
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
# Runtime config loaded from DB on startup (overrides Settings)
|
# Runtime config loaded from DB on startup (overrides Settings)
|
||||||
_runtime_config: dict[str, Any] = {}
|
_runtime_config: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_BACKEND_ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
"""Application settings"""
|
"""Application settings"""
|
||||||
|
|
||||||
|
model_config = SettingsConfigDict(
|
||||||
|
env_file=str(_BACKEND_ROOT / ".env"),
|
||||||
|
env_file_encoding="utf-8",
|
||||||
|
extra="ignore",
|
||||||
|
)
|
||||||
|
|
||||||
app_name: str = "YakPanel"
|
app_name: str = "YakPanel"
|
||||||
app_version: str = "1.0.0"
|
app_version: str = "1.0.0"
|
||||||
debug: bool = False
|
debug: bool = False
|
||||||
@@ -47,10 +58,6 @@ class Settings(BaseSettings):
|
|||||||
# Comma-separated CIDRs; empty = no restriction (e.g. "10.0.0.0/8,192.168.0.0/16")
|
# Comma-separated CIDRs; empty = no restriction (e.g. "10.0.0.0/8,192.168.0.0/16")
|
||||||
remote_install_allowed_target_cidrs: str = ""
|
remote_install_allowed_target_cidrs: str = ""
|
||||||
|
|
||||||
class Config:
|
|
||||||
env_file = ".env"
|
|
||||||
env_file_encoding = "utf-8"
|
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
@lru_cache
|
||||||
def get_settings() -> Settings:
|
def get_settings() -> Settings:
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
"""YakPanel - Database configuration"""
|
"""YakPanel - Database configuration"""
|
||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from sqlalchemy.engine.url import make_url
|
from sqlalchemy.engine.url import make_url
|
||||||
@@ -22,10 +24,28 @@ def _resolve_database_url(raw_url: str) -> str:
|
|||||||
path = (backend_dir / path).resolve()
|
path = (backend_dir / path).resolve()
|
||||||
else:
|
else:
|
||||||
path = path.resolve()
|
path = path.resolve()
|
||||||
path.parent.mkdir(parents=True, exist_ok=True)
|
data_dir = path.parent
|
||||||
# POSIX path for SQLite URL (backslashes break aiosqlite on unexpected setups)
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
posix = path.as_posix()
|
try:
|
||||||
return str(url.set(database=posix))
|
os.chmod(data_dir, 0o755)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
if not os.access(data_dir, os.W_OK):
|
||||||
|
raise RuntimeError(
|
||||||
|
f"SQLite directory not writable: {data_dir} "
|
||||||
|
f"(fix ownership or permissions; check SELinux if enabled)."
|
||||||
|
)
|
||||||
|
abs_path = path.as_posix()
|
||||||
|
try:
|
||||||
|
test = sqlite3.connect(abs_path)
|
||||||
|
test.close()
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"SQLite refused to open {abs_path} (from DATABASE_URL). {e}. "
|
||||||
|
f"Parent dir: {data_dir} writable={os.access(data_dir, os.W_OK)}."
|
||||||
|
) from e
|
||||||
|
# Unix absolute file: sqlite+aiosqlite:////abs/path (four slashes total after the colon)
|
||||||
|
return f"sqlite+aiosqlite:///{abs_path}"
|
||||||
|
|
||||||
|
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
|
|||||||
Reference in New Issue
Block a user