Fix stdout/stderr ordering in ShutdownPrepCheck #112
@@ -87,16 +87,24 @@ pub async fn check() -> Result<ShutdownPrepCheckReply> {
|
|||||||
if !script.exists() {
|
if !script.exists() {
|
||||||
bail!("shutdown-prep script not found at {}", script.display());
|
bail!("shutdown-prep script not found at {}", script.display());
|
||||||
}
|
}
|
||||||
|
// `2>&1` inside the shell merges stderr into stdout *before*
|
||||||
|
// either stream is piped back to us, preserving true
|
||||||
|
// chronological order. Capturing stdout/stderr separately (as
|
||||||
|
// `Command::output()` does by default) and concatenating them
|
||||||
|
// after the fact loses interleaving entirely — every stderr line
|
||||||
|
// lands at the very end regardless of when it was actually
|
||||||
|
// printed, which makes a mid-script warning (e.g. "replicate not
|
||||||
|
// configured on this node") look like a failure that happened
|
||||||
|
// after "DRY RUN COMPLETE".
|
||||||
let run = Command::new("bash")
|
let run = Command::new("bash")
|
||||||
.arg(&script)
|
.arg("-c")
|
||||||
.arg("--dry-run")
|
.arg(format!("{} --dry-run 2>&1", script.display()))
|
||||||
.output();
|
.output();
|
||||||
let output = timeout(CHECK_TIMEOUT, run)
|
let output = timeout(CHECK_TIMEOUT, run)
|
||||||
.await
|
.await
|
||||||
.context("shutdown-prep --dry-run timed out")?
|
.context("shutdown-prep --dry-run timed out")?
|
||||||
.context("spawning shutdown-prep --dry-run")?;
|
.context("spawning shutdown-prep --dry-run")?;
|
||||||
let mut combined = String::from_utf8_lossy(&output.stdout).into_owned();
|
let combined = String::from_utf8_lossy(&output.stdout).into_owned();
|
||||||
combined.push_str(&String::from_utf8_lossy(&output.stderr));
|
|
||||||
Ok(ShutdownPrepCheckReply {
|
Ok(ShutdownPrepCheckReply {
|
||||||
ready: output.status.success(),
|
ready: output.status.success(),
|
||||||
output: combined,
|
output: combined,
|
||||||
|
|||||||
Reference in New Issue
Block a user