enh: rework json/prom output to better split x86/arm

This commit is contained in:
Stéphane Lesimple
2026-04-08 22:27:30 +02:00
parent ff42393fa6
commit 98ec067aef
2 changed files with 113 additions and 81 deletions

View File

@@ -116,9 +116,9 @@ The entire tool is a single bash script with no external script dependencies. Ke
Two JSON formats are available via `--batch`:
- **`--batch json`** (comprehensive): A top-level object with five sections:
- `meta` — script version, format version, timestamp, run mode flags (`run_as_root`, `reduced_accuracy`, `mocked`, `paranoid`, `sysfs_only`, `no_hw`, `extra`)
- `meta` — script version, format version, timestamp, run mode flags (`run_as_root`, `reduced_accuracy`, `mocked`, `paranoid`, `sysfs_only`, `extra`)
- `system` — kernel release/version/arch/cmdline, CPU count, SMT status, hypervisor host detection
- `cpu`vendor, model name, family/model/stepping, CPUID, codename, ARM fields (`arm_part_list`, `arm_arch_list`), plus a `capabilities` sub-object containing all `cap_*` hardware flags as booleans/nulls/strings
- `cpu``arch` discriminator (`x86` or `arm`), vendor, friendly name, then an arch-specific sub-object (`cpu.x86` or `cpu.arm`) with identification fields (family/model/stepping/CPUID/codename for x86; part\_list/arch\_list for ARM) and a `capabilities` sub-object containing hardware flags as booleans/nulls
- `cpu_microcode``installed_version`, `latest_version`, `microcode_up_to_date`, `is_blacklisted`, firmware DB source/info
- `vulnerabilities` — array of per-CVE objects: `cve`, `name`, `aliases`, `cpu_affected`, `status`, `vulnerable`, `info`, `sysfs_status`, `sysfs_message`

View File

