Harden DetMir runtime hot paths

This commit is contained in:
igor04091968
2026-07-01 06:06:01 +03:00
parent fe87c85a31
commit c017cb08a9
15 changed files with 1923 additions and 86 deletions
+1
View File
@@ -9,3 +9,4 @@ publish.workspace = true
[dependencies]
anyhow.workspace = true
clap.workspace = true
serde_json.workspace = true
+87 -3
View File
@@ -1,5 +1,6 @@
use std::io::{self, Write};
use std::process::Command;
use std::process::{Command, Stdio};
use std::time::{Duration, Instant};
use anyhow::{Context, Result};
use clap::Parser;
@@ -19,8 +20,14 @@ struct Cli {
#[arg(long, default_value_t = 10)]
connect_timeout_seconds: u64,
#[arg(long, default_value_t = 90)]
timeout_seconds: u64,
#[arg(long, default_value = DEFAULT_REMOTE_COMMAND)]
remote_command: String,
#[arg(long, default_value_t = true)]
enabled: bool,
}
impl Cli {
@@ -31,6 +38,8 @@ impl Cli {
);
self.remote_command = env_first(&["DETMIR_DLP_REMOTE_COMMAND"], &self.remote_command);
self.ssh_bin = env_first(&["DETMIR_SSH_BIN"], &self.ssh_bin);
self.timeout_seconds = env_u64("DETMIR_DLP_TIMEOUT_SECONDS", self.timeout_seconds);
self.enabled = env_bool("DETMIR_DLP_ENABLED", self.enabled);
self
}
}
@@ -42,6 +51,25 @@ fn env_first(names: &[&str], fallback: &str) -> String {
.unwrap_or_else(|| fallback.to_string())
}
fn env_u64(name: &str, fallback: u64) -> u64 {
std::env::var(name)
.ok()
.and_then(|value| value.parse().ok())
.unwrap_or(fallback)
}
fn env_bool(name: &str, fallback: bool) -> bool {
std::env::var(name)
.ok()
.map(|value| {
matches!(
value.trim().to_ascii_lowercase().as_str(),
"1" | "true" | "yes" | "on"
)
})
.unwrap_or(fallback)
}
fn ssh_args(cli: &Cli) -> Vec<String> {
vec![
"-o".to_string(),
@@ -56,22 +84,76 @@ fn ssh_args(cli: &Cli) -> Vec<String> {
}
fn run(cli: Cli) -> Result<i32> {
if !cli.enabled {
println!(
"{}",
serde_json::to_string_pretty(&serde_json::json!({
"ok": true,
"counts": {"ok": 1, "warn": 0, "fail": 0},
"results": [{
"name": "dlp:mode",
"status": "ok",
"summary": "DLP health check disabled by DETMIR_DLP_ENABLED=false",
"details": {
"mode": "disabled",
"load_reduction": ["aw-dlp health ssh probe skipped"]
}
}]
}))?
);
return Ok(0);
}
let args = ssh_args(&cli);
let output = Command::new(&cli.ssh_bin)
let mut child = Command::new(&cli.ssh_bin)
.args(&args)
.output()
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.with_context(|| format!("failed to execute {}", cli.ssh_bin))?;
let started = Instant::now();
let mut timed_out = false;
loop {
if child.try_wait()?.is_some() {
break;
}
if started.elapsed() >= Duration::from_secs(cli.timeout_seconds) {
timed_out = true;
terminate_child(&mut child);
break;
}
std::thread::sleep(Duration::from_millis(100));
}
let output = child
.wait_with_output()
.context("failed to collect SSH output")?;
io::stdout()
.write_all(&output.stdout)
.context("failed to write DLP stdout")?;
io::stderr()
.write_all(&output.stderr)
.context("failed to write DLP stderr")?;
if timed_out {
writeln!(
io::stderr(),
"detmir-dlp timed out after {} seconds",
cli.timeout_seconds
)
.context("failed to write timeout message")?;
return Ok(124);
}
Ok(output.status.code().unwrap_or(1))
}
fn terminate_child(child: &mut std::process::Child) {
let _ = child.kill();
std::thread::sleep(Duration::from_secs(2));
let _ = child.kill();
}
fn main() -> Result<()> {
let cli = Cli::parse().apply_env();
let code = run(cli)?;
@@ -88,7 +170,9 @@ mod tests {
ssh_bin: "ssh".to_string(),
ssh_target: DEFAULT_SSH_TARGET.to_string(),
connect_timeout_seconds: 10,
timeout_seconds: 90,
remote_command: DEFAULT_REMOTE_COMMAND.to_string(),
enabled: true,
};
assert_eq!(
ssh_args(&cli),