From: Willy Tarreau Date: Mon, 6 Jul 2026 17:30:15 +0000 (+0200) Subject: DEV: patchbot: tolerate polluted save responses and show server warnings X-Git-Url: http://git.kaiwu.me/web//%22?a=commitdiff_plain;h=09814345d53698587d55a590e5b6d0077530f9e7;p=haproxy.git DEV: patchbot: tolerate polluted save responses and show server warnings Some server setups leak the CGI's stderr into the response body (e.g. inetd-style servers where fd 2 is the client socket): since stderr is unbuffered and stdout is buffered, a git error message then lands *before* the "OK " line, and the applied-count check failed with a cryptic "server applied only ? of N changes" although everything had been applied. Scan the whole response for the lines of interest (the "OK " count, the "conflict" and "warning" lines) instead of assuming they come first, dump the raw response to the console when no count is found at all to ease diagnosis, and display the server's warning lines (such as the new "git commit failed" one) next to the save status so that a recording problem is visible from the page instead of being buried in a server log. --- diff --git a/dev/patchbot/scripts/post-ai.sh b/dev/patchbot/scripts/post-ai.sh index 8f9d8590c..8d53753fb 100755 --- a/dev/patchbot/scripts/post-ai.sh +++ b/dev/patchbot/scripts/post-ai.sh @@ -537,8 +537,11 @@ function save_ref() { .then(function(t) { var confl = {}; var resp = t.split("\n"); - var i, j, ok, nbc = 0; + var i, j, ok = null, warn = "", nbc = 0; + // The lines of interest may be surrounded by unrelated output (some + // servers leak the CGI's stderr into the response), so scan for them + // anywhere: the count ("OK ..."), the conflicts and the warnings. for (j = 0; j < resp.length; j++) { if (resp[j].indexOf("conflict ") == 0) { i = find_line(resp[j].slice(9).trim()); @@ -547,21 +550,25 @@ function save_ref() { nbc++; } } + else if (!ok) + ok = resp[j].match(/^OK (\d+) /); + if (resp[j].indexOf("warning: ") == 0) + warn = "; " + resp[j]; } - // The server states how many directives it applied ("OK ..."): - // anything neither applied nor reported as a conflict was silently - // ignored (e.g. an outdated update.bin not knowing a directive). In - // that case believe the server, not ourselves: advance nothing, keep - // every edit local for a retry, and say what happened. - ok = resp[0] ? resp[0].match(/^OK (\d+) /) : null; + // The server states how many directives it applied: anything neither + // applied nor reported as a conflict was silently ignored (e.g. an + // outdated update.bin not knowing a directive). In that case believe + // the server, not ourselves: advance nothing, keep every edit local + // for a retry, and say what happened. if (!ok || parseInt(ok[1], 10) != nsent - nbc) { for (i = 1; i < nb_patches; i++) { if (confl[i]) mark_conflict(i, 1); } + console.log("unexpected update.cgi response: " + t); sync_msg("server applied only " + (ok ? ok[1] : "?") + " of " + nsent + - " changes (outdated update.cgi/update.bin?), edits kept"); + " changes (outdated update.cgi/update.bin?), edits kept" + warn); return; } @@ -588,7 +595,7 @@ function save_ref() { } } } - sync_msg(nbc ? "saved, but " + nbc + " note conflict(s): use Get updates and revise the red one(s)" : "saved"); + sync_msg((nbc ? "saved, but " + nbc + " note conflict(s): use Get updates and revise the red one(s)" : "saved") + warn); updt_save_btn(); }) .catch(function() { sync_msg("save failed (busy?), edits kept"); });