Skip to content

Commit

Permalink
Add tedge config plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Krzysztof Piotrowski <[email protected]>
  • Loading branch information
Ruadhri17 committed Sep 19, 2023
1 parent 5a05c68 commit d67ce56
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
"plugins/tedge_apt_plugin",
"plugins/tedge_configuration_plugin",
"plugins/tedge_configuration_plugin",
"plugins/tedge_configuration_plugin",
"plugins/tedge_dummy_plugin",
"plugins/tedge_log_plugin",
]
Expand Down Expand Up @@ -129,6 +130,7 @@ tedge_api = { path = "crates/core/tedge_api" }
tedge_config = { path = "crates/common/tedge_config" }
tedge_config_macros = { path = "crates/common/tedge_config_macros" }
tedge_config_macros-impl = { path = "crates/common/tedge_config_macros/impl" }
tedge_config_manager = { path = "crates/extensions/tedge_config_manager" }
tedge_downloader_ext = { path = "crates/extensions/tedge_downloader_ext" }
tedge_file_system_ext = { path = "crates/extensions/tedge_file_system_ext" }
tedge_health_ext = { path = "crates/extensions/tedge_health_ext" }
Expand Down
25 changes: 25 additions & 0 deletions plugins/tedge_configuration_plugin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "tedge-configuration-plugin"
description = "Thin-edge device configuration management"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }

[dependencies]
anyhow = { workspace = true }
clap = { workspace = true }
tedge_actors = { workspace = true }
tedge_config = { workspace = true }
tedge_config_manager = { workspace = true }
tedge_downloader_ext = { workspace = true }
tedge_file_system_ext = { workspace = true }
tedge_health_ext = { workspace = true }
tedge_http_ext = { workspace = true }
tedge_mqtt_ext = { workspace = true }
tedge_signal_ext = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
135 changes: 135 additions & 0 deletions plugins/tedge_configuration_plugin/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use clap::Parser;
use std::path::PathBuf;
use std::sync::Arc;
use tedge_actors::Runtime;
use tedge_config::system_services::get_log_level;
use tedge_config::system_services::set_log_level;
use tedge_config::TEdgeConfig;
use tedge_config::TEdgeConfigLocation;
use tedge_config::TEdgeConfigRepository;
use tedge_config::DEFAULT_TEDGE_CONFIG_PATH;
use tedge_config_manager::ConfigManagerBuilder;
use tedge_config_manager::ConfigManagerConfig;
use tedge_config_manager::ConfigManagerOptions;
use tedge_downloader_ext::DownloaderActor;
use tedge_file_system_ext::FsWatchActorBuilder;
use tedge_health_ext::HealthMonitorBuilder;
use tedge_http_ext::HttpActor;
use tedge_mqtt_ext::MqttActorBuilder;
use tedge_signal_ext::SignalActor;

const AFTER_HELP_TEXT: &str = r#"On start, `tedge-configuration-plugin` notifies of its
managed configuration files and sends this list via MQTT.
`tedge-configuration-plugin` subscribes to the topics for the commands `config_snapshot`
and `config_update`.
The thin-edge `CONFIG_DIR` is used:
* to find the `tedge.toml` where the following configs are defined:
** `mqtt.bind.address` and `mqtt.bind.port` to connect to the tedge MQTT broker
** `root.topic` and `device.topic`: for the MQTT topics to publish to and subscribe from
* to find/store the `tedge-configuration-plugin.toml`: the plugin configuration file"#;

const TEDGE_CONFIGURATION_PLUGIN: &str = "tedge-configuration-plugin";

#[derive(Debug, Parser, Clone)]
#[clap(
name = clap::crate_name!(),
version = clap::crate_version!(),
about = clap::crate_description!(),
after_help = AFTER_HELP_TEXT
)]
pub struct ConfigPluginOpt {
/// Turn-on the debug log level.
///
/// If off only reports ERROR, WARN, and INFO
/// If on also reports DEBUG
#[clap(long)]
pub debug: bool,

#[clap(long = "config-dir", default_value = DEFAULT_TEDGE_CONFIG_PATH)]
pub config_dir: PathBuf,

#[clap(long)]
mqtt_topic_root: Option<Arc<str>>,

#[clap(long)]
mqtt_device_topic_id: Option<Arc<str>>,
}

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let config_opt = ConfigPluginOpt::parse();

// Load tedge config from the provided location
let tedge_config_location = TEdgeConfigLocation::from_custom_root(&config_opt.config_dir);

let log_level = if config_opt.debug {
tracing::Level::DEBUG
} else {
get_log_level(
"tedge-configuration-plugin",
&tedge_config_location.tedge_config_root_path,
)?
};
set_log_level(log_level);

let tedge_config = TEdgeConfigRepository::new(tedge_config_location).load()?;

run(tedge_config, config_opt).await
}

async fn run(tedge_config: TEdgeConfig, cliopts: ConfigPluginOpt) -> Result<(), anyhow::Error> {
let runtime_events_logger = None;
let mut runtime = Runtime::try_new(runtime_events_logger).await?;

let mqtt_topic_root = cliopts
.mqtt_topic_root
.unwrap_or(tedge_config.mqtt.topic_root.clone().into());

let mqtt_device_topic_id = cliopts
.mqtt_device_topic_id
.unwrap_or(tedge_config.mqtt.device_topic_id.clone().into());

let mqtt_config = tedge_config.mqtt_config()?;
let mut mqtt_actor = MqttActorBuilder::new(mqtt_config.clone().with_session_name(format!(
"{TEDGE_CONFIGURATION_PLUGIN}#{mqtt_topic_root}/{mqtt_device_topic_id}",
)));

let mut fs_watch_actor = FsWatchActorBuilder::new();

let health_actor = HealthMonitorBuilder::new(TEDGE_CONFIGURATION_PLUGIN, &mut mqtt_actor);

let mut http_actor = HttpActor::new().builder();

let mut downloader_actor = DownloaderActor::new().builder();

// Instantiate config manager actor
let manager_config = ConfigManagerConfig::from_options(ConfigManagerOptions {
config_dir: cliopts.config_dir,
mqtt_device_topic_id,
mqtt_topic_root,
})?;

let config_actor = ConfigManagerBuilder::try_new(
manager_config,
&mut mqtt_actor,
&mut http_actor,
&mut fs_watch_actor,
&mut downloader_actor,
)?;

// Shutdown on SIGINT
let signal_actor = SignalActor::builder(&runtime.get_handle());

// Run the actors
runtime.spawn(mqtt_actor).await?;
runtime.spawn(http_actor).await?;
runtime.spawn(downloader_actor).await?;
runtime.spawn(fs_watch_actor).await?;
runtime.spawn(config_actor).await?;
runtime.spawn(signal_actor).await?;
runtime.spawn(health_actor).await?;

runtime.run_to_completion().await?;
Ok(())
}

0 comments on commit d67ce56

Please sign in to comment.