Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 61 additions & 15 deletions inventory/inventory-fwupd/policy.cf
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
# Host Security Identifier (HSI) attribute scores reported by fwupd.
#
# Implementation notes:
# - Device list is read directly from /var/cache/fwupd/devices.json, which
# fwupd's own systemd timer (fwupd-refresh.timer) keeps up to date. No
# fwupdmgr call is needed for the common steady-state inventory.
# - Pending updates and HSI attributes are not cached as files by fwupd, so
# they are sourced via fwupdmgr and re-fetched only when their respective
# JSON caches age past their TTL.
# - Device list, pending updates and HSI attributes come from fwupdmgr, into
# JSON caches refreshed past their TTL. validjson() checks each payload
# before caching, so readjson() never sees a bad file.
# - fwupd's own /var/cache/fwupd/devices.json is often zero-length, so it is
# not used (ENT-14409).
# - All inventory variables are emitted via a single module-protocol cache
# rendered from JSON with an inline_mustache template. The cache is
# consumed in one call to read_module_protocol(), which loads dozens of
Expand All @@ -36,14 +35,15 @@ bundle agent inventory_fwupd_main
);

"_fwupd_dir" string => "$(sys.statedir)/fwupd";
"_devices_src" string => "/var/cache/fwupd/devices.json";
"_devices_src" string => "$(_fwupd_dir)/inventory_devices.json";
"_updates_src" string => "$(_fwupd_dir)/inventory_updates.json";
"_security_src" string => "$(_fwupd_dir)/inventory_security.json";
"_cache" string => "$(_fwupd_dir)/inventory_cache";
"_template" string => "$(this.promise_dirname)/fwupd-inventory.mustache";

# TTLs in seconds for the fwupdmgr-derived JSON caches.
# 12 h:
"_devices_ttl" string => "43200";
"_updates_ttl" string => "43200";

# 24 h:
Expand Down Expand Up @@ -80,6 +80,9 @@ bundle agent inventory_fwupd_main
"0"
);

"_devices_age"
string => eval("$(sys.systime) - $(_devices_mtime)", "math", "infix");

"_updates_age"
string => eval("$(sys.systime) - $(_updates_mtime)", "math", "infix");

Expand Down Expand Up @@ -127,6 +130,17 @@ bundle agent inventory_fwupd_main
);

linux.have_fwupdmgr::
"_devices_stale" not => fileexists("$(_devices_src)");

"_devices_stale"
expression => isgreaterthan("$(_devices_age)", "$(_devices_ttl)"),
if => fileexists("$(_devices_src)");

# Firmware updates activate on boot, so device versions change then.
"_devices_stale"
expression => islessthan("$(_devices_mtime)", "$(_boot_mtime)"),
if => fileexists("$(_devices_src)");

"_updates_stale" not => fileexists("$(_updates_src)");

"_updates_stale"
Expand Down Expand Up @@ -172,13 +186,24 @@ bundle agent inventory_fwupd_main
};

vars:
linux.have_fwupdmgr._devices_stale::
"_devices_raw"
string => execresult("$(fwupdmgr) get-devices --json", "noshell");

"_devices_payload"
string => ifelse(
validjson("$(_devices_raw)", "true"),
"$(_devices_raw)",
'{"Devices":[]}'
);

linux.have_fwupdmgr._updates_stale::
"_updates_raw"
string => execresult("$(fwupdmgr) get-updates --json", "noshell");

"_updates_payload"
string => ifelse(
regcmp("\s*\{.*", "$(_updates_raw)"),
validjson("$(_updates_raw)", "true"),
"$(_updates_raw)",
'{"Devices":[]}'
);
Expand All @@ -189,7 +214,7 @@ bundle agent inventory_fwupd_main

"_security_payload"
string => ifelse(
regcmp("\s*\{.*", "$(_security_raw)"),
validjson("$(_security_raw)", "true"),
"$(_security_raw)",
'{"SecurityAttributes":[]}'
);
Expand All @@ -198,11 +223,23 @@ bundle agent inventory_fwupd_main
linux::
"$(_fwupd_dir)/." create => "true";

# The mtime is the TTL clock. content only writes when the file differs,
# so without touch an unchanged cache stays stale and fwupdmgr runs
# again on every agent run.
linux.have_fwupdmgr._devices_stale::
"$(_devices_src)"
content => "$(_devices_payload)",
touch => "true";

linux.have_fwupdmgr._updates_stale::
"$(_updates_src)" content => "$(_updates_payload)";
"$(_updates_src)"
content => "$(_updates_payload)",
touch => "true";

linux.have_fwupdmgr._security_stale::
"$(_security_src)" content => "$(_security_payload)";
"$(_security_src)"
content => "$(_security_payload)",
touch => "true";

methods:
linux._have_devices._rebuild_cache::
Expand Down Expand Up @@ -241,12 +278,13 @@ bundle agent inventory_fwupd_main
linux._have_devices::
"_cache_was_read" if => read_module_protocol("$(_cache)");

linux.!_have_devices::
# No source file from fwupd - emit a single status attribute.
linux.!have_fwupdmgr::
# vars run before classes, so guarding the variable on !have_fwupdmgr
# directly would set it on pass 1, before that class is evaluated.
"_emit_missing_status";

vars:
linux.!_have_devices._emit_missing_status::
linux._emit_missing_status::
"fwupd_status"
string => "FWUPD_MISSING",
meta => { "inventory", "attribute_name=Firmware update status" };
Expand All @@ -268,7 +306,11 @@ bundle agent inventory_fwupd_render(devices_src, updates_src, security_src, temp
vars:
"_template_body" string => readfile("$(template)", "inf");
"_devices_json" data => readjson("$(devices_src)");
"_dev_count" int => length("_devices_json[Devices]");

# fwupdmgr emits {} when it tracks no devices.
"_dev_count"
int => length("_devices_json[Devices]"),
if => isvariable("_devices_json[Devices]");

"_updates_json"
data => readjson("$(updates_src)"),
Expand All @@ -283,6 +325,10 @@ bundle agent inventory_fwupd_render(devices_src, updates_src, security_src, temp
if => fileexists("$(security_src)");

# Default counters when fwupdmgr-derived data is not present.
"_dev_count"
int => "0",
if => not(isvariable("_dev_count"));

"_updates_count"
int => "0",
if => not(isvariable("_updates_count"));
Expand Down
Loading