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-releases.git
The following commit(s) were added to refs/heads/main by this push:
new ce15cbe Add a migration to use an audit state subdirectory
ce15cbe is described below
commit ce15cbea99409281de3ed7b8cc6a9a7174c76283
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Jan 15 19:30:02 2026 +0000
Add a migration to use an audit state subdirectory
---
atr/config.py | 2 +-
atr/server.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/atr/config.py b/atr/config.py
index b2427e8..1bd905d 100644
--- a/atr/config.py
+++ b/atr/config.py
@@ -74,7 +74,7 @@ class AppConfig:
SVN_STORAGE_DIR = os.path.join(STATE_DIR, "svn")
ATTESTABLE_STORAGE_DIR = os.path.join(STATE_DIR, "attestable")
SQLITE_DB_PATH = decouple.config("SQLITE_DB_PATH", default="atr.db")
- STORAGE_AUDIT_LOG_FILE = os.path.join(STATE_DIR, "storage-audit.log")
+ STORAGE_AUDIT_LOG_FILE = os.path.join(STATE_DIR, "audit",
"storage-audit.log")
PERFORMANCE_LOG_FILE = os.path.join(STATE_DIR, "route-performance.log")
# Apache RAT configuration
diff --git a/atr/server.py b/atr/server.py
index 71fe523..7880643 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -20,7 +20,9 @@
import asyncio
import contextlib
import datetime
+import fcntl
import os
+import pathlib
import queue
import urllib.parse
from collections.abc import Iterable
@@ -110,6 +112,7 @@ def _app_dirs_setup(app_config: type[config.AppConfig]) ->
None:
print(f"Working directory changed to: {os.getcwd()}")
directories_to_ensure = [
+ pathlib.Path(app_config.STATE_DIR) / "audit",
util.get_downloads_dir(),
util.get_finished_dir(),
util.get_tmp_dir(),
@@ -391,6 +394,7 @@ def _create_app(app_config: type[config.AppConfig]) ->
base.QuartApp:
if os.sep != "/":
raise RuntimeError('ATR requires a POSIX compatible filesystem where
os.sep is "/"')
config_mode = config.get_mode()
+ _migrate_state_directory(app_config)
_app_dirs_setup(app_config)
log.performance_init()
app = _app_create_base(app_config)
@@ -479,6 +483,48 @@ async def _metadata_update_scheduler() -> None:
await asyncio.sleep(86400)
+def _migrate_audit(state_dir: pathlib.Path) -> None:
+ _migrate_file(
+ state_dir / "storage-audit.log",
+ state_dir / "audit" / "storage-audit.log",
+ )
+
+
+def _migrate_directory(old_path: pathlib.Path, new_path: pathlib.Path) -> None:
+ if old_path.exists() and (not new_path.exists()):
+ old_path.rename(new_path)
+ print(f"Migrated directory: {old_path} -> {new_path}")
+ elif old_path.exists() and new_path.exists():
+ raise RuntimeError(f"Migration conflict: both {old_path} and
{new_path} exist")
+ else:
+ print(f"No directory migration needed: {old_path}")
+
+
+def _migrate_file(old_path: pathlib.Path, new_path: pathlib.Path) -> None:
+ if old_path.exists() and (not new_path.exists()):
+ new_path.parent.mkdir(parents=True, exist_ok=True)
+ old_path.rename(new_path)
+ print(f"Migrated file: {old_path} -> {new_path}")
+ elif old_path.exists() and new_path.exists():
+ raise RuntimeError(f"Migration conflict: both {old_path} and
{new_path} exist")
+ else:
+ print(f"No file migration needed: {old_path}")
+
+
+def _migrate_state_directory(app_config: type[config.AppConfig]) -> None:
+ state_dir = pathlib.Path(app_config.STATE_DIR)
+ runtime_dir = state_dir / "runtime"
+ runtime_dir.mkdir(parents=True, exist_ok=True)
+ lock_path = runtime_dir / "migration.lock"
+
+ with open(lock_path, "w") as lock_file:
+ fcntl.flock(lock_file, fcntl.LOCK_EX)
+ try:
+ _migrate_audit(state_dir)
+ finally:
+ fcntl.flock(lock_file, fcntl.LOCK_UN)
+
+
def _register_routes(app: base.QuartApp) -> None:
# Add a global error handler to show helpful error messages with tracebacks
@app.errorhandler(Exception)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]