Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add profile support to the tedge cli and fix mosquitto configuration #3262

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
14 changes: 14 additions & 0 deletions configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=tedge-mapper-aws checks Thin Edge JSON measurements and forwards to AWS IoT Hub.
After=syslog.target network.target mosquitto.service

[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper aws@%i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5

[Install]
WantedBy=multi-user.target
14 changes: 14 additions & 0 deletions configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=tedge-mapper-az checks Thin Edge JSON measurements and forwards to Azure IoT Hub.
After=syslog.target network.target mosquitto.service

[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper az@%i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5

[Install]
WantedBy=multi-user.target
14 changes: 14 additions & 0 deletions configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=tedge-mapper-c8y converts Thin Edge JSON measurements to Cumulocity JSON format.
After=syslog.target network.target mosquitto.service

[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper c8y@%i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5

[Install]
WantedBy=multi-user.target
33 changes: 33 additions & 0 deletions configuration/package_manifests/nfpm.tedge-mapper.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ contents:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: deb
- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/tedge-mapper-az.service
dst: /lib/systemd/system/tedge-mapper-az.service
file_info:
Expand All @@ -55,6 +66,17 @@ contents:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: deb
- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/tedge-mapper-c8y.service
dst: /lib/systemd/system/tedge-mapper-c8y.service
file_info:
Expand All @@ -66,6 +88,17 @@ contents:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: deb
- src: ./configuration/init/systemd/[email protected]
dst: /lib/systemd/system/[email protected]
file_info:
mode: 0644
packager: rpm

- src: ./configuration/init/systemd/tedge-mapper-collectd.service
dst: /lib/systemd/system/tedge-mapper-collectd.service
file_info:
Expand Down
12 changes: 6 additions & 6 deletions crates/common/tedge_config/src/system_services/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ pub trait SystemServiceManager: Debug {
fn check_operational(&self) -> Result<(), SystemServiceError>;

/// Stops the specified system service.
fn stop_service(&self, service: SystemService) -> Result<(), SystemServiceError>;
fn stop_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError>;

/// Starts the specified system service.
fn start_service(&self, service: SystemService) -> Result<(), SystemServiceError>;
fn start_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError>;

/// Restarts the specified system service.
fn restart_service(&self, service: SystemService) -> Result<(), SystemServiceError>;
fn restart_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError>;

/// Enables the specified system service. This does not start the service, unless you reboot.
fn enable_service(&self, service: SystemService) -> Result<(), SystemServiceError>;
fn enable_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError>;

/// Disables the specified system service. This does not stop the service.
fn disable_service(&self, service: SystemService) -> Result<(), SystemServiceError>;
fn disable_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError>;

/// Queries status of the specified system service. "Running" here means the same as "active".
fn is_service_running(&self, service: SystemService) -> Result<bool, SystemServiceError>;
fn is_service_running(&self, service: SystemService<'_>) -> Result<bool, SystemServiceError>;
}

pub fn service_manager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ use anyhow::Context as _;

/// Extension trait for `SystemServiceManager`.
pub trait SystemServiceManagerExt {
fn start_and_enable_service(&self, service: SystemService) -> anyhow::Result<()>;
fn stop_and_disable_service(&self, service: SystemService) -> anyhow::Result<()>;
fn start_and_enable_service(&self, service: SystemService<'_>) -> anyhow::Result<()>;
fn stop_and_disable_service(&self, service: SystemService<'_>) -> anyhow::Result<()>;
}

impl SystemServiceManagerExt for &dyn SystemServiceManager {
fn start_and_enable_service(&self, service: SystemService) -> anyhow::Result<()> {
fn start_and_enable_service(&self, service: SystemService<'_>) -> anyhow::Result<()> {
self.start_service(service)
.with_context(|| format!("Failed to start {service}"))?;
self.enable_service(service)
.with_context(|| format!("Failed to enable {service}"))
}

fn stop_and_disable_service(&self, service: SystemService) -> anyhow::Result<()> {
fn stop_and_disable_service(&self, service: SystemService<'_>) -> anyhow::Result<()> {
self.stop_service(service)
.with_context(|| format!("Failed to stop {service}"))?;
self.disable_service(service)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,37 +47,37 @@ impl SystemServiceManager for GeneralServiceManager {
}
}

fn stop_service(&self, service: SystemService) -> Result<(), SystemServiceError> {
fn stop_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError> {
let exec_command = ServiceCommand::Stop(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())?
.must_succeed()
}

fn start_service(&self, service: SystemService) -> Result<(), SystemServiceError> {
fn start_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError> {
let exec_command = ServiceCommand::Start(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())?
.must_succeed()
}

fn restart_service(&self, service: SystemService) -> Result<(), SystemServiceError> {
fn restart_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError> {
let exec_command = ServiceCommand::Restart(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())?
.must_succeed()
}

fn enable_service(&self, service: SystemService) -> Result<(), SystemServiceError> {
fn enable_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError> {
let exec_command = ServiceCommand::Enable(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())?
.must_succeed()
}

fn disable_service(&self, service: SystemService) -> Result<(), SystemServiceError> {
fn disable_service(&self, service: SystemService<'_>) -> Result<(), SystemServiceError> {
let exec_command = ServiceCommand::Disable(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())?
.must_succeed()
}

fn is_service_running(&self, service: SystemService) -> Result<bool, SystemServiceError> {
fn is_service_running(&self, service: SystemService<'_>) -> Result<bool, SystemServiceError> {
let exec_command = ServiceCommand::IsActive(service).try_exec_command(self)?;
self.run_service_command_as_root(exec_command, self.config_path.as_str())
.map(|status| status.success())
Expand Down Expand Up @@ -109,11 +109,11 @@ impl ExecCommand {
}
}

fn try_new_with_placeholder(
fn try_new_with_placeholder<'a>(
config: Vec<String>,
service_cmd: ServiceCommand,
service_cmd: ServiceCommand<'a>,
config_path: Utf8PathBuf,
service: SystemService,
service: SystemService<'a>,
) -> Result<Self, SystemServiceError> {
let replaced = replace_with_service_name(&config, service_cmd, &config_path, service)?;
Self::try_new(replaced, service_cmd, config_path)
Expand Down Expand Up @@ -141,11 +141,11 @@ impl fmt::Display for ExecCommand {
}
}

fn replace_with_service_name(
fn replace_with_service_name<'a>(
input_args: &[String],
service_cmd: ServiceCommand,
service_cmd: ServiceCommand<'a>,
config_path: impl Into<Utf8PathBuf>,
service: SystemService,
service: SystemService<'a>,
) -> Result<Vec<String>, SystemServiceError> {
if !input_args.iter().any(|s| s == "{}") {
return Err(SystemServiceError::SystemConfigInvalidSyntax {
Expand All @@ -158,27 +158,27 @@ fn replace_with_service_name(
let mut args = input_args.to_owned();
for item in args.iter_mut() {
if item == "{}" {
*item = SystemService::as_service_name(service).to_string();
*item = service.to_string();
}
}

Ok(args)
}

#[derive(Debug, Copy, Clone)]
enum ServiceCommand {
enum ServiceCommand<'a> {
CheckManager,
Stop(SystemService),
Start(SystemService),
Restart(SystemService),
Enable(SystemService),
Disable(SystemService),
IsActive(SystemService),
Stop(SystemService<'a>),
Start(SystemService<'a>),
Restart(SystemService<'a>),
Enable(SystemService<'a>),
Disable(SystemService<'a>),
IsActive(SystemService<'a>),
}

impl ServiceCommand {
impl<'a> ServiceCommand<'a> {
fn try_exec_command(
&self,
self,
service_manager: &GeneralServiceManager,
) -> Result<ExecCommand, SystemServiceError> {
let config_path = service_manager.config_path.clone();
Expand All @@ -190,45 +190,45 @@ impl ServiceCommand {
),
Self::Stop(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.stop.clone(),
ServiceCommand::Stop(*service),
ServiceCommand::Stop(service),
config_path,
*service,
service,
),
Self::Restart(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.restart.clone(),
ServiceCommand::Restart(*service),
ServiceCommand::Restart(service),
config_path,
*service,
service,
),
Self::Start(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.start.clone(),
ServiceCommand::Enable(*service),
ServiceCommand::Enable(service),
config_path,
*service,
service,
),
Self::Enable(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.enable.clone(),
ServiceCommand::Enable(*service),
ServiceCommand::Enable(service),
config_path,
*service,
service,
),
Self::Disable(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.disable.clone(),
ServiceCommand::Disable(*service),
ServiceCommand::Disable(service),
config_path,
*service,
service,
),
Self::IsActive(service) => ExecCommand::try_new_with_placeholder(
service_manager.init_config.is_active.clone(),
ServiceCommand::IsActive(*service),
ServiceCommand::IsActive(service),
config_path,
*service,
service,
),
}
}
}

impl fmt::Display for ServiceCommand {
impl fmt::Display for ServiceCommand<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::CheckManager => write!(f, "is_available"),
Expand Down
29 changes: 21 additions & 8 deletions crates/common/tedge_config/src/system_services/services.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
use std::fmt;

use tedge_config_macros::ProfileName;

/// An enumeration of all supported system services.
#[derive(Debug, Copy, Clone, strum_macros::Display, strum_macros::IntoStaticStr)]
pub enum SystemService {
#[derive(Debug, Copy, Clone, strum_macros::IntoStaticStr)]
pub enum SystemService<'a> {
#[strum(serialize = "mosquitto")]
/// Mosquitto broker
Mosquitto,
#[strum(serialize = "tedge-mapper-az")]
/// Azure TEdge mapper
TEdgeMapperAz,
TEdgeMapperAz(Option<&'a ProfileName>),
#[strum(serialize = "tedge-mapper-aws")]
/// AWS TEdge mapper
TEdgeMapperAws,
TEdgeMapperAws(Option<&'a ProfileName>),
#[strum(serialize = "tedge-mapper-c8y")]
/// Cumulocity TEdge mapper
TEdgeMapperC8y,
TEdgeMapperC8y(Option<&'a ProfileName>),
#[strum(serialize = "tedge-agent")]
/// TEdge SM agent
TEdgeSMAgent,
}

impl SystemService {
pub(crate) fn as_service_name(service: SystemService) -> &'static str {
service.into()
impl fmt::Display for SystemService<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Mosquitto => write!(f, "mosquitto"),
Self::TEdgeMapperAz(None) => write!(f, "tedge-mapper-az"),
Self::TEdgeMapperAz(Some(profile)) => write!(f, "tedge-mapper-az@{profile}"),
Self::TEdgeMapperAws(None) => write!(f, "tedge-mapper-aws"),
Self::TEdgeMapperAws(Some(profile)) => write!(f, "tedge-mapper-aws@{profile}"),
Self::TEdgeMapperC8y(None) => write!(f, "tedge-mapper-c8y"),
Self::TEdgeMapperC8y(Some(profile)) => write!(f, "tedge-mapper-c8y@{profile}"),
Self::TEdgeSMAgent => write!(f, "tedge-agent"),
}
}
}
Loading
Loading