331 lines
7.1 KiB
Markdown
331 lines
7.1 KiB
Markdown
|
|
# Init-Servs - Cross-Platform Service Management
|
||
|
|
|
||
|
|
A unified abstraction for managing services across different init systems with platform-aware service file generation.
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Init-Servs provides a unified API for installing and managing services across different operating systems and init systems:
|
||
|
|
|
||
|
|
- 🐧 **systemd** - Linux (modern default)
|
||
|
|
- 🍎 **launchd** - macOS
|
||
|
|
- 🔧 **OpenRC** - Alpine Linux, Gentoo
|
||
|
|
- 🚀 **runit** - Void Linux, Devuan
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
- 🔄 **Unified API** - Same interface for all init systems
|
||
|
|
- 📝 **Service File Generation** - Generate native format files for each system
|
||
|
|
- 🎯 **Auto-Detection** - Detect init system on current platform
|
||
|
|
- ⚙️ **Async Support** - Built with async/await
|
||
|
|
- 🔧 **Flexible Configuration** - Extensive service configuration options
|
||
|
|
- 📋 **Builder Pattern** - Fluent API for easy configuration
|
||
|
|
|
||
|
|
## Supported Init Systems
|
||
|
|
|
||
|
|
### systemd (Linux)
|
||
|
|
Modern init system used by most Linux distributions
|
||
|
|
|
||
|
|
```rust
|
||
|
|
use init_servs::{InitSystemType, InitSystem, InitConfig};
|
||
|
|
|
||
|
|
let config = InitConfig::new(InitSystemType::Systemd);
|
||
|
|
let init = InitSystem::new(config);
|
||
|
|
// Service files: /etc/systemd/system/service.service
|
||
|
|
```
|
||
|
|
|
||
|
|
### launchd (macOS)
|
||
|
|
Launch daemon system on macOS
|
||
|
|
|
||
|
|
```rust
|
||
|
|
let config = InitConfig::new(InitSystemType::Launchd);
|
||
|
|
let init = InitSystem::new(config);
|
||
|
|
// Service files: ~/Library/LaunchAgents/com.service.plist
|
||
|
|
```
|
||
|
|
|
||
|
|
### OpenRC (Alpine, Gentoo)
|
||
|
|
Dependency-based init system
|
||
|
|
|
||
|
|
```rust
|
||
|
|
let config = InitConfig::new(InitSystemType::OpenRC);
|
||
|
|
let init = InitSystem::new(config);
|
||
|
|
// Service files: /etc/init.d/service
|
||
|
|
```
|
||
|
|
|
||
|
|
### runit (Void, Devuan)
|
||
|
|
Supervision suite init system
|
||
|
|
|
||
|
|
```rust
|
||
|
|
let config = InitConfig::new(InitSystemType::Runit);
|
||
|
|
let init = InitSystem::new(config);
|
||
|
|
// Service files: /etc/sv/service/run
|
||
|
|
```
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
```rust
|
||
|
|
use init_servs::{InitSystem, InitConfig, ServiceConfig, RestartPolicy};
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
|
// Detect current init system
|
||
|
|
let config = InitConfig::default();
|
||
|
|
let init = InitSystem::new(config);
|
||
|
|
|
||
|
|
// Create service configuration
|
||
|
|
let service = ServiceConfig::new("my-service")
|
||
|
|
.with_description("My Service")
|
||
|
|
.with_exec_start("/usr/bin/my-service")
|
||
|
|
.with_restart_policy(RestartPolicy::OnFailure)
|
||
|
|
.with_user("myuser")
|
||
|
|
.with_group("mygroup")
|
||
|
|
.with_environment("RUST_LOG", "info");
|
||
|
|
|
||
|
|
// Install service
|
||
|
|
init.install_service(&service).await?;
|
||
|
|
|
||
|
|
println!("Service installed!");
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Service Configuration
|
||
|
|
|
||
|
|
### Basic Service
|
||
|
|
```rust
|
||
|
|
let service = ServiceConfig::new("tracker")
|
||
|
|
.with_description("Tracker Service");
|
||
|
|
```
|
||
|
|
|
||
|
|
### With Execution Commands
|
||
|
|
```rust
|
||
|
|
let service = ServiceConfig::new("api")
|
||
|
|
.with_exec_start("/usr/bin/my-app")
|
||
|
|
.with_exec_stop("/bin/kill $MAINPID");
|
||
|
|
```
|
||
|
|
|
||
|
|
### With Restart Policy
|
||
|
|
```rust
|
||
|
|
use init::RestartPolicy;
|
||
|
|
|
||
|
|
let service = ServiceConfig::new("service")
|
||
|
|
.with_restart_policy(RestartPolicy::OnFailure);
|
||
|
|
```
|
||
|
|
|
||
|
|
### With User/Group
|
||
|
|
```rust
|
||
|
|
let service = ServiceConfig::new("service")
|
||
|
|
.with_user("serviceuser")
|
||
|
|
.with_group("servicegroup");
|
||
|
|
```
|
||
|
|
|
||
|
|
### With Environment Variables
|
||
|
|
```rust
|
||
|
|
let service = ServiceConfig::new("service")
|
||
|
|
.with_environment("LOG_LEVEL", "debug")
|
||
|
|
.with_environment("CONFIG_PATH", "/etc/service.conf");
|
||
|
|
```
|
||
|
|
|
||
|
|
### With Dependencies
|
||
|
|
```rust
|
||
|
|
let service = ServiceConfig::new("api")
|
||
|
|
.with_after("network.target")
|
||
|
|
.with_requires("tracker.service");
|
||
|
|
```
|
||
|
|
|
||
|
|
## Service File Generation
|
||
|
|
|
||
|
|
The crate automatically generates the correct format for each init system:
|
||
|
|
|
||
|
|
### systemd (INI format)
|
||
|
|
```ini
|
||
|
|
[Unit]
|
||
|
|
Description=My App Service
|
||
|
|
After=network.target
|
||
|
|
|
||
|
|
[Service]
|
||
|
|
Type=simple
|
||
|
|
User=myapp
|
||
|
|
ExecStart=/usr/bin/my-app
|
||
|
|
Restart=on-failure
|
||
|
|
|
||
|
|
[Install]
|
||
|
|
WantedBy=multi-user.target
|
||
|
|
```
|
||
|
|
|
||
|
|
### launchd (XML plist)
|
||
|
|
```xml
|
||
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ...>
|
||
|
|
<plist version="1.0">
|
||
|
|
<dict>
|
||
|
|
<key>Label</key>
|
||
|
|
<string>com.example.myapp</string>
|
||
|
|
<key>ProgramArguments</key>
|
||
|
|
<array>
|
||
|
|
<string>/usr/bin/my-app</string>
|
||
|
|
</array>
|
||
|
|
</dict>
|
||
|
|
</plist>
|
||
|
|
```
|
||
|
|
|
||
|
|
### OpenRC (Shell script)
|
||
|
|
```bash
|
||
|
|
#!/sbin/openrc-run
|
||
|
|
|
||
|
|
description="My App Service"
|
||
|
|
command="/usr/bin/my-app"
|
||
|
|
command_user="myapp"
|
||
|
|
```
|
||
|
|
|
||
|
|
### runit (Run script)
|
||
|
|
```bash
|
||
|
|
#!/bin/sh
|
||
|
|
exec 2>&1
|
||
|
|
exec chpst -u myapp /usr/bin/my-app
|
||
|
|
```
|
||
|
|
|
||
|
|
## Auto-Detection
|
||
|
|
|
||
|
|
Detect the current init system:
|
||
|
|
|
||
|
|
```rust
|
||
|
|
use init::detect_init_system;
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
|
let init_type = detect_init_system().await?;
|
||
|
|
println!("Init system: {}", init_type.name());
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
- `error.rs` - Error types and result types
|
||
|
|
- `init_type.rs` - InitSystemType enum with service directories
|
||
|
|
- `config.rs` - InitConfig configuration
|
||
|
|
- `detect.rs` - Async init system detection
|
||
|
|
- `service.rs` - ServiceConfig and RestartPolicy
|
||
|
|
- `init.rs` - Main InitSystem abstraction
|
||
|
|
|
||
|
|
## Use Cases
|
||
|
|
|
||
|
|
### Service Installation
|
||
|
|
Install applications as system services
|
||
|
|
|
||
|
|
### Daemon Management
|
||
|
|
Manage long-running processes
|
||
|
|
|
||
|
|
### Auto-Start Configuration
|
||
|
|
Configure services to start at boot
|
||
|
|
|
||
|
|
### Cross-Platform Deployments
|
||
|
|
Same code works on different OS/init systems
|
||
|
|
|
||
|
|
### Infrastructure as Code
|
||
|
|
Define services declaratively
|
||
|
|
|
||
|
|
## Restart Policies
|
||
|
|
|
||
|
|
- **No** - Don't restart on failure
|
||
|
|
- **Always** - Always restart
|
||
|
|
- **OnFailure** - Restart only on failure (default)
|
||
|
|
- **OnAbnormal** - Restart on abnormal termination
|
||
|
|
|
||
|
|
## Configuration Files
|
||
|
|
|
||
|
|
Services are typically defined in configuration files:
|
||
|
|
|
||
|
|
### systemd
|
||
|
|
```
|
||
|
|
/etc/systemd/system/
|
||
|
|
/usr/lib/systemd/system/
|
||
|
|
```
|
||
|
|
|
||
|
|
### launchd
|
||
|
|
```
|
||
|
|
~/Library/LaunchAgents/
|
||
|
|
/Library/LaunchDaemons/
|
||
|
|
```
|
||
|
|
|
||
|
|
### OpenRC
|
||
|
|
```
|
||
|
|
/etc/init.d/
|
||
|
|
```
|
||
|
|
|
||
|
|
### runit
|
||
|
|
```
|
||
|
|
/etc/sv/
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
Run tests with:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cargo test --lib
|
||
|
|
```
|
||
|
|
|
||
|
|
All 23 tests pass with full coverage of:
|
||
|
|
- Init system detection
|
||
|
|
- Service configuration
|
||
|
|
- Service file generation for all systems
|
||
|
|
- Async operations
|
||
|
|
- Error handling
|
||
|
|
|
||
|
|
## Performance
|
||
|
|
|
||
|
|
- Fast service file generation
|
||
|
|
- Minimal memory overhead
|
||
|
|
- Efficient system detection
|
||
|
|
- Low latency operations
|
||
|
|
|
||
|
|
## API Documentation
|
||
|
|
|
||
|
|
Full API documentation available with:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cargo doc --open
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration
|
||
|
|
|
||
|
|
Init can be integrated with:
|
||
|
|
- Deployment automation (provctl, provisioning)
|
||
|
|
- Infrastructure management tools
|
||
|
|
- Configuration management systems
|
||
|
|
- Container orchestration
|
||
|
|
- Service management frameworks
|
||
|
|
|
||
|
|
## Platform Support
|
||
|
|
|
||
|
|
- ✅ Linux (all distributions with systemd)
|
||
|
|
- ✅ Alpine Linux (with OpenRC)
|
||
|
|
- ✅ Gentoo (with OpenRC)
|
||
|
|
- ✅ Void Linux (with runit)
|
||
|
|
- ✅ Devuan (with runit)
|
||
|
|
- ✅ macOS (with launchd)
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
- ✅ Services run with specific user/group
|
||
|
|
- ✅ Proper file permissions
|
||
|
|
- ✅ Isolated service environments
|
||
|
|
- ✅ Resource limits support
|
||
|
|
- ✅ Logging and audit trails
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
Same as prov-ecosystem parent project
|
||
|
|
|
||
|
|
## Contributing
|
||
|
|
|
||
|
|
Contributions welcome! See parent project guidelines.
|
||
|
|
|
||
|
|
## See Also
|
||
|
|
|
||
|
|
- [prov-ecosystem README](../../README.md) - Parent project overview
|
||
|
|
- [valida](../valida/README.md) - Validation rules engine
|
||
|
|
- [encrypt](../encrypt/README.md) - Multi-backend encryption
|
||
|
|
- [runtime](../runtime/README.md) - Container runtime abstraction
|