//! Run Vulkan enumeration on the current host and print the resulting //! `BoxReportPayload` skeleton as pretty JSON. //! //! No measurements, no signing. The goal at this stage is to confirm //! that the discrete-compute filter sees the right cards and skips //! everything else, and that the host-identity reads return something //! useful on the target platform. use std::time::{SystemTime, UNIX_EPOCH}; use everycycle_appraise::enumerate::{EnumeratedDevice, enumerate}; const PROBE_SUITE: &str = env!("CARGO_PKG_VERSION"); fn main() { let host = match enumerate() { Ok(h) => h, Err(e) => { eprintln!("enumeration failed: {e}"); std::process::exit(1); } }; eprintln!("host: {}", host.host.hostname); if let Some(dmi) = &host.host.dmi_string { eprintln!("dmi: {dmi}"); } eprintln!("cpu: {}", host.host.cpu_model); eprintln!("devices: {}", host.devices.len()); for d in &host.devices { print_device(d); } eprintln!(); let payload = host.into_box_payload(rough_rfc3339_now(), 0.0, PROBE_SUITE); match serde_json::to_string_pretty(&payload) { Ok(s) => println!("{s}"), Err(e) => { eprintln!("could not serialize box payload: {e}"); std::process::exit(1); } } } #[allow(clippy::cast_precision_loss)] fn print_device(d: &EnumeratedDevice) { eprintln!( " - {} @ {} pci_ids={} driver={} vram={:.1} GiB", d.device_name, d.bus_address, d.pci_ids, d.driver_version, d.physical_bytes as f64 / (1024.0 * 1024.0 * 1024.0), ); } /// A placeholder RFC 3339 timestamp using the system clock at second /// resolution. Replaced by a real time source once a probe lands that /// needs one. #[allow(clippy::cast_possible_wrap)] fn rough_rfc3339_now() -> String { let Ok(d) = SystemTime::now().duration_since(UNIX_EPOCH) else { return "1970-01-01T00:00:00Z".to_string(); }; let secs = d.as_secs() as i64; let (y, mo, da, h, mi, s) = civil_from_unix(secs); format!("{y:04}-{mo:02}-{da:02}T{h:02}:{mi:02}:{s:02}Z") } /// Trivial UTC unix-seconds to civil-date converter. Good enough for /// timestamp recording; will be replaced by a real time crate when we /// need timezone correctness for anything user-facing. #[allow( clippy::cast_possible_truncation, clippy::cast_sign_loss, clippy::many_single_char_names )] fn civil_from_unix(secs: i64) -> (i32, u32, u32, u32, u32, u32) { // Howard Hinnant's date algorithm, public domain. let z = secs.div_euclid(86_400); let day_secs = secs.rem_euclid(86_400); let h = (day_secs / 3600) as u32; let mi = ((day_secs / 60) % 60) as u32; let s = (day_secs % 60) as u32; let z = z + 719_468; let era = if z >= 0 { z } else { z - 146_096 } / 146_097; let doe = (z - era * 146_097) as u32; let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365; let y = i64::from(yoe) + era * 400; let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); let mp = (5 * doy + 2) / 153; let d = doy - (153 * mp + 2) / 5 + 1; let m = if mp < 10 { mp + 3 } else { mp - 9 }; let y = y + i64::from(m <= 2); (y as i32, m, d, h, mi, s) }