summaryrefslogtreecommitdiffstats
path: root/crates/core
diff options
context:
space:
mode:
Diffstat (limited to 'crates/core')
-rw-r--r--crates/core/agent_interface/Cargo.toml2
-rw-r--r--crates/core/c8y_api/Cargo.toml2
-rw-r--r--crates/core/c8y_smartrest/Cargo.toml2
-rw-r--r--crates/core/c8y_translator/Cargo.toml2
-rw-r--r--crates/core/c8y_translator/fuzz/Cargo.lock8
-rw-r--r--crates/core/plugin_sm/Cargo.toml3
-rw-r--r--crates/core/plugin_sm/src/lib.rs1
-rw-r--r--crates/core/plugin_sm/src/logged_command.rs231
-rw-r--r--crates/core/plugin_sm/src/plugin.rs2
-rw-r--r--crates/core/tedge/Cargo.toml4
-rw-r--r--crates/core/tedge/src/cli/config/config_key.rs6
-rw-r--r--crates/core/tedge/src/main.rs27
-rw-r--r--crates/core/tedge_agent/Cargo.toml2
-rw-r--r--crates/core/tedge_agent/src/agent.rs24
-rw-r--r--crates/core/tedge_agent/src/main.rs4
-rw-r--r--crates/core/tedge_agent/src/state.rs2
-rw-r--r--crates/core/tedge_mapper/Cargo.toml3
-rw-r--r--crates/core/tedge_mapper/src/az/mapper.rs17
-rw-r--r--crates/core/tedge_mapper/src/c8y/mapper.rs140
-rw-r--r--crates/core/tedge_mapper/src/collectd/mapper.rs10
-rw-r--r--crates/core/tedge_mapper/src/core/component.rs6
-rw-r--r--crates/core/tedge_mapper/src/main.rs6
-rw-r--r--crates/core/tedge_watchdog/Cargo.toml9
-rw-r--r--crates/core/thin_edge_json/Cargo.toml2
24 files changed, 213 insertions, 302 deletions
diff --git a/crates/core/agent_interface/Cargo.toml b/crates/core/agent_interface/Cargo.toml
index 352f62b2..e7fb2d01 100644
--- a/crates/core/agent_interface/Cargo.toml
+++ b/crates/core/agent_interface/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "agent_interface"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
diff --git a/crates/core/c8y_api/Cargo.toml b/crates/core/c8y_api/Cargo.toml
index 3d9e8036..aefbb6c5 100644
--- a/crates/core/c8y_api/Cargo.toml
+++ b/crates/core/c8y_api/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "c8y_api"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
diff --git a/crates/core/c8y_smartrest/Cargo.toml b/crates/core/c8y_smartrest/Cargo.toml
index 5426da5e..3aed6de4 100644
--- a/crates/core/c8y_smartrest/Cargo.toml
+++ b/crates/core/c8y_smartrest/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "c8y_smartrest"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
diff --git a/crates/core/c8y_translator/Cargo.toml b/crates/core/c8y_translator/Cargo.toml
index a8c427ec..b2aecfe3 100644
--- a/crates/core/c8y_translator/Cargo.toml
+++ b/crates/core/c8y_translator/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "c8y_translator"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
diff --git a/crates/core/c8y_translator/fuzz/Cargo.lock b/crates/core/c8y_translator/fuzz/Cargo.lock
index e7a4927b..b9b5965d 100644
--- a/crates/core/c8y_translator/fuzz/Cargo.lock
+++ b/crates/core/c8y_translator/fuzz/Cargo.lock
@@ -25,7 +25,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "c8y_translator"
-version = "0.6.1"
+version = "0.6.2"
dependencies = [
"clock",
"json-writer",
@@ -56,7 +56,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clock"
-version = "0.6.1"
+version = "0.6.2"
dependencies = [
"mockall",
"time",
@@ -97,7 +97,7 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "json-writer"
-version = "0.6.1"
+version = "0.6.2"
dependencies = [
"serde_json",
"thiserror",
@@ -309,7 +309,7 @@ checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b"
[[package]]
name = "thin_edge_json"
-version = "0.6.1"
+version = "0.6.2"
dependencies = [
"clock",
"json-writer",
diff --git a/crates/core/plugin_sm/Cargo.toml b/crates/core/plugin_sm/Cargo.toml
index b246444d..e54837a1 100644
--- a/crates/core/plugin_sm/Cargo.toml
+++ b/crates/core/plugin_sm/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "plugin_sm"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
@@ -10,6 +10,7 @@ agent_interface = { path = "../agent_interface" }
async-trait = "0.1"
csv = "1.1"
download = { path = "../../common/download" }
+logged_command = { path = "../../common/logged_command" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tedge_utils = { path = "../../common/tedge_utils" }
diff --git a/crates/core/plugin_sm/src/lib.rs b/crates/core/plugin_sm/src/lib.rs
index 79800999..c124bbbc 100644
--- a/crates/core/plugin_sm/src/lib.rs
+++ b/crates/core/plugin_sm/src/lib.rs
@@ -1,4 +1,3 @@
pub mod log_file;
-pub mod logged_command;
pub mod plugin;
pub mod plugin_manager;
diff --git a/crates/core/plugin_sm/src/logged_command.rs b/crates/core/plugin_sm/src/logged_command.rs
deleted file mode 100644
index 11739ce0..00000000
--- a/crates/core/plugin_sm/src/logged_command.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use std::ffi::OsStr;
-use std::process::{Output, Stdio};
-use tokio::fs::File;
-use tokio::io::{AsyncWriteExt, BufWriter};
-use tokio::process::{Child, Command};
-
-pub struct LoggingChild {
- command_line: String,
- pub inner_child: Child,
-}
-
-impl LoggingChild {
- pub async fn wait_with_output(
- self,
- logger: &mut BufWriter<File>,
- ) -> Result<Output, std::io::Error> {
- let outcome = self.inner_child.wait_with_output().await;
- if let Err(err) = LoggedCommand::log_outcome(&self.command_line, &outcome, logger).await {
- tracing::log::error!("Fail to log the command execution: {}", err);
- }
-
- outcome
- }
-}
-
-/// A command which execution is logged.
-///
-/// This struct wraps the main command with a nice representation of that command.
-/// This `command_line` field is only required because the
-/// [`Command::get_program()`](https://doc.rust-lang.org/std/process/struct.Command.html#method.get_program)
-/// and
-/// [`Command::get_args()`](https://doc.rust-lang.org/std/process/struct.Command.html#method.get_args)
-/// are nightly-only experimental APIs.
-pub struct LoggedCommand {
- command_line: String,
- command: Command,
-}
-
-impl std::fmt::Display for LoggedCommand {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.command_line.fmt(f)
- }
-}
-
-impl LoggedCommand {
- pub fn new(program: impl AsRef<OsStr>) -> LoggedCommand {
- let command_line = match program.as_ref().to_str() {
- None => format!("{:?}", program.as_ref()),
- Some(cmd) => cmd.to_string(),
- };
-
- let mut command = Command::new(program);
- command
- .current_dir("/tmp")
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped());
-
- LoggedCommand {
- command_line,
- command,
- }
- }
-
- pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut LoggedCommand {
- // The arguments are displayed as debug, to be properly quoted and distinguished from each other.
- self.command_line.push_str(&format!(" {:?}", arg.as_ref()));
- self.command.arg(arg);
- self
- }
-
- /// Execute the command and log its exit status, stdout and stderr
- ///
- /// If the command has been executed the outcome is returned (successful or not).
- /// If the command fails to execute (say not found or not executable) an `std::io::Error` is returned.
- ///
- /// If the function fails to log the execution of the command,
- /// this is logged with `log::error!` without changing the return value.
- pub async fn execute(mut self, logger: &mut BufWriter<File>) -> Result<Output, std::io::Error> {
- let outcome = self.command.output().await;
-
- if let Err(err) = LoggedCommand::log_outcome(&self.command_line, &outcome, logger).await {
- tracing::log::error!("Fail to log the command execution: {}", err);
- }
-
- outcome
- }
-
- pub fn spawn(&mut self) -> Result<LoggingChild, std::io::Error> {
- let child = self.command.spawn()?;
- Ok(LoggingChild {
- command_line: self.command_line.clone(),
- inner_child: child,
- })
- }
-
- async fn log_outcome(
- command_line: &str,
- result: &Result<Output, std::io::Error>,
- logger: &mut BufWriter<File>,
- ) -> Result<(), std::io::Error> {
- logger
- .write_all(format!("----- $ {}\n", command_line).as_bytes())
- .await?;
-
- match result.as_ref() {
- Ok(output) => {
- match &output.status.code() {
- None => logger.write_all(b"exit status: unknown\n\n").await?,
- Some(code) => {
- logger
- .write_all(format!("exit status: {}\n\n", code).as_bytes())
- .await?
- }
- };
- logger.write_all(b"stdout <<EOF\n").await?;
- logger.write_all(&output.stdout).await?;
- logger.write_all(b"EOF\n\n").await?;
- logger.write_all(b"stderr <<EOF\n").await?;
- logger.write_all(&output.stderr).await?;
- logger.write_all(b"EOF\n").await?;
- }
- Err(err) => {
- logger
- .write_all(format!("error: {}\n", &err).as_bytes())
- .await?;
- }
- }
-
- logger.flush().await?;
- Ok(())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use tempfile::*;
- use tokio::fs::File;
-
- #[tokio::test]
- async fn on_execute_are_logged_command_line_exit_status_stdout_and_stderr(
- ) -> Result<(), anyhow::Error> {
- // Prepare a log file
- let tmp_dir = TempDir::new()?;
- let log_file_path = tmp_dir.path().join("operation.log");
- let log_file = File::create(log_file_path.clone()).await?;
- let mut logger = BufWriter::new(log_file);
-
- // Prepare a command
- let mut command = LoggedCommand::new("echo");
- command.arg("Hello").arg("World!");
-
- // Execute the command with logging
- let _ = command.execute(&mut logger).await;
-
- let log_content = String::from_utf8(std::fs::read(&log_file_path)?)?;
- assert_eq!(
- log_content,
- r#"----- $ echo "Hello" "World!"
-exit status: 0
-
-stdout <<EOF
-Hello World!
-EOF
-
-stderr <<EOF
-EOF
-"#
- );
- Ok(())
- }
-
- #[tokio::test]
- async fn on_execute_with_error_stderr_is_logged() -> Result<(), anyhow::Error> {
- // Prepare a log file
- let tmp_dir = TempDir::new()?;
- let log_file_path = tmp_dir.path().join("operation.log");
- let log_file = File::create(log_file_path.clone()).await?;
- let mut logger = BufWriter::new(log_file);
-
- // Prepare a command that triggers some content on stderr
- let mut command = LoggedCommand::new("ls");
- command.arg("dummy-file");
-
- // Execute the command with logging
- let _ = command.execute(&mut logger).await;
-
- // On expect the errors to be logged
- let log_content = String::from_utf8(std::fs::read(&log_file_path)?)?;
- assert_eq!(
- log_content,
- r#"----- $ ls "dummy-file"
-exit status: 2
-
-stdout <<EOF
-EOF
-
-stderr <<EOF
-ls: cannot access 'dummy-file': No such file or directory
-EOF
-"#
- );
- Ok(())
- }
-
- #[tokio::test]
- async fn on_execution_error_are_logged_command_line_and_error() -> Result<(), anyhow::Error> {
- // Prepare a log file
- let tmp_dir = TempDir::new()?;
- let log_file_path = tmp_dir.path().join("operation.log");
- let log_file = File::create(log_file_path.clone()).await?;
- let mut logger = BufWriter::new(log_file);
-
- // Prepare a command that cannot be executed
- let command = LoggedCommand::new("dummy-command");
-
- // Execute the command with logging
- let _ = command.execute(&mut logger).await;
-
- // The fact that the command cannot be executed must be logged
- let log_content = String::from_utf8(std::fs::read(&log_file_path)?)?;
- assert_eq!(
- log_content,
- r#"----- $ dummy-command
-error: No such file or directory (os error 2)
-"#
- );
- Ok(())
- }
-}
diff --git a/crates/core/plugin_sm/src/plugin.rs b/crates/core/plugin_sm/src/plugin.rs
index f7df5449..95ab2988 100644
--- a/crates/core/plugin_sm/src/plugin.rs
+++ b/crates/core/plugin_sm/src/plugin.rs
@@ -1,8 +1,8 @@
-use crate::logged_command::LoggedCommand;
use agent_interface::*;
use async_trait::async_trait;
use csv::ReaderBuilder;
use download::Downloader;
+use logged_command::LoggedCommand;
use serde::Deserialize;
use std::path::Path;
use std::{path::PathBuf, process::Output};
diff --git a/crates/core/tedge/Cargo.toml b/crates/core/tedge/Cargo.toml
index 14b13d89..f236f29b 100644
--- a/crates/core/tedge/Cargo.toml
+++ b/crates/core/tedge/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "tedge"
-version = "0.6.1"
+version = "0.6.2"
edition = "2021"
rust-version = "1.58.1"
authors = ["thin-edge.io team <info@thin-edge.io>"]
@@ -9,7 +9,7 @@ readme = "README.md"
description = "tedge is the cli tool for thin-edge.io"
[package.metadata.deb]
-depends = "mosquitto"
+recommends = "mosquitto"
maintainer-scripts = "../../../configuration/debian/tedge"
[dependencies]
diff --git a/crates/core/tedge/src/cli/config/config_key.rs b/crates/core/tedge/src/cli/config/config_key.rs
index 064791a4..96227269 100644
--- a/crates/core/tedge/src/cli/config/config_key.rs
+++ b/crates/core/tedge/src/cli/config/config_key.rs
@@ -57,9 +57,9 @@ impl ConfigKey {
config_key!(MqttExternalCertfileSetting),
config_key!(MqttExternalKeyfileSetting),
config_key!(SoftwarePluginDefaultSetting),
- config_key!(TmpPathDefaultSetting),
- config_key!(LogPathDefaultSetting),
- config_key!(RunPathDefaultSetting),
+ config_key!(TmpPathSetting),
+ config_key!(LogPathSetting),
+ config_key!(RunPathSetting),
]
}
}
diff --git a/crates/core/tedge/src/main.rs b/crates/core/tedge/src/main.rs
index 5b384e35..eab007f6 100644
--- a/crates/core/tedge/src/main.rs
+++ b/crates/core/tedge/src/main.rs
@@ -1,6 +1,8 @@
#![forbid(unsafe_code)]
#![deny(clippy::mem_forget)]
+use std::path::PathBuf;
+
use anyhow::Context;
use clap::Parser;
use tedge_users::UserManager;
@@ -18,7 +20,7 @@ fn main() -> anyhow::Result<()> {
let opt = cli::Opt::parse();
if opt.init {
- initialize_tedge()?;
+ initialize_tedge(&opt.config_dir)?;
return Ok(());
}
@@ -45,12 +47,23 @@ fn main() -> anyhow::Result<()> {
}
}
-fn initialize_tedge() -> anyhow::Result<()> {
- create_directory_with_user_group("/etc/tedge", "tedge", "tedge", 0o775)?;
+fn initialize_tedge(cfg_dir: &PathBuf) -> anyhow::Result<()> {
+ let config_dir = cfg_dir.as_path().display().to_string();
+ create_directory_with_user_group(&config_dir, "tedge", "tedge", 0o775)?;
create_directory_with_user_group("/var/log/tedge", "tedge", "tedge", 0o775)?;
- create_directory_with_user_group("/etc/tedge/mosquitto-conf", "tedge", "tedge", 0o775)?;
- create_directory_with_user_group("/etc/tedge/operations", "tedge", "tedge", 0o775)?;
- create_directory_with_user_group("/etc/tedge/plugins", "tedge", "tedge", 0o775)?;
- create_directory_with_user_group("/etc/tedge/device-certs", "mosquitto", "mosquitto", 0o775)?;
+ create_directory_with_user_group(
+ &format!("{config_dir}/mosquitto-conf"),
+ "tedge",
+ "tedge",
+ 0o775,
+ )?;
+ create_directory_with_user_group(&format!("{config_dir}/operations"), "tedge", "tedge", 0o775)?;
+ create_directory_with_user_group(&format!("{config_dir}/plugins"), "tedge", "tedge", 0o775)?;
+ create_directory_with_user_group(
+ &format!("{config_dir}/device-certs"),
+ "mosquitto",
+ "mosquitto",
+ 0o775,
+ )?;
Ok(())
}
diff --git a/crates/core/tedge_agent/Cargo.toml b/crates/core/tedge_agent/Cargo.toml
index 63a2ba5a..af1498bf 100644
--- a/crates/core/tedge_agent/Cargo.toml
+++ b/crates/core/tedge_agent/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "tedge_agent"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
diff --git a/crates/core/tedge_agent/src/agent.rs b/crates/core/tedge_agent/src/agent.rs
index df41368f..b7c7ba27 100644
--- a/crates/core/tedge_agent/src/agent.rs
+++ b/crates/core/tedge_agent/src/agent.rs
@@ -20,9 +20,9 @@ use serde_json::json;
use std::process;
use std::{convert::TryInto, fmt::Debug, path::PathBuf, sync::Arc};
use tedge_config::{
- ConfigRepository, ConfigSettingAccessor, ConfigSettingAccessorStringExt, LogPathDefaultSetting,
- MqttBindAddressSetting, MqttPortSetting, RunPathDefaultSetting, SoftwarePluginDefaultSetting,
- TEdgeConfigLocation, TmpPathDefaultSetting, DEFAULT_LOG_PATH, DEFAULT_RUN_PATH,
+ ConfigRepository, ConfigSettingAccessor, ConfigSettingAccessorStringExt, LogPathSetting,
+ MqttBindAddressSetting, MqttPortSetting, RunPathSetting, SoftwarePluginDefaultSetting,
+ TEdgeConfigLocation, TmpPathSetting, DEFAULT_LOG_PATH, DEFAULT_RUN_PATH,
};
use tedge_utils::file::create_directory_with_user_group;
use tokio::sync::Mutex;
@@ -139,11 +139,11 @@ impl SmAgentConfig {
.tedge_config_root_path()
.to_path_buf();
- let tedge_download_dir = tedge_config.query_string(TmpPathDefaultSetting)?.into();
+ let tedge_download_dir = tedge_config.query_string(TmpPathSetting)?.into();
- let tedge_log_dir: String = tedge_config.query_string(LogPathDefaultSetting)?.into();
+ let tedge_log_dir: String = tedge_config.query_string(LogPathSetting)?.into();
let tedge_log_dir = PathBuf::from(&format!("{tedge_log_dir}/{AGENT_LOG_PATH}"));
- let tedge_run_dir = tedge_config.query_string(RunPathDefaultSetting)?.into();
+ let tedge_run_dir = tedge_config.query_string(RunPathSetting)?.into();
Ok(SmAgentConfig::default()
.with_sm_home(tedge_config_path)
@@ -224,14 +224,10 @@ impl SmAgent {
}
#[instrument(skip(self), name = "sm-agent")]
- pub async fn init(&mut self) -> Result<(), anyhow::Error> {
- create_directory_with_user_group("/etc/tedge/.agent", "tedge-agent", "tedge-agent", 0o775)?;
- create_directory_with_user_group(
- "/var/log/tedge/agent",
- "tedge-agent",
- "tedge-agent",
- 0o775,
- )?;
+ pub async fn init(&mut self, config_dir: PathBuf) -> Result<(), anyhow::Error> {
+ let cfg_dir = config_dir.as_path().display().to_string();
+ create_directory_with_user_group(&format!("{cfg_dir}/.agent"), "tedge", "tedge", 0o775)?;
+ create_directory_with_user_group("/var/log/tedge/agent", "tedge", "tedge", 0o775)?;
info!("Initializing the tedge agent session");
mqtt_channel::init_session(&self.config.mqtt_config).await?;
diff --git a/crates/core/tedge_agent/src/main.rs b/crates/core/tedge_agent/src/main.rs
index 4e71de4b..96069769 100644
--- a/crates/core/tedge_agent/src/main.rs
+++ b/crates/core/tedge_agent/src/main.rs
@@ -47,13 +47,13 @@ async fn main() -> Result<(), anyhow::Error> {
tedge_utils::logging::initialise_tracing_subscriber(agent_opt.debug);
let tedge_config_location =
- tedge_config::TEdgeConfigLocation::from_custom_root(agent_opt.config_dir);
+ tedge_config::TEdgeConfigLocation::from_custom_root(agent_opt.config_dir.clone());
let mut agent = agent::SmAgent::try_new(
"tedge_agent",
SmAgentConfig::try_new(tedge_config_location)?,
)?;
if agent_opt.init {
- agent.init().await?;
+ agent.init(agent_opt.config_dir).await?;
} else if agent_opt.clear {
agent.clear_session().await?;
} else {
diff --git a/crates/core/tedge_agent/src/state.rs b/crates/core/tedge_agent/src/state.rs
index e58052e5..b7819448 100644
--- a/crates/core/tedge_agent/src/state.rs
+++ b/crates/core/tedge_agent/src/state.rs
@@ -39,7 +39,7 @@ impl StateRepository for AgentStateRepository {
async fn store(&self, state: &State) -> Result<(), StateError> {
let toml = toml::to_string_pretty(&state)?;
- // Create `$HOME/.tedge` or `/etc/tedge` directory in case it does not exist yet
+ // Create in path given through `config-dir` or `/etc/tedge` directory in case it does not exist yet
if !self.state_repo_root.exists() {
let () = fs::create_dir(&self.state_repo_root).await?;
}
diff --git a/crates/core/tedge_mapper/Cargo.toml b/crates/core/tedge_mapper/Cargo.toml
index 64bdbd86..92bf879c 100644
--- a/crates/core/tedge_mapper/Cargo.toml
+++ b/crates/core/tedge_mapper/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "tedge_mapper"
-version = "0.6.1"
+version = "0.6.2"
authors = ["thin-edge.io team <info@thin-edge.io>"]
edition = "2021"
rust-version = "1.58.1"
@@ -57,6 +57,7 @@ tracing = { version = "0.1", features = ["attributes", "log"] }
assert_matches = "1.5"
assert-json-diff = "2.0"
serde = "1.0"
+mockito = "0.31"
mqtt_tests = { path = "../../tests/mqtt_tests" }
serde_json = "1.0"
serial_test = "0.5"
diff --git a/crates/core/tedge_mapper/src/az/mapper.rs b/crates/core/tedge_mapper/src/az/mapper.rs
index 0d998eff..7f608f08 100644
--- a/crates/core/tedge_mapper/src/az/mapper.rs
+++ b/crates/core/tedge_mapper/src/az/mapper.rs
@@ -1,3 +1,5 @@
+use std::path::Path;
+
use crate::{
az::converter::AzureConverter,
core::{component::TEdgeComponent, mapper::create_mapper, size_threshold::SizeThreshold},
@@ -26,12 +28,13 @@ impl TEdgeComponent for AzureMapper {
AZURE_MAPPER_NAME
}
- async fn init(&self) -> Result<(), anyhow::Error> {
+ async fn init(&self, cfg_dir: &Path) -> Result<(), anyhow::Error> {
info!("Initialize tedge mapper az");
+ let config_dir = cfg_dir.display().to_string();
create_directory_with_user_group(
- "/etc/tedge/operations/az",
- "tedge-mapper",
- "tedge-mapper",
+ &format!("{config_dir}/operations/az"),
+ "tedge",
+ "tedge",
0o775,
)?;
@@ -39,7 +42,11 @@ impl TEdgeComponent for AzureMapper {
Ok(())
}
- async fn start(&self, tedge_config: TEdgeConfig) -> Result<(), anyhow::Error> {
+ async fn start(
+ &self,
+ tedge_config: TEdgeConfig,
+ _config_dir: &Path,
+ ) -> Result<(), anyhow::Error> {
let add_timestamp = tedge_config.query(AzureMapperTimestamp)?.is_set();
let mqtt_port = tedge_config.query(MqttPortSetting)?.into();
let mqtt_host = tedge_config.query(MqttBindAddressSetting)?.to_string();
diff --git a/crates/core/tedge_mapper/src/c8y/mapper.rs b/crates/core/tedge_mapper/src/c8y/mapper.rs
index cb9a4f93..3842b3a5 100644
--- a/crates/core/tedge_mapper/src/c8y/mapper.rs
+++ b/crates/core/tedge_mapper/src/c8y/mapper.rs
@@ -1,3 +1,5 @@
+use std::path::Path;
+
use crate::{
c8y::converter::CumulocityConverter,
core::{component::TEdgeComponent, mapper::create_mapper, size_threshold::SizeThreshold},
@@ -47,19 +49,21 @@ impl TEdgeComponent for CumulocityMapper {
CUMULOCITY_MAPPER_NAME
}
- async fn init(&self) -> Result<(), anyhow::Error> {
+ async fn init(&self, cfg_dir: &Path) -> Result<(), anyhow::Error> {
info!("Initialize tedge mapper c8y");
- create_directories()?;
- let operations = Operations::try_new("/etc/tedge/operations", "c8y")?;
+ let config_dir = cfg_dir.display().to_string();
+ create_directories(&config_dir)?;
+ let operations = Operations::try_new(&format!("{config_dir}/operations"), "c8y")?;
self.init_session(CumulocityMapper::subscriptions(&operations)?)
.await?;
Ok(())
}
- async fn start(&self, tedge_config: TEdgeConfig) -> Result<(), anyhow::Error> {
+ async fn start(&self, tedge_config: TEdgeConfig, cfg_dir: &Path) -> Result<(), anyhow::Error> {
let size_threshold = SizeThreshold(MQTT_MESSAGE_SIZE_THRESHOLD);
+ let config_dir = cfg_dir.display().to_string();
- let operations = Operations::try_new("/etc/tedge/operations", "c8y")?;
+ let operations = Operations::try_new(format!("{config_dir}/operations"), "c8y")?;
let mut http_proxy = JwtAuthHttpProxy::try_new(&tedge_config).await?;
http_proxy.init().await?;
let device_name = tedge_config.query(DeviceIdSetting)?;
@@ -87,24 +91,130 @@ impl TEdgeComponent for CumulocityMapper {
}
}
-fn create_directories() -> Result<(), anyhow::Error> {
+fn create_directories(config_dir: &str) -> Result<(), anyhow::Error> {
create_directory_with_user_group(
- "/etc/tedge/operations/c8y",
- "tedge-mapper",
- "tedge-mapper",
+ &format!("{config_dir}/operations/c8y"),
+ "tedge",
+ "tedge",
0o775,
)?;
create_file_with_user_group(
- "/etc/tedge/operations/c8y/c8y_SoftwareUpdate",
- "tedge-mapper",
- "tedge-mapper",
+ &format!("{config_dir}/operations/c8y/c8y_SoftwareUpdate"),
+ "tedge",
+ "tedge",
0o644,
)?;
create_file_with_user_group(
- "/etc/tedge/operations/c8y/c8y_Restart",
- "tedge-mapper",
- "tedge-mapper",
+ &format!("{config_dir}/operations/c8y/c8y_Restart"),
+ "tedge",
+ "tedge",
0o644,
)?;
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use c8y_api::http_proxy::MockC8yJwtTokenRetriever;
+ use c8y_smartrest::smartrest_deserializer::SmartRestJwtResponse;
+ use mockito::mock;
+ use mqtt_tests::{assert_received_all_expected, test_mqtt_broker};
+ use serde_json::json;
+ use std::time::Duration;