172 lines
5.8 KiB
PHP
172 lines
5.8 KiB
PHP
<?php
|
|
// WEVIA autowire trigger endpoint - doctrine 147 + 148 (presets)
|
|
// Whitelist + generic preset dispatcher
|
|
header('Content-Type: application/json');
|
|
|
|
$whitelist = [
|
|
'wire-mr-paperclip' => '/opt/wevia-brain/scripts/wire-mr-paperclip.sh',
|
|
'wire-wtp-live-ops' => '/opt/wevia-brain/scripts/wire-wtp-live-ops.sh',
|
|
'wevia-playwright-test' => '/opt/wevia-brain/scripts/wevia-playwright-test.sh',
|
|
];
|
|
|
|
// Presets dir (doctrine 148)
|
|
$presets_dir = '/opt/wevia-brain/presets';
|
|
$preset_runner = '/opt/wevia-brain/scripts/apply-preset.sh';
|
|
|
|
$action = $_GET['action'] ?? $_POST['action'] ?? '';
|
|
$action = preg_replace('/[^a-z0-9\-]/i','',$action);
|
|
|
|
// LIST available (for introspection)
|
|
if ($action === 'list') {
|
|
$presets_available = [];
|
|
if (is_dir($presets_dir)) {
|
|
foreach (glob("$presets_dir/*.json") as $p) {
|
|
$presets_available[] = basename($p, '.json');
|
|
}
|
|
}
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'whitelist_actions' => array_keys($whitelist),
|
|
'presets_available' => $presets_available,
|
|
'presets_dir' => $presets_dir,
|
|
], JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
// APPLY PRESET (doctrine 148)
|
|
if ($action === 'apply-preset') {
|
|
$preset = $_GET['preset'] ?? $_POST['preset'] ?? '';
|
|
$preset = preg_replace('/[^a-z0-9\-]/i','',$preset);
|
|
if (!$preset) {
|
|
echo json_encode(['ok' => false, 'err' => 'preset_required']);
|
|
exit;
|
|
}
|
|
$preset_file = "$presets_dir/$preset.json";
|
|
if (!is_file($preset_file)) {
|
|
$available = array_map(fn($p) => basename($p, '.json'), glob("$presets_dir/*.json"));
|
|
echo json_encode(['ok' => false, 'err' => 'preset_not_found', 'preset' => $preset, 'available' => $available]);
|
|
exit;
|
|
}
|
|
$log_id = bin2hex(random_bytes(6));
|
|
$start = microtime(true);
|
|
$cmd = "timeout 30 sudo bash $preset_runner " . escapeshellarg($preset) . " 2>&1";
|
|
$output = @shell_exec($cmd);
|
|
$duration_ms = round((microtime(true) - $start) * 1000);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
// Parfois output contient des lignes debug puis JSON final
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
@file_put_contents('/tmp/wevia-autowire-trigger.log',
|
|
date('c') . " apply-preset=$preset log_id=$log_id duration={$duration_ms}ms ok=" . ($parsed['ok'] ?? '?') . "
|
|
", FILE_APPEND);
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'action' => 'apply-preset',
|
|
'preset' => $preset,
|
|
'log_id' => $log_id,
|
|
'duration_ms' => $duration_ms,
|
|
'raw_output' => trim((string)$output),
|
|
'result' => $parsed,
|
|
], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// ROLLBACK (doctrine 153)
|
|
if ($action === 'rollback') {
|
|
$marker = $_GET['marker'] ?? $_POST['marker'] ?? '';
|
|
$target = $_GET['target'] ?? $_POST['target'] ?? '';
|
|
$marker = preg_replace('/[^a-zA-Z0-9\-_]/','', $marker);
|
|
if ($target && !str_starts_with($target, '/var/www/html/')) {
|
|
echo json_encode(['ok'=>false,'err'=>'target_outside_whitelist']); exit;
|
|
}
|
|
if (!$marker && !$target) {
|
|
echo json_encode(['ok'=>false,'err'=>'marker_or_target_required']); exit;
|
|
}
|
|
$env = [];
|
|
if ($marker) $env[] = 'MARKER=' . escapeshellarg($marker);
|
|
if ($target) $env[] = 'TARGET=' . escapeshellarg($target);
|
|
$cmd = 'timeout 30 sudo env ' . implode(' ', $env) . ' bash /opt/wevia-brain/scripts/wevia-rollback.sh 2>&1';
|
|
$output = @shell_exec($cmd);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
echo json_encode(['ok'=>true,'action'=>'rollback','marker'=>$marker,'target'=>$target,'raw_output'=>trim((string)$output),'result'=>$parsed], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// LIST GOLD backups (doctrine 153)
|
|
if ($action === 'list-gold') {
|
|
$golds = [];
|
|
foreach (glob('/var/www/html/*.html.GOLD-*') as $g) {
|
|
$basename = basename($g);
|
|
if (preg_match('/^(.+?)\.html\.GOLD-([0-9\-]+)-pre-(.+)$/', $basename, $m)) {
|
|
$golds[] = [
|
|
'file' => $basename,
|
|
'page' => $m[1] . '.html',
|
|
'timestamp' => $m[2],
|
|
'marker_slug' => $m[3],
|
|
'size_bytes' => filesize($g),
|
|
];
|
|
}
|
|
}
|
|
usort($golds, fn($a,$b) => strcmp($b['timestamp'], $a['timestamp']));
|
|
echo json_encode(['ok'=>true,'count'=>count($golds),'golds'=>$golds], JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
// Classic whitelist action
|
|
if (!$action || !isset($whitelist[$action])) {
|
|
echo json_encode([
|
|
'ok' => false,
|
|
'err' => 'unknown_action',
|
|
'available_actions' => array_keys($whitelist),
|
|
'presets_endpoint' => '?action=list',
|
|
'hint' => 'GET ?action=<action> OR ?action=apply-preset&preset=<preset>'
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$script = $whitelist[$action];
|
|
if (!is_file($script) || !is_executable($script)) {
|
|
echo json_encode(['ok'=>false,'err'=>'script_not_executable','path'=>$script]);
|
|
exit;
|
|
}
|
|
|
|
$log_id = bin2hex(random_bytes(6));
|
|
$start = microtime(true);
|
|
$output = @shell_exec("timeout 150 sudo bash $script 2>&1");
|
|
$duration_ms = round((microtime(true) - $start) * 1000);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
@file_put_contents('/tmp/wevia-autowire-trigger.log',
|
|
date('c') . " action=$action log_id=$log_id duration={$duration_ms}ms ok=" . ($parsed['ok'] ?? '?') . "
|
|
", FILE_APPEND);
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'action' => $action,
|
|
'script' => $script,
|
|
'log_id' => $log_id,
|
|
'duration_ms' => $duration_ms,
|
|
'raw_output' => trim((string)$output),
|
|
'result' => $parsed,
|
|
], JSON_UNESCAPED_SLASHES);
|