This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new e45f7a8  Validate configuration paths as absolute or relative
e45f7a8 is described below

commit e45f7a8b587b7bb604d8e02edd27f1d2809c1730
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon May 5 19:54:33 2025 +0100

    Validate configuration paths as absolute or relative
---
 alembic.ini        |  1 +
 atr/config.py      | 25 ++++++++++++++++++++++---
 atr/db/__init__.py |  4 +++-
 atr/tasks/bulk.py  |  6 +++++-
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/alembic.ini b/alembic.ini
index 257e5f1..02dadc7 100644
--- a/alembic.ini
+++ b/alembic.ini
@@ -63,6 +63,7 @@ version_path_separator = os
 # are written from script.py.mako
 # output_encoding = utf-8
 
+# Despite the three slashes, this is a relative path
 sqlalchemy.url = sqlite:///state/atr.db
 
 
diff --git a/atr/config.py b/atr/config.py
index 56b361b..bdc0084 100644
--- a/atr/config.py
+++ b/atr/config.py
@@ -30,13 +30,13 @@ class AppConfig:
     SSH_HOST = decouple.config("SSH_HOST", default="0.0.0.0")
     SSH_PORT = decouple.config("SSH_PORT", default=2222, cast=int)
     PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    STATE_DIR = os.path.join(PROJECT_ROOT, "state")
+    STATE_DIR = decouple.config("STATE_DIR", 
default=os.path.join(PROJECT_ROOT, "state"))
     DEBUG = False
     TEMPLATES_AUTO_RELOAD = False
     USE_BLOCKBUSTER = False
     FINISHED_STORAGE_DIR = os.path.join(STATE_DIR, "finished")
     UNFINISHED_STORAGE_DIR = os.path.join(STATE_DIR, "unfinished")
-    SQLITE_DB_PATH = decouple.config("SQLITE_DB_PATH", default="/atr.db")
+    SQLITE_DB_PATH = decouple.config("SQLITE_DB_PATH", default="atr.db")
 
     # Apache RAT configuration
     APACHE_RAT_JAR_PATH = decouple.config("APACHE_RAT_JAR_PATH", 
default="/opt/tools/apache-rat-0.16.1.jar")
@@ -94,10 +94,29 @@ _CONFIG_DICT: Final = {
 
 def get() -> type[AppConfig]:
     try:
-        return _CONFIG_DICT[get_mode()]
+        config = _CONFIG_DICT[get_mode()]
     except KeyError:
         exit("Error: Invalid <mode>. Expected values [Debug, Production, 
Profiling].")
 
+    absolute_paths = [
+        (config.PROJECT_ROOT, "PROJECT_ROOT"),
+        (config.STATE_DIR, "STATE_DIR"),
+        (config.FINISHED_STORAGE_DIR, "FINISHED_STORAGE_DIR"),
+        (config.UNFINISHED_STORAGE_DIR, "UNFINISHED_STORAGE_DIR"),
+    ]
+    relative_paths = [
+        (config.SQLITE_DB_PATH, "SQLITE_DB_PATH"),
+    ]
+
+    for path, name in absolute_paths:
+        if not path.startswith("/"):
+            raise RuntimeError(f"{name} must be an absolute path")
+    for path, name in relative_paths:
+        if path.startswith("/"):
+            raise RuntimeError(f"{name} must be a relative path")
+
+    return config
+
 
 def get_mode() -> Mode:
     global _global_mode
diff --git a/atr/db/__init__.py b/atr/db/__init__.py
index 5f8e4aa..01eea06 100644
--- a/atr/db/__init__.py
+++ b/atr/db/__init__.py
@@ -481,7 +481,9 @@ class Session(sqlalchemy.ext.asyncio.AsyncSession):
 
 
 async def create_async_engine(app_config: type[config.AppConfig]) -> 
sqlalchemy.ext.asyncio.AsyncEngine:
-    sqlite_url = f"sqlite+aiosqlite://{app_config.SQLITE_DB_PATH}"
+    absolute_db_path = os.path.join(app_config.STATE_DIR, 
app_config.SQLITE_DB_PATH)
+    # Three slashes are required before either a relative or absolute path
+    sqlite_url = f"sqlite+aiosqlite:///{absolute_db_path}"
     # Use aiosqlite for async SQLite access
     engine = sqlalchemy.ext.asyncio.create_async_engine(
         sqlite_url,
diff --git a/atr/tasks/bulk.py b/atr/tasks/bulk.py
index 2903a5f..1fb3b4d 100644
--- a/atr/tasks/bulk.py
+++ b/atr/tasks/bulk.py
@@ -31,6 +31,7 @@ import sqlalchemy.ext.asyncio
 
 import atr.db.models as models
 import atr.tasks.task as task
+from atr import config
 
 # Configure detailed logging
 _LOGGER: Final = logging.getLogger(__name__)
@@ -587,7 +588,10 @@ async def get_db_session() -> 
sqlalchemy.ext.asyncio.AsyncSession:
     try:
         # Create connection only if it doesn't exist already
         if global_db_connection is None:
-            db_url = "sqlite+aiosqlite:///atr.db"
+            conf = config.get()
+            absolute_db_path = os.path.join(conf.STATE_DIR, 
conf.SQLITE_DB_PATH)
+            # Three slashes are required before either a relative or absolute 
path
+            db_url = f"sqlite+aiosqlite://{absolute_db_path}"
             _LOGGER.debug(f"Creating database engine: {db_url}")
 
             engine = sqlalchemy.ext.asyncio.create_async_engine(db_url)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to