Private
Public Access
1
0

fix: resolve CI failures (fmt, clippy, tests)
All checks were successful
CI/CD Pipeline / Code Format (pull_request) Successful in 4s
CI/CD Pipeline / Clippy Lints (pull_request) Successful in 47s
CI/CD Pipeline / All Unit Tests (pull_request) Successful in 1m22s
CI/CD Pipeline / Security Audit (pull_request) Successful in 5s
CI/CD Pipeline / Enrollment Tests (pull_request) Successful in 1m22s
CI/CD Pipeline / Verify Enrollment CLI Flag (pull_request) Successful in 1m27s
CI/CD Pipeline / Build Debian Package (Ubuntu 22.04) (pull_request) Successful in 2m49s
CI/CD Pipeline / Build RPM Package (pull_request) Successful in 2m40s
CI/CD Pipeline / Build Arch Package (pull_request) Successful in 3m2s
CI/CD Pipeline / Build Debian Package (pull_request) Successful in 2m34s
CI/CD Pipeline / Build Alpine Package (pull_request) Successful in 4m3s

- Fix rustfmt formatting in cache.rs, patches.rs, system.rs, routes.rs, main.rs
- Add Default impl for PackageCacheState (clippy new_without_default)
- Change apply_with_cache_retry generic bound from Fn to FnMut
- Add mut to refresh_fn parameter for FnMut compatibility
- Replace bool comparison with ! operator (clippy bool_comparison)
- Update todo.md with completed status
This commit is contained in:
2026-05-27 15:04:25 -05:00
parent cf3d597480
commit 6f63eeed57
6 changed files with 137 additions and 72 deletions

View File

