Actualiser script_creator.py

This commit is contained in:
administrateur 2025-03-29 13:59:43 +01:00
parent 57ed76e50f
commit b277abe8dc

View File

@ -3,33 +3,84 @@ import os
import subprocess
import base64
import requests
from redlock import Redlock
from threading import Thread, Lock
import time
app = Flask(__name__)
# Configuration MinIO depuis les variables d'environnement
# Variables d'environnement
MINIO_BUCKET = os.getenv("MINIO_BUCKET", "nextcloud")
MINIO_HOST = os.getenv("MINIO_HOST", "minio.minio.svc.cluster.local:9000")
MINIO_REGION = os.getenv("MINIO_REGION", "us-east-1")
S3_ACCESS_KEY = os.getenv("S3_ACCESS_KEY")
S3_SECRET_KEY = os.getenv("S3_SECRET_KEY")
MINIO_MOUNT_PATH = "/mnt"
N8N_WEBHOOK_URL = os.getenv("N8N_WEBHOOK_URL", "https://n8n.n8n.svc.kube.ia86.cc/webhook/7950310f-e526-475a-82d1-63818da79339")
DEBUG = bool(os.getenv("DEBUG", False))
DEBUG = bool(os.getenv("DEBUG"))
S3_ACCESS_KEY = os.getenv("S3_ACCESS_KEY")
S3_SECRET_KEY = os.getenv("S3_SECRET_KEY")
if not S3_ACCESS_KEY or not S3_SECRET_KEY:
raise ValueError("❌ ERREUR: S3_ACCESS_KEY ou S3_SECRET_KEY manquantes")
def log_debug(message):
redis_host = os.getenv("REDIS_HOST", "redis.redis.svc.cluster.local")
redis_port = int(os.getenv("REDIS_PORT", 6379))
dlm = Redlock([{"host": redis_host, "port": redis_port, "db": 0}])
S3_UNMOUNT_CHECK_INTERVAL = int(os.getenv("S3_UNMOUNT_CHECK_INTERVAL", 300)) # 5 minutes par défaut
lock_prefix = "lock:mkdocs:"
local_lock = Lock()
def log_debug(msg):
if DEBUG:
print(f"🔍 DEBUG: {message}")
print(f"🔍 DEBUG: {msg}")
def mount_s3():
if not os.path.ismount(MINIO_MOUNT_PATH):
os.makedirs(MINIO_MOUNT_PATH, exist_ok=True)
credentials_file = "/etc/passwd-s3fs"
with open(credentials_file, "w") as f:
f.write(f"{S3_ACCESS_KEY}:{S3_SECRET_KEY}\n")
os.chmod(credentials_file, 0o600)
cmd = f"s3fs {MINIO_BUCKET} {MINIO_MOUNT_PATH} -o passwd_file={credentials_file} -o url=https://{MINIO_HOST} -o use_path_request_style -o allow_other"
subprocess.run(cmd, shell=True, capture_output=True, text=True)
with local_lock:
if not os.path.ismount(MINIO_MOUNT_PATH):
os.makedirs(MINIO_MOUNT_PATH, exist_ok=True)
credentials_file = "/etc/passwd-s3fs"
with open(credentials_file, "w") as f:
f.write(f"{S3_ACCESS_KEY}:{S3_SECRET_KEY}\n")
os.chmod(credentials_file, 0o600)
cmd = (
f"s3fs {MINIO_BUCKET} {MINIO_MOUNT_PATH} "
f"-o passwd_file={credentials_file} "
f"-o url=https://{MINIO_HOST} "
"-o use_path_request_style "
"-o allow_other"
)
log_debug(f"🚀 Montage S3: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
log_debug(f"❌ Erreur montage: {result.stderr}")
raise RuntimeError(f"Erreur montage: {result.stderr}")
log_debug("✅ Montage réussi.")
else:
log_debug("✅ Montage S3 déjà actif.")
def unmount_s3():
with local_lock:
if os.path.ismount(MINIO_MOUNT_PATH):
cmd = f"fusermount -u {MINIO_MOUNT_PATH}"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
log_debug("✅ Démontage S3 réussi.")
else:
log_debug(f"⚠️ Échec démontage S3: {result.stderr}")
def unmount_checker():
while True:
time.sleep(S3_UNMOUNT_CHECK_INTERVAL)
log_debug("⏰ Vérification périodique pour démontage S3...")
# Vérification si aucun build actif
active_locks = dlm.redis_clients[0].keys(f"{lock_prefix}*")
if not active_locks:
log_debug("🟢 Aucun build actif, démontage S3...")
unmount_s3()
else:
log_debug("🔴 Builds en cours détectés, S3 reste monté.")
@app.route("/build", methods=["POST"])
def build_mkdocs():
@ -38,53 +89,44 @@ def build_mkdocs():
error_callback = data.get("ERROR_CALLBACK", N8N_WEBHOOK_URL)
if not website:
log_debug("❌ Paramètre WEBSITE manquant.")
return jsonify({"error": "Paramètre WEBSITE manquant"}), 400
return jsonify({"error": "WEBSITE manquant"}), 400
lock_file = f"/tmp/build_{website}.lock"
if os.path.exists(lock_file):
log_debug(f"⚠️ Un build est déjà en cours pour {website}.")
return jsonify({
"status": "busy",
"message": f"Un build est déjà en cours pour {website}."
}), 429
# Création du verrou
open(lock_file, 'w').close()
log_debug(f"🔐 Verrou activé pour {website}.")
lock_key = f"{lock_prefix}{website}"
lock = dlm.lock(lock_key, 60000)
if not lock:
log_debug(f"⚠️ Build déjà actif: {website}")
return jsonify({"status": "busy", "message": f"Build déjà actif: {website}"}), 429
try:
mount_s3()
src = f"/mnt/files/sites/@{website}/mkdocs.yml"
src = f"{MINIO_MOUNT_PATH}/files/sites/@{website}/mkdocs.yml"
tmp = f"/srv/{website}"
if not os.path.exists(src):
log_debug(f"Le fichier de configuration {src} n'existe pas.")
log_debug(f"Config introuvable: {src}")
return jsonify({"error": f"{src} introuvable"}), 404
cmd = f"mkdocs build --quiet --no-strict --config-file {src} --site-dir {tmp}"
log_debug(f"🚀 Exécution: {cmd}")
log_debug(f"🚀 Build MkDocs: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
build_error = base64.b64encode(result.stderr.encode()).decode()
json_payload = {"site": tmp, "erreur": build_error}
json_payload = {"site": website, "erreur": build_error}
log_debug(f"❌ Échec build: {result.stderr}")
requests.post(error_callback, json=json_payload, headers={"Content-Type": "application/json"})
log_debug(f"❌ Échec du build {website}: {result.stderr}")
return jsonify({"status": "error", "message": "Build échoué", "error": result.stderr}), 500
log_debug(f"✅ Build réussi pour {website}.")
log_debug(f"✅ Build réussi: {website}")
return jsonify({"status": "success", "message": "Build réussi"}), 200
finally:
if os.path.exists(lock_file):
os.remove(lock_file)
log_debug(f"🔓 Verrou supprimé pour {website}.")
dlm.unlock(lock)
log_debug(f"🔓 Verrou libéré: {website}")
if __name__ == "__main__":
log_debug("🚀 Serveur Flask démarré.")
log_debug("🚀 Flask démarré (0.0.0.0:80)")
checker_thread = Thread(target=unmount_checker, daemon=True)
checker_thread.start()
app.run(host="0.0.0.0", port=80)