Fix asset inventory update
This commit is contained in:
+6
-2
@@ -12,8 +12,12 @@
|
|||||||
//! Get-CimInstance and emits compact JSON. One subprocess for the whole
|
//! Get-CimInstance and emits compact JSON. One subprocess for the whole
|
||||||
//! inventory is cheaper than per-field WMI queries and avoids pulling a
|
//! inventory is cheaper than per-field WMI queries and avoids pulling a
|
||||||
//! `wmi`/COM crate into the dep tree. Inventory is collected once at
|
//! `wmi`/COM crate into the dep tree. Inventory is collected once at
|
||||||
//! startup; the sysinfo loop's hash-compare suppresses re-uploads of
|
//! startup. Collection routinely outruns the first sysinfo tick (TIME_CONN
|
||||||
//! unchanged data, so this isn't repeated on every 120 s tick.
|
//! = 3 s) — `Invoke-RestMethod 'api.ipify.org' -TimeoutSec 5` alone can
|
||||||
|
//! burn that budget on hosts with blocked egress — so the sysinfo loop in
|
||||||
|
//! `hbbs_http::sync` watches for INVENTORY transitioning empty → populated
|
||||||
|
//! and forces a re-upload at that point. Subsequent ticks are suppressed
|
||||||
|
//! by the loop's `had_inventory` / `uploaded` bookkeeping.
|
||||||
//!
|
//!
|
||||||
//! Non-Windows builds return an empty JSON object — hello-agent v0 only
|
//! Non-Windows builds return an empty JSON object — hello-agent v0 only
|
||||||
//! ships on Windows, but keeping the cross-platform surface compiling
|
//! ships on Windows, but keeping the cross-platform surface compiling
|
||||||
|
|||||||
+24
-4
@@ -57,6 +57,13 @@ struct InfoUploaded {
|
|||||||
last_uploaded: Option<Instant>,
|
last_uploaded: Option<Instant>,
|
||||||
id: String,
|
id: String,
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
|
// hello-agent local patch: tracks whether the most recent successful
|
||||||
|
// sysinfo upload carried the `inventory` key. The CMDB collector
|
||||||
|
// (hello-agent's `inventory.rs`) runs on a background thread and can
|
||||||
|
// finish *after* the first sysinfo tick has already fired; without
|
||||||
|
// this flag the loop would never re-upload because `uploaded == true`
|
||||||
|
// and `username` is unchanged. Re-apply on vendor resync.
|
||||||
|
had_inventory: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InfoUploaded {
|
impl Default for InfoUploaded {
|
||||||
@@ -67,18 +74,20 @@ impl Default for InfoUploaded {
|
|||||||
last_uploaded: None,
|
last_uploaded: None,
|
||||||
id: "".to_owned(),
|
id: "".to_owned(),
|
||||||
username: None,
|
username: None,
|
||||||
|
had_inventory: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InfoUploaded {
|
impl InfoUploaded {
|
||||||
fn uploaded(url: String, id: String, username: String) -> Self {
|
fn uploaded(url: String, id: String, username: String, had_inventory: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
uploaded: true,
|
uploaded: true,
|
||||||
url,
|
url,
|
||||||
last_uploaded: None,
|
last_uploaded: None,
|
||||||
id,
|
id,
|
||||||
username: Some(username),
|
username: Some(username),
|
||||||
|
had_inventory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,9 +135,18 @@ async fn start_hbbs_sync_async() {
|
|||||||
// we may not be able to get the username before login after the next restart.
|
// we may not be able to get the username before login after the next restart.
|
||||||
let mut v = crate::get_sysinfo();
|
let mut v = crate::get_sysinfo();
|
||||||
let sys_username = v["username"].as_str().unwrap_or_default().to_string();
|
let sys_username = v["username"].as_str().unwrap_or_default().to_string();
|
||||||
|
// hello-agent local patch: the inventory collector is async
|
||||||
|
// (PowerShell + WMI + ipify, see `inventory::collect_inventory`)
|
||||||
|
// and routinely finishes after the first sysinfo tick. When
|
||||||
|
// INVENTORY transitions from empty → populated we need to
|
||||||
|
// re-upload, even though `uploaded == true` and the username
|
||||||
|
// hasn't changed. Re-apply on vendor resync.
|
||||||
|
let inventory_now_available = !config::INVENTORY.read().unwrap().is_empty();
|
||||||
// Though the username comparison is only necessary on Windows,
|
// Though the username comparison is only necessary on Windows,
|
||||||
// we still keep the comparison on other platforms for consistency.
|
// we still keep the comparison on other platforms for consistency.
|
||||||
let need_upload = (!info_uploaded.uploaded || info_uploaded.username.as_ref() != Some(&sys_username)) &&
|
let need_upload = (!info_uploaded.uploaded
|
||||||
|
|| info_uploaded.username.as_ref() != Some(&sys_username)
|
||||||
|
|| (inventory_now_available && !info_uploaded.had_inventory)) &&
|
||||||
info_uploaded.last_uploaded.map(|x| x.elapsed() >= UPLOAD_SYSINFO_TIMEOUT).unwrap_or(true);
|
info_uploaded.last_uploaded.map(|x| x.elapsed() >= UPLOAD_SYSINFO_TIMEOUT).unwrap_or(true);
|
||||||
if need_upload {
|
if need_upload {
|
||||||
v["version"] = json!(crate::VERSION);
|
v["version"] = json!(crate::VERSION);
|
||||||
@@ -158,9 +176,11 @@ async fn start_hbbs_sync_async() {
|
|||||||
// the `inventory` key, identical to a vanilla rustdesk
|
// the `inventory` key, identical to a vanilla rustdesk
|
||||||
// install.
|
// install.
|
||||||
let inventory = config::INVENTORY.read().unwrap().clone();
|
let inventory = config::INVENTORY.read().unwrap().clone();
|
||||||
|
let mut had_inventory = false;
|
||||||
if !inventory.is_empty() {
|
if !inventory.is_empty() {
|
||||||
if let Ok(inv_v) = serde_json::from_str::<Value>(&inventory) {
|
if let Ok(inv_v) = serde_json::from_str::<Value>(&inventory) {
|
||||||
v["inventory"] = inv_v;
|
v["inventory"] = inv_v;
|
||||||
|
had_inventory = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ab_name = Config::get_option(keys::OPTION_PRESET_ADDRESS_BOOK_NAME);
|
let ab_name = Config::get_option(keys::OPTION_PRESET_ADDRESS_BOOK_NAME);
|
||||||
@@ -232,7 +252,7 @@ async fn start_hbbs_sync_async() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if samever {
|
if samever {
|
||||||
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username);
|
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username, had_inventory);
|
||||||
log::info!("sysinfo not changed, skip upload");
|
log::info!("sysinfo not changed, skip upload");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -241,7 +261,7 @@ async fn start_hbbs_sync_async() {
|
|||||||
match crate::post_request(url.replace("heartbeat", "sysinfo"), v, "").await {
|
match crate::post_request(url.replace("heartbeat", "sysinfo"), v, "").await {
|
||||||
Ok(x) => {
|
Ok(x) => {
|
||||||
if x == "SYSINFO_UPDATED" {
|
if x == "SYSINFO_UPDATED" {
|
||||||
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username);
|
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username, had_inventory);
|
||||||
log::info!("sysinfo updated");
|
log::info!("sysinfo updated");
|
||||||
if !hash.is_empty() {
|
if !hash.is_empty() {
|
||||||
config::Status::set("sysinfo_hash", hash);
|
config::Status::set("sysinfo_hash", hash);
|
||||||
|
|||||||
Reference in New Issue
Block a user