isoloom_plan/configure/
unstarted.rs1use isoloom_spec::syntax::{self, OsRef, PackageName, Step, UnitName};
8
9use super::daemons::DaemonTable;
10use super::family::Family;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Unstarted {
15 pub step: usize,
17 pub package: PackageName,
19 pub unit: UnitName,
21}
22
23#[must_use]
26pub fn unstarted(os: OsRef, m: &syntax::Machine, daemons: &DaemonTable) -> Vec<Unstarted> {
27 let family = Family::from(os);
28 let Some(app) = m.app().filter(|_| family != Family::Windows) else {
29 return Vec::new();
30 };
31 let named: Vec<&UnitName> = app
32 .steps
33 .iter()
34 .filter_map(|s| match s {
35 Step::Service(service) => daemons.find(service.name(), family).map(|(entry, _)| &entry.key),
36 _ => None,
37 })
38 .collect();
39 let mut out = Vec::new();
40 for (i, step) in app.steps.iter().enumerate() {
41 let Step::Packages(packages) = step else { continue };
42 for p in packages {
43 if let Some((entry, form)) = daemons.shipped_by(&p.name, family)
44 && !named.contains(&&entry.key)
45 {
46 out.push(Unstarted {
47 step: i,
48 package: p.name.clone(),
49 unit: form.daemon.unit.clone(),
50 });
51 }
52 }
53 }
54 out
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 fn found(yaml: &str) -> Vec<(usize, String)> {
62 let m: syntax::Machine = serde_yaml_ng::from_str(yaml).unwrap_or_else(|e| panic!("{yaml}: {e}"));
63 let os = m.os.expect("an os");
64 unstarted(os, &m, &DaemonTable::common())
65 .into_iter()
66 .map(|u| (u.step, u.unit.to_string()))
67 .collect()
68 }
69
70 #[test]
71 fn a_daemon_package_without_its_service_step_is_found() {
72 assert_eq!(
73 found("{ os: debian@12, app: { steps: [{ run: a.sh }, { packages: [curl, nginx] }] } }"),
74 [(1, "nginx".to_owned())]
75 );
76 assert_eq!(
77 found("{ os: rocky@9, app: { steps: [{ packages: [httpd, openssh-server] }] } }"),
78 [(0, "httpd".to_owned()), (0, "sshd".to_owned())]
79 );
80 }
81
82 #[test]
83 fn a_service_step_for_the_daemon_says_where_it_runs() {
84 assert_eq!(found("{ os: debian@12, app: { steps: [{ packages: [nginx] }, { service: nginx }] } }"), []);
85 assert_eq!(
86 found("{ os: debian@12, app: { steps: [{ packages: [nginx] }, { service: { name: nginx, enabled: false } }] } }"),
87 []
88 );
89 assert_eq!(
91 found("{ os: debian@12, app: { steps: [{ packages: [openssh-server] }, { service: ssh }] } }"),
92 []
93 );
94 assert_eq!(
95 found("{ os: rocky@9, app: { steps: [{ packages: [openssh-server] }, { service: sshd }] } }"),
96 []
97 );
98 }
99
100 #[test]
101 fn windows_features_start_nothing_to_warn_about() {
102 assert_eq!(found("{ os: windows-server@2022, app: { steps: [{ packages: [Web-Server] }] } }"), []);
103 }
104}