diff --git a/app/main.py b/app/main.py index 6d75d7f..1fbfe03 100644 --- a/app/main.py +++ b/app/main.py @@ -12,6 +12,7 @@ from fastapi import FastAPI DB_FILE = Path("/opt/appfactory/data/appfactory/appfactory.db") TOOLS_DIR = Path("/tools") +MAINTENANCE_DIR = Path("/opt/appfactory/workspace/appfactory-tools/maintenance") WORKER_ID = os.getenv("APPFACTORY_WORKER_ID", socket.gethostname()) POLL_SECONDS = int(os.getenv("APPFACTORY_WORKER_POLL_SECONDS", "3")) @@ -153,7 +154,7 @@ def acquire_lock(job: dict) -> bool: ) """, ( - job["target_type"], + job.get("target_type") or job["type"], job["target_id"], job["id"], WORKER_ID, @@ -181,7 +182,7 @@ def release_lock(job: dict): AND job_id = ? """, ( - job["target_type"], + job.get("target_type") or job["type"], job["target_id"], job["id"], ), @@ -203,7 +204,7 @@ def extend_lock(job: dict): AND job_id = ? """, ( - job["target_type"], + job.get("target_type") or job["type"], job["target_id"], job["id"], ), @@ -360,6 +361,29 @@ def command_for_job(job: dict): if job_type == "deploy_core_service": return [str(TOOLS_DIR / "deploy-core-service.sh"), target_id] + if job_type == "run_script": + payload = json.loads(job.get("payload_json") or "{}") + script_name = payload.get("script_name") or target_id + + if not script_name: + raise ValueError("Missing script_name") + + if "/" in script_name or "\\" in script_name or ".." in script_name: + raise ValueError("Invalid script name") + + if not script_name.endswith(".sh"): + raise ValueError("Script must end with .sh") + + script_path = MAINTENANCE_DIR / script_name + + if not script_path.exists(): + raise ValueError(f"Script not found: {script_name}") + + if not script_path.is_file(): + raise ValueError(f"Script is not a file: {script_name}") + + return [str(script_path)] + raise ValueError(f"Unsupported job type: {job_type}")