@ -126,7 +126,12 @@ pub async fn apply_patches(
// MANDATORY: Refresh package cache before applying patches
let _ = job_manager_clone
.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Refreshing package index...".to_string()))
.update_job(
&job_id_clone,
JobStatus::Running,
Some(0),
Some("Refreshing package index...".to_string()),
)
.await;
let _ = job_manager_clone
.add_job_log(&job_id_clone, "Refreshing package cache...".to_string())
@ -135,10 +140,18 @@ pub async fn apply_patches(
match backend_clone.refresh_package_cache(&cache_state_clone) {
Ok(_) => {
let _ = job_manager_clone
.add_job_log(&job_id_clone, "Package cache refreshed successfully".to_string())
.add_job_log(
&job_id_clone,
"Package cache refreshed successfully".to_string(),
)
.await;
let _ = job_manager_clone
.update_job(&job_id_clone, JobStatus::Running, Some(10), Some("Cache refreshed, applying patches...".to_string()))
.update_job(
&job_id_clone,
JobStatus::Running,
Some(10),
Some("Cache refreshed, applying patches...".to_string()),
)
.await;
}
Err(e) => {
@ -194,17 +207,25 @@ pub async fn apply_patches(
// 404/fetch error: refresh cache and retry once
info!(job_id = %job_id_clone, "Patch apply failed with fetch error, refreshing cache and retrying");
let _ = job_manager_clone
.add_job_log(&job_id_clone, "Fetch error detected, refreshing cache and retrying...".to_string())
.add_job_log(
&job_id_clone,
"Fetch error detected, refreshing cache and retrying..."
.to_string(),
)
.await;
match backend_clone.refresh_package_cache(&cache_state_clone) {
Ok(_) => {
let _ = job_manager_clone
.add_job_log(&job_id_clone, "Cache refreshed, retrying patch apply...".to_string())
.add_job_log(
&job_id_clone,
"Cache refreshed, retrying patch apply...".to_string(),
)
.await;
}
Err(refresh_err) => {
let err_msg = format!("Cache refresh on retry failed: {}", refresh_err);
let err_msg =
format!("Cache refresh on retry failed: {}", refresh_err);
let _ = job_manager_clone.fail_job(&job_id_clone, err_msg).await;
error!(job_id = %job_id_clone, error = %refresh_err, "Cache refresh on retry failed");
return;
@ -228,29 +249,40 @@ pub async fn apply_patches(
),
)
.await;
match backend_clone.reboot_system(request.reboot_delay_seconds) {
match backend_clone.reboot_system(request.reboot_delay_seconds)
{
Ok(_) => {
let _ = job_manager_clone
.add_job_log(&job_id_clone, "Reboot command executed".to_string())
.add_job_log(
&job_id_clone,
"Reboot command executed".to_string(),
)
.await;
}
Err(e) => {
let _ = job_manager_clone
.add_job_log(&job_id_clone, format!("Reboot failed: {}", e))
.add_job_log(
&job_id_clone,
format!("Reboot failed: {}", e),
)
.await;
}
}
}
}
Err(retry_err) => {
let _ = job_manager_clone.fail_job(&job_id_clone, retry_err.to_string()).await;
let _ = job_manager_clone
.fail_job(&job_id_clone, retry_err.to_string())
.await;
error!(job_id = %job_id_clone, error = %retry_err, "Patch application failed after retry");
}
}
}
Err(e) => {
// Non-fetch error: fail immediately
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
let _ = job_manager_clone
.fail_job(&job_id_clone, e.to_string())
.await;
error!(job_id = %job_id_clone, error = %e, "Patch application failed");
}
}

View File

@ -42,11 +42,11 @@ pub struct SystemInfoData {
/// Health check response data
#[derive(Debug, Serialize)]
pub struct HealthData {
pub status: String, // "healthy" or "degraded"
pub status: String, // "healthy" or "degraded"
pub uptime_seconds: u64,
pub version: String,
pub last_cache_update: Option<String>, // RFC3339 timestamp
pub cache_status: String, // "fresh", "stale", "unknown", "failed"
pub last_cache_update: Option<String>, // RFC3339 timestamp
pub cache_status: String, // "fresh", "stale", "unknown", "failed"
}
/// Service status response data
@ -138,15 +138,27 @@ pub async fn health_check(
match backend.refresh_package_cache(&cache_state) {
Ok(_) => {
let updated = cache_state.status();
("healthy".to_string(), "fresh".to_string(), updated.last_update.map(|dt| dt.to_rfc3339()))
(
"healthy".to_string(),
"fresh".to_string(),
updated.last_update.map(|dt| dt.to_rfc3339()),
)
}
Err(e) => {
error!("Health check cache refresh failed: {}", e);
("degraded".to_string(), "failed".to_string(), cache_status_val.last_update.map(|dt| dt.to_rfc3339()))
(
"degraded".to_string(),
"failed".to_string(),
cache_status_val.last_update.map(|dt| dt.to_rfc3339()),
)
}
}
} else {
("healthy".to_string(), "fresh".to_string(), cache_status_val.last_update.map(|dt| dt.to_rfc3339()))
(
"healthy".to_string(),
"fresh".to_string(),
cache_status_val.last_update.map(|dt| dt.to_rfc3339()),
)
};
let response = ApiResponse::success(HealthData {

View File

@ -26,21 +26,24 @@ pub fn configure_api_routes(
) {
info!("Configuring API v1 routes");
cfg.app_data(job_manager).app_data(backend).app_data(cache_state).service(
web::scope("/api/v1")
// VULN-005: Default handler for unsupported methods returns 405 instead of 404
.default_service(web::route().to(method_not_allowed))
// Package Management Endpoints
.configure(packages::configure_routes)
// Patch Management Endpoints
.configure(patches::configure_routes)
// System Management Endpoints
.configure(system::configure_routes)
// Job Management Endpoints
.configure(jobs::configure_routes)
// WebSocket Endpoint
.configure(websocket::configure_routes),
);
cfg.app_data(job_manager)
.app_data(backend)
.app_data(cache_state)
.service(
web::scope("/api/v1")
// VULN-005: Default handler for unsupported methods returns 405 instead of 404
.default_service(web::route().to(method_not_allowed))
// Package Management Endpoints
.configure(packages::configure_routes)
// Patch Management Endpoints
.configure(patches::configure_routes)
// System Management Endpoints
.configure(system::configure_routes)
// Job Management Endpoints
.configure(jobs::configure_routes)
// WebSocket Endpoint
.configure(websocket::configure_routes),
);
}
/// Health check route (outside API scope for load balancer checks)