OpenRC generator

This commit is contained in:
Maurice
2025-07-21 21:44:02 +02:00
commit da47934db9
6 changed files with 313 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
use std::fs;
use crate::service::ServiceConfig;
mod service;
pub fn generate_openrc(config: &ServiceConfig) {
let mut script = String::from("#!/sbin/openrc-run\n# !!! AUTO GENERATED - DO NOT EDIT !!!\n\n");
let wrap = |cmd: &str| {
if let Some(user) = config.user.as_ref() {
format!("\tsu -c \"{}\" {} ", cmd, user)
} else {
format!("\t{}", cmd)
}
};
// depend() {
script.push_str("depend() {\n\tneed sysfs cgroups; ");
if config.service.depend.len() > 0 {
script.push_str(&format!("\n\tuse {}; ", config.service.depend.join(" ")));
}
script.push_str("\n}\n\n");
// }
// start_pre()
script.push_str("start_pre() {\n");
script.push_str(&wrap(&format!("podman rm {} --ignore", config.service.name)));
script.push_str("\n}\n\n");
// }
// start()
script.push_str("start() {\n");
let mut arguments = vec![String::from("--restart unless-stopped"), format!("--name {}", config.service.name)];
if let Some(network) = &config.service.network {
arguments.push(format!("--network {}", network));
}
for secret in &config.secrets {
if let Some(target) = &secret.target {
arguments.push(format!("--secret {},target={}", &secret.key, target));
} else {
arguments.push(format!("--secret {}", &secret.key));
}
}
for (key, value) in &config.environment {
arguments.push(format!("--env {}={}", key, value));
}
for volume in &config.volumes {
arguments.push(format!("--volume {}:{}", &volume.volume, &volume.path));
}
arguments.push(config.service.image.clone());
script.push_str(&wrap(&format!("podman run -d {}", arguments.iter()
.enumerate()
.map(|(i, arg)| if i > 0 { format!("\t{}", arg) } else { arg.to_string() })
.collect::<Vec<_>>()
.join(" \\\n"))));
script.push_str("\n}\n\n");
// }
// stop()
script.push_str("stop() {\n");
script.push_str(&wrap(&format!("podman stop {} --ignore", config.service.name)));
script.push_str("\n}\n\n");
// }
println!("\n\n{}", script);
}
fn main() {
let file = fs::read_to_string("example.toml").unwrap();
let service: ServiceConfig = toml::from_str(&file).unwrap();
println!("{:?}", service);
generate_openrc(&service);
}
+50
View File
@@ -0,0 +1,50 @@
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct ServiceConfig {
pub service: Service,
// Optionally support simple or structured secrets list
#[serde(default)]
pub secrets: Vec<Secret>,
#[serde(default)]
pub environment: HashMap<String, String>,
#[serde(default)]
pub ports: Vec<PortMapping>,
#[serde(default)]
pub volumes: Vec<VolumeMapping>,
pub user: Option<String>
}
#[derive(Debug, Deserialize)]
pub struct Service {
pub name: String,
pub image: String,
pub network: Option<String>,
#[serde(default)]
pub depend: Vec<String>
}
#[derive(Debug, Deserialize)]
pub struct Secret {
pub key: String,
pub target: Option<String>
}
#[derive(Debug, Deserialize)]
pub struct PortMapping {
pub host: u16,
pub container: u16,
pub protocol: Option<String>
}
#[derive(Debug, Deserialize)]
pub struct VolumeMapping {
pub volume: String,
pub path: String
}