_RSYNC_ENABLED enabled=0|1 // // RESPONSE // {"ok":true,"error":null,"push":[{"host","ok","ready","error"}, …]} // {"ok":false,"error":"POST only"|"Invalid flag name"|"Failed to write master.conf", // "push":[]} // // DEPENDS ON // include/scheduler.php vv_conf_flag_set() → vv_write_conf_raw() // include/config.php vv_push_master_conf(), vv_push_setup_state() // ═══════════════════════════════════════════════════════════════════════════════════════════════ header('Content-Type: application/json'); require_once dirname(__DIR__) . '/include/scheduler.php'; if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['ok' => false, 'error' => 'POST only']); exit; } $name = trim($_POST['name'] ?? ''); $enabled = ($_POST['enabled'] ?? '0') === '1'; // The tier prefix is optional. RSYNC_ENABLED itself is the global gate the page also renders, // and requiring a prefix silently rejected it — the toggle reverted to off with no way to turn // syncing on from the UI at all. Masked until now because every POST to this endpoint was // being swallowed by the multipart bug. if (!$name || !preg_match('/^([A-Z][A-Z_]*_)?RSYNC_ENABLED$/', $name)) { echo json_encode(['ok' => false, 'error' => 'Invalid flag name']); exit; } $ok = vv_conf_flag_set($name, $enabled); // master.conf is shared — propagate the change to partner hosts (no-op on non-owner). $push = []; if ($ok) { $push = vv_push_master_conf(); vv_push_setup_state(); } echo json_encode(['ok' => $ok, 'error' => $ok ? null : 'Failed to write master.conf', 'push' => $push]);