fix(cms): run publish deploy as direct child — detached spawn died under systemd
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
Root-caused with systemd-run repros: under the unit's hardening flags the
backgrounded grandchild ('cmd &' / setsid) died silently, so a CMS publish
committed+pushed but never rebuilt the site (stale content, no deploy.log,
no trace). A direct (non-detached) exec child provably survives the same
flags; the response is sent first, output goes to deploy.log, and the
callback's audit entry now reports real deploy completion (ok/error).
Closes MITHOME-72
This commit is contained in:
+9
-7
@@ -305,18 +305,20 @@ const server = http.createServer(async (req, res) => {
|
|||||||
// trigger a rebuild. Deploy only the explicitly configured environment;
|
// trigger a rebuild. Deploy only the explicitly configured environment;
|
||||||
// never default to production. Overridable for tests.
|
// never default to production. Overridable for tests.
|
||||||
if (outcome.hadChanges) {
|
if (outcome.hadChanges) {
|
||||||
// WHY setsid+nohup+stdin-null: under systemd the naive `cmd &` child died
|
// WHY direct child instead of a detached `cmd &`: under the systemd unit's
|
||||||
// together with the spawning shell (observed: the deploy never ran after a
|
// hardening (NoNewPrivileges/PrivateTmp) the backgrounded grandchild died
|
||||||
// CMS publish, leaving the site on stale content). Full detachment makes it
|
// silently (observed twice: stale site after a publish). A direct child is
|
||||||
// survive; the audit entries make the spawn observable instead of silent.
|
// not detached, runs to completion, and the callback turns the audit entry
|
||||||
|
// into a real "deploy finished/failed" signal. The HTTP response is already
|
||||||
|
// sent; deploy output goes to deploy.log so the pipes stay quiet.
|
||||||
const deployCmd = process.env.CONTENT_EDITOR_DEPLOY_CMD
|
const deployCmd = process.env.CONTENT_EDITOR_DEPLOY_CMD
|
||||||
|| `cd ../../../ && setsid nohup ./deploy.sh ${CMS_DEPLOY_ENV} > deploy.log 2>&1 < /dev/null &`;
|
|| `cd ../../../ && ./deploy.sh ${CMS_DEPLOY_ENV} > deploy.log 2>&1`;
|
||||||
writeAudit('deploy_spawned', { clientAddress, user: CMS_USER, env: CMS_DEPLOY_ENV });
|
writeAudit('deploy_spawned', { clientAddress, user: CMS_USER, env: CMS_DEPLOY_ENV });
|
||||||
exec(deployCmd, deployError => {
|
exec(deployCmd, { maxBuffer: 8 * 1024 * 1024 }, deployError => {
|
||||||
writeAudit('deploy_exec_exit', {
|
writeAudit('deploy_exec_exit', {
|
||||||
clientAddress,
|
clientAddress,
|
||||||
user: CMS_USER,
|
user: CMS_USER,
|
||||||
result: deployError ? 'error' : 'shell_exited',
|
result: deployError ? 'error' : 'ok',
|
||||||
error: deployError ? String(deployError.message).slice(0, 300) : undefined,
|
error: deployError ? String(deployError.message).slice(0, 300) : undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user