const axios = require('axios'); const https = require('https'); const config = require('./config'); const { getContainerInfo } = require('./docker'); // Store pour les statuts des apps const appStatuses = new Map(); // Store pour les logs de déploiement const deploymentLogs = []; const MAX_DEPLOYMENT_LOGS = 50; // Store pour les commits Gitea const giteaCommits = new Map(); // Agent HTTPS qui ignore les certificats auto-signés const httpsAgent = new https.Agent({ rejectUnauthorized: false }); // Au démarrage : marquer tous les déploiements "running" orphelins comme "failed" // (ils ont été interrompus lors du dernier redémarrage du Dashboard) function cleanupOrphanedDeployments() { const orphans = deploymentLogs.filter((l) => l.status === 'running'); if (orphans.length > 0) { console.log(`[healthcheck] Nettoyage de ${orphans.length} déploiement(s) orphelin(s) au démarrage`); orphans.forEach((l) => { l.status = 'failed'; l.message = 'Déploiement interrompu (redémarrage du Dashboard)'; l.endedAt = new Date().toISOString(); }); } } /** * Vérifier la santé d'une URL */ async function checkUrl(url) { try { const start = Date.now(); const response = await axios.get(url, { timeout: 10000, httpsAgent, validateStatus: (status) => status < 500, }); const responseTime = Date.now() - start; return { online: true, statusCode: response.status, responseTime, }; } catch (err) { return { online: false, statusCode: null, responseTime: null, error: err.message, }; } } /** * Vérifier la santé d'une application */ async function checkApp(appConfig) { const result = { id: appConfig.id, name: appConfig.name, description: appConfig.description, urls: appConfig.urls, containerName: appConfig.containerName, lastCheck: new Date().toISOString(), status: 'unknown', container: null, health: { recette: null, prod: null, }, }; // Vérifier le conteneur Docker const containerInfo = await getContainerInfo(appConfig.containerName); result.container = containerInfo; // Health check recette if (appConfig.urls.recette) { result.health.recette = await checkUrl(appConfig.urls.recette); } // Health check prod if (appConfig.urls.prod) { result.health.prod = await checkUrl(appConfig.urls.prod); } // Déterminer le statut global if (!containerInfo || !containerInfo.running) { result.status = 'offline'; } else if (result.health.recette && result.health.recette.online) { result.status = 'online'; } else if (containerInfo.running) { result.status = 'error'; } else { result.status = 'offline'; } // Stocker le résultat appStatuses.set(appConfig.id, result); return result; } /** * Lancer les health checks pour toutes les apps */ async function checkAllApps() { const results = []; for (const app of config.apps) { const result = await checkApp(app); results.push(result); } return results; } /** * Ajouter un log de déploiement (retourne l'entrée créée avec son id) */ function addDeploymentLog(appId, log) { const entry = { id: Date.now().toString(), appId, timestamp: new Date().toISOString(), ...log, }; deploymentLogs.unshift(entry); if (deploymentLogs.length > MAX_DEPLOYMENT_LOGS) { deploymentLogs.pop(); } return entry; } /** * Mettre à jour un log de déploiement existant par son id * Permet de passer de "running" à "success" ou "failed" sans créer une nouvelle entrée */ function updateDeploymentLog(entryId, updates) { const entry = deploymentLogs.find((l) => l.id === entryId); if (entry) { Object.assign(entry, updates, { updatedAt: new Date().toISOString() }); return entry; } return null; } /** * Récupérer les logs de déploiement */ function getDeploymentLogs(appId = null) { if (appId) { return deploymentLogs.filter((l) => l.appId === appId); } return deploymentLogs; } /** * Récupérer le statut d'une app */ function getAppStatus(appId) { return appStatuses.get(appId) || null; } /** * Récupérer tous les statuts */ function getAllStatuses() { return Array.from(appStatuses.values()); } module.exports = { checkUrl, checkApp, checkAllApps, addDeploymentLog, updateDeploymentLog, getDeploymentLogs, getAppStatus, getAllStatuses, cleanupOrphanedDeployments, appStatuses, giteaCommits, };