@@ -68,7 +68,9 @@ _json_bool() {
_build_json_meta() {
local timestamp mode
timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || echo "unknown")
if [ "$opt_no_hw" = 1 ]; then
if [ "$opt_hw_only" = 1 ]; then
mode="hw-only"
elif [ "$opt_no_hw" = 1 ]; then
mode="no-hw"
elif [ "$opt_runtime" = 0 ]; then
mode="no-runtime"
@@ -81,7 +83,7 @@ _build_json_meta() {
else
run_as_root='false'
fi
g_json_meta=$(printf '{"script_version":%s,"format_version":1,"timestamp":%s,"os":%s,"mode":"%s","run_as_root":%s,"reduced_accuracy":%s,"paranoid":%s,"sysfs_only":%s,"no_hw":%s,"extra":%s}' \
g_json_meta=$(printf '{"script_version":%s,"format_version":1,"timestamp":%s,"os":%s,"mode":"%s","run_as_root":%s,"reduced_accuracy":%s,"paranoid":%s,"sysfs_only":%s,"extra":%s}' \
"$(_json_str "$VERSION")" \
"$(_json_str "$timestamp")" \
"$(_json_str "$g_os")" \
@@ -90,7 +92,6 @@ _build_json_meta() {
"$(_json_bool "${g_bad_accuracy:-0}")" \
"$(_json_bool "$opt_paranoid")" \
"$(_json_bool "$opt_sysfs_only")" \
"$(_json_bool "$opt_no_hw")" \
"$(_json_bool "$opt_extra")")
}
@@ -134,22 +135,22 @@ _build_json_system() {
# Sets: g_json_cpu
# shellcheck disable=SC2034
_build_json_cpu() {
local cpuid_hex ucode_hex codename caps
local cpuid_hex codename caps arch_sub arch_type
if [ -n "${cpu_cpuid:-}" ]; then
cpuid_hex=$(printf '0x%08x' "$cpu_cpuid")
else
cpuid_hex=''
fi
if [ -n "${cpu_ucode:-}" ]; then
ucode_hex=$(printf '0x%x' "$cpu_ucode")
else
ucode_hex=''
fi
codename=''
if is_intel; then
codename=$(get_intel_codename 2>/dev/null || true)
fi
# Build capabilities sub-object
# Determine architecture type and build the arch-specific sub-object
case "${cpu_vendor:-}" in
GenuineIntel | AuthenticAMD | HygonGenuine)
arch_type='x86'
# Build x86 capabilities sub-object
caps=$(printf '{"spec_ctrl":%s,"ibrs":%s,"ibpb":%s,"ibpb_ret":%s,"stibp":%s,"ssbd":%s,"l1d_flush":%s,"md_clear":%s,"arch_capabilities":%s,"rdcl_no":%s,"ibrs_all":%s,"rsba":%s,"l1dflush_no":%s,"ssb_no":%s,"mds_no":%s,"taa_no":%s,"pschange_msc_no":%s,"tsx_ctrl_msr":%s,"tsx_ctrl_rtm_disable":%s,"tsx_ctrl_cpuid_clear":%s,"gds_ctrl":%s,"gds_no":%s,"gds_mitg_dis":%s,"gds_mitg_lock":%s,"rfds_no":%s,"rfds_clear":%s,"its_no":%s,"sbdr_ssdp_no":%s,"fbsdp_no":%s,"psdp_no":%s,"fb_clear":%s,"rtm":%s,"tsx_force_abort":%s,"tsx_force_abort_rtm_disable":%s,"tsx_force_abort_cpuid_clear":%s,"sgx":%s,"srbds":%s,"srbds_on":%s,"amd_ssb_no":%s,"hygon_ssb_no":%s,"ipred":%s,"rrsba":%s,"bhi":%s,"tsa_sq_no":%s,"tsa_l1_no":%s,"verw_clear":%s,"autoibrs":%s,"sbpb":%s,"avx2":%s,"avx512":%s}' \
"$(_json_cap "${cap_spec_ctrl:-}")" \
"$(_json_cap "${cap_ibrs:-}")" \
@@ -201,10 +202,7 @@ _build_json_cpu() {
"$(_json_cap "${cap_sbpb:-}")" \
"$(_json_cap "${cap_avx2:-}")" \
"$(_json_cap "${cap_avx512:-}")")
g_json_cpu=$(printf '{"vendor":%s,"friendly_name":%s,"family":%s,"model":%s,"stepping":%s,"cpuid":%s,"platform_id":%s,"hybrid":%s,"codename":%s,"arm_part_list":%s,"arm_arch_list":%s,"capabilities":%s}' \
"$(_json_str "${cpu_vendor:-}")" \
"$(_json_str "${cpu_friendly_name:-}")" \
arch_sub=$(printf '{"family":%s,"model":%s,"stepping":%s,"cpuid":%s,"platform_id":%s,"hybrid":%s,"codename":%s,"capabilities":%s}' \
"$(_json_num "${cpu_family:-}")" \
"$(_json_num "${cpu_model:-}")" \
"$(_json_num "${cpu_stepping:-}")" \
@@ -212,9 +210,32 @@ _build_json_cpu() {
"$(_json_num "${cpu_platformid:-}")" \
"$(_json_bool "${cpu_hybrid:-}")" \
"$(_json_str "$codename")" \
"$(_json_str "${cpu_part_list:-}")" \
"$(_json_str "${cpu_arch_list:-}")" \
"$caps")
;;
ARM | CAVIUM | PHYTIUM)
arch_type='arm'
arch_sub=$(printf '{"part_list":%s,"arch_list":%s,"capabilities":{}}' \
"$(_json_str "${cpu_part_list:-}")" \
"$(_json_str "${cpu_arch_list:-}")")
;;
*)
arch_type=''
arch_sub=''
;;
esac
if [ -n "$arch_type" ]; then
g_json_cpu=$(printf '{"arch":"%s","vendor":%s,"friendly_name":%s,"%s":%s}' \
"$arch_type" \
"$(_json_str "${cpu_vendor:-}")" \
"$(_json_str "${cpu_friendly_name:-}")" \
"$arch_type" \
"$arch_sub")
else
g_json_cpu=$(printf '{"arch":null,"vendor":%s,"friendly_name":%s}' \
"$(_json_str "${cpu_vendor:-}")" \
"$(_json_str "${cpu_friendly_name:-}")")
fi
}
# Build the "cpu_microcode" section of the comprehensive JSON output
@@ -443,11 +464,22 @@ _build_prometheus_cpu_info() {
cpu_labels=''
[ -n "${cpu_vendor:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}vendor=\"$(_prom_escape "$cpu_vendor")\""
[ -n "${cpu_friendly_name:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}model=\"$(_prom_escape "$cpu_friendly_name")\""
# arch-specific labels
case "${cpu_vendor:-}" in
GenuineIntel | AuthenticAMD | HygonGenuine)
cpu_labels="${cpu_labels:+$cpu_labels,}arch=\"x86\""
[ -n "${cpu_family:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}family=\"$cpu_family\""
[ -n "${cpu_model:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}model_id=\"$cpu_model\""
[ -n "${cpu_stepping:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}stepping=\"$cpu_stepping\""
[ -n "$cpuid_hex" ] && cpu_labels="${cpu_labels:+$cpu_labels,}cpuid=\"$cpuid_hex\""
[ -n "$codename" ] && cpu_labels="${cpu_labels:+$cpu_labels,}codename=\"$(_prom_escape "$codename")\""
;;
ARM | CAVIUM | PHYTIUM)
cpu_labels="${cpu_labels:+$cpu_labels,}arch=\"arm\""
[ -n "${cpu_part_list:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}part_list=\"$(_prom_escape "$cpu_part_list")\""
[ -n "${cpu_arch_list:-}" ] && cpu_labels="${cpu_labels:+$cpu_labels,}arch_list=\"$(_prom_escape "$cpu_arch_list")\""
;;
esac
[ -n "$smt_val" ] && cpu_labels="${cpu_labels:+$cpu_labels,}smt=\"$smt_val\""
[ -n "$ucode_hex" ] && cpu_labels="${cpu_labels:+$cpu_labels,}microcode=\"$ucode_hex\""
[ -n "$ucode_latest_hex" ] && cpu_labels="${cpu_labels:+$cpu_labels,}microcode_latest=\"$ucode_latest_hex\""