WP-10: OS and package inventory
Debian inspector (dpkg-query, apt-get -s upgrade, snap list, os-release, reboot-required) behind a CommandRunner port with tested parsers, fake inspector for dev, persisted inventory snapshot, package_refresh job, /api/system/inventory, Updates page with OS card, summary and filterable package table. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use chrono::Utc;
|
||||
use domain::host::Inventory;
|
||||
use domain::ports::{HostInspector, InventoryRepository};
|
||||
use domain::DomainError;
|
||||
@ -14,18 +15,26 @@ pub struct InventoryService {
|
||||
|
||||
impl InventoryService {
|
||||
pub fn new(inspector: Arc<dyn HostInspector>, repo: Arc<dyn InventoryRepository>) -> Self {
|
||||
let _ = (&inspector, &repo);
|
||||
Self { inspector, repo }
|
||||
}
|
||||
|
||||
/// Query the host and persist a new snapshot.
|
||||
pub async fn refresh(&self) -> Result<Inventory, DomainError> {
|
||||
todo!()
|
||||
let os = self.inspector.os_info().await?;
|
||||
let mut packages = self.inspector.packages().await?;
|
||||
packages.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
let inventory = Inventory {
|
||||
os,
|
||||
packages,
|
||||
refreshed_at: Utc::now(),
|
||||
};
|
||||
self.repo.save(&inventory).await?;
|
||||
Ok(inventory)
|
||||
}
|
||||
|
||||
/// Last persisted snapshot.
|
||||
pub async fn current(&self) -> Result<Option<Inventory>, DomainError> {
|
||||
todo!()
|
||||
self.repo.load().await
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +43,27 @@ pub struct PackageRefreshJob(pub Arc<InventoryService>);
|
||||
|
||||
#[async_trait]
|
||||
impl JobHandler for PackageRefreshJob {
|
||||
async fn run(&self, _params: Option<String>, _log: &dyn JobLog) -> Result<(), String> {
|
||||
todo!()
|
||||
async fn run(&self, _params: Option<String>, log: &dyn JobLog) -> Result<(), String> {
|
||||
log.line("querying host for OS and package information")
|
||||
.await;
|
||||
let inv = self.0.refresh().await.map_err(|e| e.to_string())?;
|
||||
log.line(&format!(
|
||||
"{} {} on kernel {}",
|
||||
inv.os.name, inv.os.version, inv.os.kernel
|
||||
))
|
||||
.await;
|
||||
log.line(&format!(
|
||||
"{} packages, {} upgradable ({} security){}",
|
||||
inv.packages.len(),
|
||||
inv.upgradable(),
|
||||
inv.security_upgrades(),
|
||||
if inv.os.reboot_required {
|
||||
", reboot required"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
))
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user