Skip to content

Commit bfda95e

Browse files
authored
Merge pull request #3469 from jarhodes314/refactor/service-managers
refactor: separate service management from system toml configurations
2 parents 6b8dff9 + ada1b6e commit bfda95e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+192
-206
lines changed

crates/common/tedge_config/src/lib.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
pub mod mqtt_config;
21
mod sudo;
3-
pub mod system_services;
4-
pub mod tedge_config_cli;
2+
pub mod tedge_toml;
53
pub use sudo::SudoCommandBuilder;
64
pub mod cli;
5+
mod system_toml;
76

8-
pub use self::tedge_config_cli::config_setting::*;
9-
pub use self::tedge_config_cli::error::*;
10-
pub use self::tedge_config_cli::models::*;
11-
pub use self::tedge_config_cli::tedge_config::*;
12-
pub use self::tedge_config_cli::tedge_config_location::*;
7+
pub use self::system_toml::*;
8+
pub use self::tedge_toml::error::*;
9+
pub use self::tedge_toml::models::*;
10+
pub use self::tedge_toml::tedge_config::*;
11+
pub use self::tedge_toml::tedge_config_location::*;
1312
pub use camino::Utf8Path as Path;
1413
pub use camino::Utf8PathBuf as PathBuf;
1514
pub use certificate::CertificateError;

crates/common/tedge_config/src/mqtt_config.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

crates/common/tedge_config/src/system_services/log_config.rs renamed to crates/common/tedge_config/src/system_toml/log_level.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use camino::Utf8Path;
22

3+
use super::SystemConfig;
4+
use super::SystemTomlError;
35
use crate::cli::LogConfigArgs;
4-
use crate::system_services::SystemConfig;
5-
use crate::system_services::SystemServiceError;
66
use std::io::IsTerminal;
77
use std::str::FromStr;
88

