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
|
||||
//! inventory is cheaper than per-field WMI queries and avoids pulling a
|
||||
//! `wmi`/COM crate into the dep tree. Inventory is collected once at
|
||||
//! startup; the sysinfo loop's hash-compare suppresses re-uploads of
|
||||
//! unchanged data, so this isn't repeated on every 120 s tick.
|
||||
//! startup. Collection routinely outruns the first sysinfo tick (TIME_CONN
|
||||
//! = 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
|
||||
//! ships on Windows, but keeping the cross-platform surface compiling
|
||||
|
||||
+24
-4
@@ -57,6 +57,13 @@ struct InfoUploaded {
|
||||
last_uploaded: Option<Instant>,
|
||||
id: 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 {
|
||||
@@ -67,18 +74,20 @@ impl Default for InfoUploaded {
|
||||
last_uploaded: None,
|
||||
id: "".to_owned(),
|
||||
username: None,
|
||||
had_inventory: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InfoUploaded {
|
||||
fn uploaded(url: String, id: String, username: String) -> Self {
|
||||
fn uploaded(url: String, id: String, username: String, had_inventory: bool) -> Self {
|
||||
Self {
|
||||
uploaded: true,
|
||||
url,
|
||||
last_uploaded: None,
|
||||
id,
|
||||
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.
|
||||
let mut v = crate::get_sysinfo();
|
||||
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,
|
||||
// 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);
|
||||
if need_upload {
|
||||
v["version"] = json!(crate::VERSION);
|
||||
@@ -158,9 +176,11 @@ async fn start_hbbs_sync_async() {
|
||||
// the `inventory` key, identical to a vanilla rustdesk
|
||||
// install.
|
||||
let inventory = config::INVENTORY.read().unwrap().clone();
|
||||
let mut had_inventory = false;
|
||||
if !inventory.is_empty() {
|
||||
if let Ok(inv_v) = serde_json::from_str::<Value>(&inventory) {
|
||||
v["inventory"] = inv_v;
|
||||
had_inventory = true;
|
||||
}
|
||||
}
|
||||
let ab_name = Config::get_option(keys::OPTION_PRESET_ADDRESS_BOOK_NAME);
|
||||
@@ -232,7 +252,7 @@ async fn start_hbbs_sync_async() {
|
||||
}
|
||||
};
|
||||
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");
|
||||
continue;
|
||||
}
|
||||
@@ -241,7 +261,7 @@ async fn start_hbbs_sync_async() {
|
||||
match crate::post_request(url.replace("heartbeat", "sysinfo"), v, "").await {
|
||||
Ok(x) => {
|
||||
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");
|
||||
if !hash.is_empty() {
|
||||
config::Status::set("sysinfo_hash", hash);
|
||||
|
||||
Reference in New Issue
Block a user