From 7fb47ffde880f803220d24b34889642e28ce7c0d Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sat, 23 May 2026 14:10:53 +0200 Subject: [PATCH] fix(smart v0.1.17): smart_status optionnel + AmbientCapabilities CAP_SYS_ADMIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SmartJson.smart_status devient Option avec #[serde(default)] → parsing non-bloquant si le champ est absent (ex: NVME_IOCTL_ADMIN_CMD échoue) - Service: suppression NoNewPrivileges, ajout AmbientCapabilities=CAP_SYS_ADMIN → smartctl hérite la capability via execve (kernel ≥ 5.2) - Nettoyage logs debug (suppression dump JSON brut) Co-Authored-By: Claude Sonnet 4.6 --- agent/Cargo.lock | 2 +- agent/Cargo.toml | 2 +- agent/src/metrics/smart.rs | 11 +++-------- deploy/nanometrics-agent.service | 7 ++++++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/agent/Cargo.lock b/agent/Cargo.lock index d0a9735..752aefa 100644 --- a/agent/Cargo.lock +++ b/agent/Cargo.lock @@ -248,7 +248,7 @@ dependencies = [ [[package]] name = "nanometrics-agent" -version = "0.1.16" +version = "0.1.17" dependencies = [ "libc", "rumqttc", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index c67585f..ce6aef4 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nanometrics-agent" -version = "0.1.16" +version = "0.1.17" edition = "2021" [lib] diff --git a/agent/src/metrics/smart.rs b/agent/src/metrics/smart.rs index e5ba145..af51fd4 100644 --- a/agent/src/metrics/smart.rs +++ b/agent/src/metrics/smart.rs @@ -2,7 +2,8 @@ use serde::Deserialize; #[derive(Deserialize)] struct SmartJson { - smart_status: SmartStatus, + #[serde(default)] + smart_status: Option, temperature: Option, ata_smart_attributes: Option, nvme_smart_health_information_log: Option, @@ -78,7 +79,7 @@ pub fn parse_json(json: &str) -> Result Option> { Ok(o) => o, Err(e) => { eprintln!("[smart] erreur exec smartctl {}: {}", dev, e); continue } }; - eprintln!("[smart] smartctl {} → exit={}, stdout={} octets, stderr={} octets", - dev, output.status, output.stdout.len(), output.stderr.len()); let json = String::from_utf8_lossy(&output.stdout); match parse_json(&json) { Ok(metrics) => { - eprintln!("[smart] {} parsé OK (passed={})", dev, metrics.passed); results.push(crate::payload::SmartMetrics { device: dev.trim_start_matches("/dev/").to_string(), ..metrics @@ -138,9 +136,6 @@ pub fn collect() -> Option> { } Err(e) => { eprintln!("[smart] {} parse JSON échoué: {}", dev, e); - eprintln!("[smart] --- JSON BRUT BEGIN ({} octets) ---", json.len()); - eprintln!("{}", &*json); - eprintln!("[smart] --- JSON BRUT END ---"); } } } diff --git a/deploy/nanometrics-agent.service b/deploy/nanometrics-agent.service index f5f47da..246071e 100644 --- a/deploy/nanometrics-agent.service +++ b/deploy/nanometrics-agent.service @@ -17,7 +17,12 @@ ConfigurationDirectoryMode=0755 ProtectSystem=strict ProtectHome=read-only PrivateTmp=yes -NoNewPrivileges=yes +# CAP_SYS_ADMIN est requis par le noyau pour NVME_IOCTL_ADMIN_CMD (lecture SMART NVMe). +# NoNewPrivileges est retiré car il efface les ambient capabilities sur exec (noyau ≥ 5.2), +# ce qui empêcherait smartctl enfant d'hériter la capability. +# CapabilityBoundingSet borne à la seule cap nécessaire. +CapabilityBoundingSet=CAP_SYS_ADMIN +AmbientCapabilities=CAP_SYS_ADMIN RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX