sd_switch/systemd/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
pub mod dbus;
mod dbus_manager;
mod dbus_unit;
pub mod systemctl;

use crate::error::Error;
use std::{fmt::Display, result::Result, str::FromStr, time::Duration};

pub enum SystemStatus {
    Initializing,
    Starting,
    Running,
    Degraded,
    Maintenance,
    Stopping,
}

impl FromStr for SystemStatus {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "initializing" => Ok(SystemStatus::Initializing),
            "starting" => Ok(SystemStatus::Starting),
            "running" => Ok(SystemStatus::Running),
            "degraded" => Ok(SystemStatus::Degraded),
            "maintenance" => Ok(SystemStatus::Maintenance),
            "stopping" => Ok(SystemStatus::Stopping),
            _ => Err(Error::SdSwitch(format!("invalid system status {s}"))),
        }
    }
}

impl Display for SystemStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            SystemStatus::Initializing => write!(f, "initializing"),
            SystemStatus::Starting => write!(f, "starting"),
            SystemStatus::Running => write!(f, "running"),
            SystemStatus::Degraded => write!(f, "degraded"),
            SystemStatus::Maintenance => write!(f, "maintenance"),
            SystemStatus::Stopping => write!(f, "stopping"),
        }
    }
}

pub trait UnitStatus {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn active_state(&self) -> &str;
}

pub trait JobSet {
    fn reload_unit(&mut self, unit_name: &str) -> Result<(), Error>;

    fn restart_unit(&mut self, unit_name: &str) -> Result<(), Error>;

    fn start_unit(&mut self, unit_name: &str) -> Result<(), Error>;

    fn stop_unit(&mut self, unit_name: &str) -> Result<(), Error>;

    fn wait_for_all<F>(&mut self, job_handler: F, timeout: Duration) -> Result<(), Error>
    where
        F: Fn(&str, &str) + Send + 'static;
}

pub trait ServiceManager {
    type JobSet: JobSet;
    type UnitManager: UnitManager;
    type UnitStatus: UnitStatus;

    /// Checks whether this service manager has a working connection to systemd
    /// and that systemd is running.
    fn system_status(&self) -> Result<SystemStatus, Error>;

    /// Performs a systemd daemon reload, blocking until complete.
    fn daemon_reload(&self) -> Result<(), Error>;

    fn reset_failed(&self) -> Result<(), Error>;

    /// Builds a unit manager for the unit with the given address.
    fn unit_manager(&self, address: &Self::UnitStatus) -> Result<Self::UnitManager, Error>;

    fn new_job_set(&self) -> Result<Self::JobSet, Error>;

    fn list_units_by_states(&self, states: &[&str]) -> Result<Vec<Self::UnitStatus>, Error>;
}

pub trait UnitManager {
    fn refuse_manual_start(&self) -> Result<bool, Error>;

    fn refuse_manual_stop(&self) -> Result<bool, Error>;
}