date('c'), 'doctrine' => 'NO-DORMANT-CAPABILITIES']; // 1. OSS clones /opt $oss = []; $opt_dirs = array_filter(explode("\n", trim(@shell_exec('ls -d /opt/*/ 2>/dev/null')))); foreach ($opt_dirs as $d) { if (!is_dir($d . '.git')) continue; $remote = trim(@shell_exec("cd " . escapeshellarg($d) . " && git remote -v 2>/dev/null | grep -oE 'github\\.com[:/][a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+' | head -1")); if (!$remote) continue; $size = trim(@shell_exec("du -sh " . escapeshellarg($d) . " 2>/dev/null | cut -f1")); $ts = (int)trim(@shell_exec("cd " . escapeshellarg($d) . " && git log -1 --format=%ct 2>/dev/null")); $age = $ts ? intval((time() - $ts) / 86400) : 999; $oss[] = ['path' => $d, 'remote' => $remote, 'size' => $size, 'age_days' => $age, 'dormant' => $age > 60]; } $out['oss_total'] = count($oss); $out['oss_dormant'] = count(array_filter($oss, fn($o) => $o['dormant'])); $out['oss_samples'] = array_slice($oss, 0, 40); // 2. Gitea repos $gitea = []; $gitea_raw = @shell_exec('curl -sk "http://127.0.0.1:3300/api/v1/repos/search?limit=50" 2>/dev/null'); if ($gitea_raw) { $g = json_decode($gitea_raw, true); $now = time(); foreach (($g['data'] ?? []) as $r) { $updated = strtotime($r['updated_at'] ?? ''); $age = $updated ? intval(($now - $updated) / 86400) : 999; $gitea[] = [ 'full_name' => $r['full_name'] ?? '?', 'size_kb' => $r['size'] ?? 0, 'updated' => substr($r['updated_at'] ?? '?', 0, 10), 'age_days' => $age, 'dormant' => $age > 60, ]; } } $out['gitea_total'] = count($gitea); $out['gitea_dormant'] = count(array_filter($gitea, fn($r) => $r['dormant'])); $out['gitea_samples'] = array_slice($gitea, 0, 50); // 3. GitHub repos (yace222) $github = []; $secrets = @file_get_contents('/etc/weval/secrets.env'); $pat = ''; $pat = "getenv("GITHUB_PAT") ?: "REDACTED""; if (!$pat) $pat = 'getenv("GITHUB_PAT") ?: "REDACTED"'; // fallback connu $gh_raw = @shell_exec("curl -sk -H \"Authorization: token " . $pat . "\" -H \"Accept: application/vnd.github+json\" \"https://api.github.com/user/repos?per_page=50&sort=updated&type=all\" 2>/dev/null"); if ($gh_raw) { $gh = json_decode($gh_raw, true); $now = time(); if (is_array($gh)) { foreach ($gh as $r) { $updated = strtotime($r['updated_at'] ?? ''); $age = $updated ? intval(($now - $updated) / 86400) : 999; $github[] = [ 'name' => $r['name'] ?? '?', 'updated' => substr($r['updated_at'] ?? '?', 0, 10), 'age_days' => $age, 'private' => $r['private'] ?? false, 'size_kb' => $r['size'] ?? 0, 'dormant' => $age > 60, ]; } } } $out['github_total'] = count($github); $out['github_dormant'] = count(array_filter($github, fn($r) => $r['dormant'])); $out['github_samples'] = $github; // 4. Services inactive (légitimes exclus) $svc_raw = @shell_exec("systemctl list-units --state=inactive --type=service --no-legend --no-pager 2>/dev/null"); $svc_lines = array_filter(explode("\n", trim($svc_raw))); $svc_dormant = []; foreach ($svc_lines as $line) { if (preg_match('/^[●\s]*(\S+\.service)\s+(loaded|not-found)\s+inactive/', $line, $m)) { $name = $m[1]; if (preg_match('/^(apt-|cloud-init|snap\.|acpid|apport|certbot|console-|connman|auditd|e2scrub|nftables|ssh-|ua-|fwupd|hostname|fail2ban|sys-|systemd-|dev-|dbus-|user-runtime-|motd-|multipathd|polkit|rsyslog|setvtrgb|getty|plymouth|rc-local|wpa|bluetooth|cups|packagekit|networkd|modprobe|blk-|chronyd-|iscsi|multi-user|networking|finalrd|user@|crowdsec-|display-|dm-|dmesg|dpkg-|ebtables|emergency|fcoe|firewalld|fstrim|grub-|hc-net|hv_|initrd-|ip6tables|ipset|iptables|kbd|ldconfig|logrotate|lvm2-|lxc|man-db|netfilter|nfs-|open-vm|plymouth-|quota|rescue|runlevel|screen-cleanup|serial-|setup|smartmontools|swap|thin-|ufw|unattended|userstat|x11-common|sudo|fstrim|halt|reboot|shutdown)/', $name)) continue; $svc_dormant[] = $name; } } $out['services_dormant'] = $svc_dormant; // 5. Docker stopped $docker_stopped_raw = @shell_exec("docker ps -a --filter status=exited --format '{{.Names}}' 2>/dev/null"); $out['docker_stopped'] = array_filter(explode("\n", trim($docker_stopped_raw))); // 6. Totals $out['opt_total_size'] = trim(@shell_exec("du -sh /opt 2>/dev/null | cut -f1")); $out['disk_usage'] = trim(@shell_exec("df -h / | tail -1 | awk '{print \$5}'")); // 7. Grand total dormants $out['dormant_grand_total'] = $out['oss_dormant'] + $out['gitea_dormant'] + $out['github_dormant'] + count($svc_dormant) + count($out['docker_stopped']); echo json_encode($out, JSON_PRETTY_PRINT);