Expand description
§Service Manager
Rust library that provides an interface towards working with the following service management platforms:
sc.exefor use with Window Service (Windows)- Winsw (Windows)
- Launchd (MacOS)
- systemd (Linux)
- OpenRC (Linux)
- rc.d (FreeBSD)
Requires Rust 1.58.1 or higher!
§Installation
Add the following to your Cargo.toml:
[dependencies]
service-manager = "0.8"§Examples
§Generic service management
This crate provides a mechanism to detect and use the default service
management platform of the current operating system. Each ServiceManager
instance provides four key methods:
install- will install the service specified by a given contextuninstall- will uninstall the service specified by a given contextstart- will start an installed service specified by a given contextstop- will stop a running service specified by a given context
use service_manager::*;
use std::ffi::OsString;
use std::path::PathBuf;
// Create a label for our service
let label: ServiceLabel = "com.example.my-service".parse().unwrap();
// Get generic service by detecting what is available on the platform
let manager = <dyn ServiceManager>::native()
.expect("Failed to detect management platform");
// Install our service using the underlying service management platform
manager.install(ServiceInstallCtx {
label: label.clone(),
program: PathBuf::from("path/to/my-service-executable"),
args: vec![OsString::from("--some-arg")],
contents: None, // Optional String for system-specific service content.
username: None, // Optional String for alternative user to run service.
working_directory: None, // Optional String for the working directory for the service process.
environment: None, // Optional list of environment variables to supply the service process.
autostart: true, // Specify whether the service should automatically start upon OS reboot.
restart_policy: RestartPolicy::default(), // Restart on failure by default.
}).expect("Failed to install");
// Start our service using the underlying service management platform
manager.start(ServiceStartCtx {
label: label.clone()
}).expect("Failed to start");
// Stop our service using the underlying service management platform
manager.stop(ServiceStopCtx {
label: label.clone()
}).expect("Failed to stop");
// Uninstall our service using the underlying service management platform
manager.uninstall(ServiceUninstallCtx {
label: label.clone()
}).expect("Failed to stop");§User-level service management
By default, service management platforms will interact with system-level
services; however, some service management platforms like systemd and
launchd support user-level services. To interact with services at the
user level, you configure your manager using the generic
ServiceManager::set_level function.
use service_manager::*;
// Create a label for our service
let label: ServiceLabel = "com.example.my-service".parse().unwrap();
// Get generic service by detecting what is available on the platform
let mut manager = <dyn ServiceManager>::native()
.expect("Failed to detect management platform");
// Update our manager to work with user-level services
manager.set_level(ServiceLevel::User)
.expect("Service manager does not support user-level services");
// Continue operating as usual via install/uninstall/start/stop
// ...§Specific service manager configurations
There are times where you need more control over the configuration of a service tied to a specific platform. To that end, you can create the service manager explicitly and set configuration properties appropriately.
use service_manager::*;
use std::ffi::OsString;
use std::path::PathBuf;
// Create a label for our service
let label: ServiceLabel = "com.example.my-service".parse().unwrap();
// Instantiate a specific service manager
let mut manager = LaunchdServiceManager::system();
// Update an install configuration property where installing a service
// will NOT add the KeepAlive flag
manager.config.install.keep_alive = Some(false);
// Install our service using the explicit service manager
manager.install(ServiceInstallCtx {
label: label.clone(),
program: PathBuf::from("path/to/my-service-executable"),
args: vec![OsString::from("--some-arg")],
contents: None, // Optional String for system-specific service content.
username: None, // Optional String for alternative user to run service.
working_directory: None, // Optional String for the working directory for the service process.
environment: None, // Optional list of environment variables to supply the service process.
autostart: true, // Specify whether the service should automatically start upon OS reboot.
restart_policy: RestartPolicy::default(), // Restart on failure by default.
}).expect("Failed to install");§Configuring restart policies
The crate provides a cross-platform RestartPolicy enum that allows you to control
when and how services should be restarted. Different platforms support different levels
of granularity, and the implementation will use the closest approximation when an exact
match isn’t available.
If you need options specific to any given service manager, you should use that specific
service manager rather than the generic ServiceManager crate.
use service_manager::*;
use std::ffi::OsString;
use std::path::PathBuf;
let label: ServiceLabel = "com.example.my-service".parse().unwrap();
let manager = <dyn ServiceManager>::native()
.expect("Failed to detect management platform");
// Example 1: Never restart the service
manager.install(ServiceInstallCtx {
label: label.clone(),
program: PathBuf::from("path/to/my-service-executable"),
args: vec![OsString::from("--some-arg")],
contents: None,
username: None,
working_directory: None,
environment: None,
autostart: true,
restart_policy: RestartPolicy::Never,
}).expect("Failed to install");
// Example 2: Always restart regardless of exit status
manager.install(ServiceInstallCtx {
label: label.clone(),
program: PathBuf::from("path/to/my-service-executable"),
args: vec![OsString::from("--some-arg")],
contents: None,
username: None,
working_directory: None,
environment: None,
autostart: true,
restart_policy: RestartPolicy::Always { delay_secs: Some(10) },
}).expect("Failed to install");
// Example 3: Restart only on failure (non-zero exit)
manager.install(ServiceInstallCtx {
label: label.clone(),
program: PathBuf::from("path/to/my-service-executable"),
args: vec![OsString::from("--some-arg")],
contents: None,
username: None,
working_directory: None,
environment: None,
autostart: true,
restart_policy: RestartPolicy::OnFailure { delay_secs: Some(5) },
}).expect("Failed to install");Platform support:
- systemd (Linux): Supports all restart policies natively
- launchd (macOS): Only supports Never vs Always/OnFailure (uses KeepAlive boolean)
- WinSW (Windows): Supports all restart policies
- OpenRC/rc.d/sc.exe: Limited or no restart support; warnings logged for unsupported policies
§Running tests
For testing purposes, we use a separate crate called system-tests and
execute singular tests based on desired platform and level. From the root of
the repository, execute the following to run a systemd user test:
cargo test -p system-tests systemd_for_user -- --nocaptureSeparately, run a systemd system test using the following (notice using of
sudo -E to maintain permissions needed for system-level installation):
sudo -E cargo test -p system-tests systemd_for_system -- --nocapture§License
This project is licensed under either of
Apache License, Version 2.0, (LICENSE-APACHE or apache-license) MIT license (LICENSE-MIT or mit-license) at your option.
Structs§
- Launchd
Config - Configuration settings tied to launchd services
- Launchd
Install Config - Configuration settings tied to launchd services during installation
- Launchd
Service Manager - Implementation of
ServiceManagerfor MacOS’s Launchd - Open
RcConfig - Configuration settings tied to OpenRC services
- Open
RcService Manager - Implementation of
ServiceManagerfor Linux’s OpenRC - RcdConfig
- Configuration settings tied to rc.d services
- RcdService
Manager - Implementation of
ServiceManagerfor FreeBSD’s rc.d - ScConfig
- Configuration settings tied to sc.exe services
- ScInstall
Config - Configuration settings tied to sc.exe services during installation
- ScService
Manager - Implementation of
ServiceManagerfor Window Service leveragingsc.exe - Service
Install Ctx - Context provided to the install function of
ServiceManager - Service
Label - Label describing the service (e.g.
org.example.my_application - Service
Start Ctx - Context provided to the start function of
ServiceManager - Service
Status Ctx - Context provided to the status function of
ServiceManager - Service
Stop Ctx - Context provided to the stop function of
ServiceManager - Service
Uninstall Ctx - Context provided to the uninstall function of
ServiceManager - Systemd
Config - Configuration settings tied to systemd services
- Systemd
Install Config - Configuration settings tied to systemd services during installation
- Systemd
Service Manager - Implementation of
ServiceManagerfor Linux’s systemd - WinSw
Config - Service configuration
- WinSw
Install Config - WinSw
Options Config - WinSw
Service Manager - Service manager implementation
Enums§
- Restart
Policy - Represents the restart policy for a service.
- Service
Level - Represents whether a service is system-wide or user-level
- Service
Manager Kind - Represents the kind of service manager
- Service
Status - Represents the status of a service
- Systemd
Service Restart Type - Typed
Service Manager - Represents an implementation of a known
ServiceManager - WinSw
OnFailure Action - WinSw
Priority - WinSw
Start Type - Windows
Error Severity - Windows
Service Type - Windows
Start Type
Traits§
- Service
Manager - Interface for a service manager
Functions§
- native_
service_ manager - Attempts to select a native service manager for the current operating system1
- systemd_
global_ dir_ path - systemd_
user_ dir_ path