use super::super::codegen;
use super::super::resolver;
use super::super::types::*;
use super::ApplyConfig;
use crate::transport;
use std::collections::{HashMap, HashSet};
pub(super) fn refresh_in_scope(cfg: &ApplyConfig, id: &str, resource: &Resource) -> bool {
if cfg.resource_filter.is_some_and(|f| id != f) {
return false;
}
if cfg
.tag_filter
.is_some_and(|t| !resource.tags.iter().any(|x| x == t))
{
return false;
}
!resource.phony
}
fn refresh_check_fails(cfg: &ApplyConfig, resource: &Resource) -> bool {
let Ok(resolved) =
resolver::resolve_resource_templates(resource, &cfg.config.params, &cfg.config.machines)
else {
return false;
};
let Ok(script) = codegen::check_script(&resolved) else {
return false;
};
resource.machine.iter().any(|machine_name| {
if cfg.machine_filter.is_some_and(|f| machine_name != f) {
return false;
}
cfg.config
.machines
.get(machine_name)
.and_then(|m| transport::exec_script(m, &script).ok())
.is_some_and(|out| !out.success() && out.exit_code != 2)
})
}
pub(crate) fn refresh_locks(
cfg: &ApplyConfig,
locks: &HashMap<String, StateLock>,
) -> HashMap<String, StateLock> {
let stale: HashSet<String> = cfg
.config
.resources
.iter()
.filter(|(id, r)| refresh_in_scope(cfg, id, r))
.filter(|(_, r)| refresh_check_fails(cfg, r))
.map(|(id, _)| id.clone())
.collect();
let mut result = HashMap::with_capacity(cfg.config.machines.len().max(locks.len()));
let names: HashSet<&String> = cfg.config.machines.keys().chain(locks.keys()).collect();
for machine in names {
let mut new_lock = match locks.get(machine) {
Some(lock) => lock.clone(),
None => empty_lock(machine),
};
new_lock.resources.retain(|rid, _| !stale.contains(rid));
super::refresh_seed::seed_converged(cfg, machine, &mut new_lock);
result.insert(machine.clone(), new_lock);
}
result
}
fn empty_lock(machine: &str) -> StateLock {
StateLock {
schema: "1".to_string(),
machine: machine.to_string(),
hostname: machine.to_string(),
generated_at: crate::tripwire::eventlog::now_iso8601(),
generator: format!("forjar-refresh {}", env!("CARGO_PKG_VERSION")),
blake3_version: "1.5".to_string(),
resources: indexmap::IndexMap::new(),
}
}