@@ -18,7 +18,7 @@ pub fn log_init(
1818
sname: &str,
1919
flags: &LogConfigArgs,
2020
config_dir: &Utf8Path,
21-
) -> Result<(), SystemServiceError> {
21+
) -> Result<(), SystemTomlError> {
2222
let subscriber = tracing_subscriber::fmt()
2323
.with_writer(std::io::stderr)
2424
.with_ansi(std::io::stderr().is_terminal())
@@ -51,11 +51,11 @@ pub fn log_init(
5151
pub fn get_log_level(
5252
sname: &str,
5353
config_dir: &Utf8Path,
54-
) -> Result<tracing::Level, SystemServiceError> {
54+
) -> Result<tracing::Level, SystemTomlError> {
5555
let loglevel = SystemConfig::try_new(config_dir)?.log;
5656
match loglevel.get(sname) {
5757
Some(ll) => tracing::Level::from_str(&ll.to_uppercase()).map_err(|_| {
58-
SystemServiceError::InvalidLogLevel {
58+
SystemTomlError::InvalidLogLevel {
5959
name: ll.to_string(),
6060
}
6161
}),

crates/common/tedge_config/src/system_services/managers/config.rs renamed to crates/common/tedge_config/src/system_toml/mod.rs

Lines changed: 34 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,51 @@
1-
use crate::system_services::SystemServiceError;
2-
use camino::Utf8Path;
3-
use serde::Deserialize;
41
use std::collections::HashMap;
5-
use std::fs;
62
use std::time::Duration;
73

8-
pub const SERVICE_CONFIG_FILE: &str = "system.toml";
4+
use serde::Deserialize;
5+
6+
mod log_level;
7+
mod services;
8+
9+
pub use self::log_level::*;
10+
pub use self::services::*;
11+
use camino::Utf8Path;
12+
use camino::Utf8PathBuf;
13+
use std::fs;
14+
15+
pub const SYSTEM_CONFIG_FILE: &str = "system.toml";
916
const REBOOT_COMMAND: &[&str] = &["init", "6"];
1017

18+
#[derive(thiserror::Error, Debug)]
19+
pub enum SystemTomlError {
20+
#[error("Toml syntax error in the system config file '{path}': {reason}")]
21+
InvalidSyntax { path: Utf8PathBuf, reason: String },
22+
23+
#[error("Invalid log level: {name:?}, supported levels are info, warn, error and debug")]
24+
InvalidLogLevel { name: String },
25+
}
26+
1127
#[derive(Deserialize, Debug, Default, Eq, PartialEq)]
1228
pub struct SystemConfig {
1329
#[serde(default)]
14-
pub init: InitConfig,
30+
pub init: services::InitConfig,
1531
#[serde(default)]
1632
pub log: HashMap<String, String>,
1733
#[serde(default)]
1834
pub system: SystemSpecificCommands,
1935
}
2036

21-
#[derive(Deserialize, Debug, Eq, PartialEq)]
22-
#[serde(from = "InitConfigToml")]
23-
pub struct InitConfig {
24-
pub name: String,
25-
pub is_available: Vec<String>,
26-
pub restart: Vec<String>,
27-
pub stop: Vec<String>,
28-
pub start: Vec<String>,
29-
pub enable: Vec<String>,
30-
pub disable: Vec<String>,
31-
pub is_active: Vec<String>,
32-
}
33-
34-
#[derive(Deserialize, Debug, Eq, PartialEq)]
35-
#[serde(deny_unknown_fields)]
36-
struct InitConfigToml {
37-
name: String,
38-
is_available: Vec<String>,
39-
restart: Vec<String>,
40-
stop: Vec<String>,
41-
start: Option<Vec<String>>,
42-
enable: Vec<String>,
43-
disable: Vec<String>,
44-
is_active: Vec<String>,
45-
}
37+
impl SystemConfig {
38+
pub fn try_new(config_root: &Utf8Path) -> Result<Self, SystemTomlError> {
39+
let config_path = config_root.join(SYSTEM_CONFIG_FILE);
4640

47-
impl From<InitConfigToml> for InitConfig {
48-
fn from(value: InitConfigToml) -> Self {
49-
Self {
50-
name: value.name,
51-
is_available: value.is_available,
52-
start: value.start.unwrap_or(value.restart.clone()),
53-
restart: value.restart,
54-
stop: value.stop,
55-
enable: value.enable,
56-
disable: value.disable,
57-
is_active: value.is_active,
41+
match fs::read_to_string(config_path.clone()) {
42+
Ok(contents) => {
43+
toml::from_str(contents.as_str()).map_err(|e| SystemTomlError::InvalidSyntax {
44+
path: config_path,
45+
reason: e.to_string(),
46+
})
47+
}
48+
Err(_) => Ok(Self::default()),
5849
}
5950
}
6051
}
@@ -94,37 +85,6 @@ impl Default for SystemSpecificCommands {
9485
}
9586
}
9687

97-
impl Default for InitConfig {
98-
fn default() -> Self {
99-
Self {
100-
name: "systemd".to_string(),
101-
is_available: vec!["/bin/systemctl".into(), "--version".into()],
102-
restart: vec!["/bin/systemctl".into(), "restart".into(), "{}".into()],
103-
stop: vec!["/bin/systemctl".into(), "stop".into(), "{}".into()],
104-
start: vec!["/bin/systemctl".into(), "start".into(), "{}".into()],
105-
enable: vec!["/bin/systemctl".into(), "enable".into(), "{}".into()],
106-
disable: vec!["/bin/systemctl".into(), "disable".into(), "{}".into()],
107-
is_active: vec!["/bin/systemctl".into(), "is-active".into(), "{}".into()],
108-
}
109-
}
110-
}
111-
112-
impl SystemConfig {
113-
pub fn try_new(config_root: &Utf8Path) -> Result<Self, SystemServiceError> {
114-
let config_path = config_root.join(SERVICE_CONFIG_FILE);
115-
116-
match fs::read_to_string(config_path.clone()) {
117-
Ok(contents) => toml::from_str(contents.as_str()).map_err(|e| {
118-
SystemServiceError::SystemConfigInvalidToml {
119-
path: config_path,
120-
reason: e.to_string(),
121-
}
122-
}),
123-
Err(_) => Ok(Self::default()),
124-
}
125-
}
126-
}
127-
12888
#[cfg(test)]
12989
mod tests {
13090
use super::*;
@@ -235,7 +195,7 @@ mod tests {
235195
fn create_temp_system_config(content: &str) -> std::io::Result<(TempDir, Utf8PathBuf)> {
236196
let temp_dir = TempDir::new()?;
237197
let config_root = Utf8Path::from_path(temp_dir.path()).unwrap().to_owned();
238-
let config_file_path = config_root.join(SERVICE_CONFIG_FILE);
198+
let config_file_path = config_root.join(SYSTEM_CONFIG_FILE);
239199
let mut file = std::fs::File::create(config_file_path.as_path())?;
240200
file.write_all(content.as_bytes())?;
241201
Ok((temp_dir, config_root))
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use serde::Deserialize;
2+
3+
#[derive(Deserialize, Debug, Eq, PartialEq)]
4+
#[serde(from = "InitConfigToml")]
5+
pub struct InitConfig {
6+
pub name: String,
7+
pub is_available: Vec<String>,
8+
pub restart: Vec<String>,
9+
pub stop: Vec<String>,
10+
pub start: Vec<String>,
11+
pub enable: Vec<String>,
12+
pub disable: Vec<String>,
13+
pub is_active: Vec<String>,
14+
}
15+
16+
#[derive(Deserialize, Debug, Eq, PartialEq)]
17+
#[serde(deny_unknown_fields)]
18+
struct InitConfigToml {
19+
name: String,
20+
is_available: Vec<String>,
21+
restart: Vec<String>,
22+
stop: Vec<String>,
23+
start: Option<Vec<String>>,
24+
enable: Vec<String>,
25+
disable: Vec<String>,
26+
is_active: Vec<String>,
27+
}
28+
29+
impl From<InitConfigToml> for InitConfig {
30+
fn from(value: InitConfigToml) -> Self {
31+
Self {
32+
name: value.name,
33+
is_available: value.is_available,
34+
start: value.start.unwrap_or(value.restart.clone()),
35+
restart: value.restart,
36+
stop: value.stop,
37+
enable: value.enable,
38+
disable: value.disable,
39+
is_active: value.is_active,
40+
}
41+
}
42+
}
43+
44+
impl Default for InitConfig {
45+
fn default() -> Self {
46+
Self {
47+
name: "systemd".to_string(),
48+
is_available: vec!["/bin/systemctl".into(), "--version".into()],
49+
restart: vec!["/bin/systemctl".into(), "restart".into(), "{}".into()],
50+
stop: vec!["/bin/systemctl".into(), "stop".into(), "{}".into()],
51+
start: vec!["/bin/systemctl".into(), "start".into(), "{}".into()],
52+
enable: vec!["/bin/systemctl".into(), "enable".into(), "{}".into()],
53+
disable: vec!["/bin/systemctl".into(), "disable".into(), "{}".into()],
54+
is_active: vec!["/bin/systemctl".into(), "is-active".into(), "{}".into()],
55+
}
56+
}
57+
}

crates/common/tedge_config/src/tedge_config_cli/config_setting.rs

Lines changed: 0 additions & 34 deletions
This file was deleted.

crates/common/tedge_config/src/tedge_config_cli/error.rs renamed to crates/common/tedge_config/src/tedge_toml/error.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub enum TEdgeConfigError {
1313
FromConfigSetting(#[from] crate::ConfigSettingError),
1414

1515
#[error(transparent)]
16-
FromInvalidConfigUrl(#[from] crate::tedge_config_cli::models::InvalidConnectUrl),
16+
FromInvalidConfigUrl(#[from] crate::tedge_toml::models::InvalidConnectUrl),
1717

1818
#[error("Config file not found: {0}")]
1919
ConfigFileNotFound(std::path::PathBuf),
@@ -31,12 +31,48 @@ pub enum TEdgeConfigError {
3131
DirNotFound(#[from] tedge_utils::paths::PathsError),
3232

3333
#[error(transparent)]
34-
FromParseHostPortError(#[from] crate::tedge_config_cli::models::host_port::ParseHostPortError),
34+
FromParseHostPortError(#[from] crate::tedge_toml::models::host_port::ParseHostPortError),
3535

3636
#[error(transparent)]
3737
FromAtomFileError(#[from] tedge_utils::fs::AtomFileError),
3838
}
3939

40+
pub type ConfigSettingResult<T> = Result<T, ConfigSettingError>;
41+
42+
#[derive(thiserror::Error, Debug)]
43+
/// An error encountered while updating a value in tedge.toml
44+
pub enum ConfigSettingError {
45+
#[error(
46+
r#"A value for `{key}` is missing.
47+
A value can be set with `tedge config set {key} <value>`"#
48+
)]
49+
ConfigNotSet { key: &'static str },
50+
51+
#[error("Readonly setting: {message}")]
52+
ReadonlySetting { message: &'static str },
53+
54+
#[error("Conversion from String failed")]
55+
ConversionFromStringFailed,
56+
57+
#[error("Conversion into String failed")]
58+
ConversionIntoStringFailed,
59+
60+
#[error("Derivation for `{key}` failed: {cause}")]
61+
DerivationFailed { key: &'static str, cause: String },
62+
63+
#[error("Config value {key}, cannot be configured: {message} ")]
64+
SettingIsNotConfigurable {
65+
key: &'static str,
66+
message: &'static str,
67+
},
68+
69+
#[error("An error occurred: {msg}")]
70+
Other { msg: &'static str },
71+
72+
#[error(transparent)]
73+
Write(#[from] crate::WriteError),
74+
}
75+
4076
impl TEdgeConfigError {
4177
pub fn multiple_errors(mut errors: Vec<Self>) -> Self {
4278
match errors.len() {
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
pub mod config_setting;
21
pub mod error;
3-
pub mod tedge_config_location;
4-
52
mod figment;
63
pub mod models;
74
pub mod tedge_config;
5+
pub mod tedge_config_location;

0 commit comments

Comments
 (0)