From 401ab5f0166871a72d568768938a03c0141c01d7 Mon Sep 17 00:00:00 2001 From: Maurice Date: Wed, 23 Jul 2025 18:21:13 +0200 Subject: [PATCH] Added health etc --- example.toml | 18 +++++++++++++++++- src/main.rs | 46 +++++++++++++++++++++++++++++++++++++++++++--- src/service.rs | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/example.toml b/example.toml index 9761ef2..b47d38c 100644 --- a/example.toml +++ b/example.toml @@ -5,6 +5,16 @@ name = "nc-test-api" image = "numberchords-api" network = "nc-network" depend = ["nc-test-database"] +restart = "unless-stopped" +detach = true +hostname = "nc-test-api-hn" + +[service.healthcheck] +cmd = "pg_isready --dbname=$DB_DATABASE_NAME --username=$DB_USERNAME || exit 1" +interval = "5s" +start_period = "30s" +retries = 3 +on_failure = "none" [environment] ASPNETCORE_ENVIRONMENT = "Test" @@ -28,4 +38,10 @@ container = 2222 [[volumes]] volume = "test" -path = "/data/test" \ No newline at end of file +path = "/data/test" + +[[mounts]] +typ = "bind" +source = "/etc/hosts" +target = "/etc/hosts" +read_only = true \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 41b819b..99af376 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,11 +31,27 @@ pub fn generate_openrc(config: &ServiceConfig) { // start() script.push_str("start() {\n"); - let mut arguments = vec![String::from("--restart unless-stopped"), format!("--name {}", config.service.name)]; + let mut arguments = vec![ + format!("--restart {}", config.service.restart.as_deref().unwrap_or("unless-stopped")), + format!("--name {}", config.service.name) + ]; + + if let Some(hostname) = &config.service.hostname { + arguments.push(format!("--hostname {}", hostname)); + } + + if config.service.detach.unwrap_or(true) { + arguments.push("--detach".to_string()); + } + if let Some(network) = &config.service.network { arguments.push(format!("--network {}", network)); } + for capability in &config.capabilities { + arguments.push(format!("--cap-add {}", capability)); + } + for secret in &config.secrets { if let Some(target) = &secret.target { arguments.push(format!("--secret {},target={}", &secret.key, target)); @@ -45,16 +61,40 @@ pub fn generate_openrc(config: &ServiceConfig) { } for (key, value) in &config.environment { - arguments.push(format!("--env {}={}", key, value)); + arguments.push(format!("--env {}='{}'", key, value)); } for volume in &config.volumes { arguments.push(format!("--volume {}:{}", &volume.volume, &volume.path)); } + for mount in &config.mounts { + let mut mount_str = format!("--mount type={},source={},target={}", mount.typ, mount.source, mount.target); + if mount.read_only.unwrap_or(false) { + mount_str.push_str(",readonly"); + } + arguments.push(mount_str); + } + + if let Some(healthcheck) = &config.service.healthcheck { + arguments.push(format!("--health-cmd '{}'", healthcheck.cmd)); + if let Some(interval) = &healthcheck.interval { + arguments.push(format!("--health-interval {}", interval)); + } + if let Some(start_period) = &healthcheck.start_period { + arguments.push(format!("--health-start-period {}", start_period)); + } + if let Some(retries) = healthcheck.retries { + arguments.push(format!("--health-retries {}", retries)); + } + if let Some(on_failure) = &healthcheck.on_failure { + arguments.push(format!("--health-on-failure {}", on_failure)); + } + } + arguments.push(config.service.image.clone()); - script.push_str(&wrap(&format!("podman run -d {}", arguments.iter() + script.push_str(&wrap(&format!("podman run {}", arguments.iter() .enumerate() .map(|(i, arg)| if i > 0 { format!("\t{}", arg) } else { arg.to_string() }) .collect::>() diff --git a/src/service.rs b/src/service.rs index f7bbbcb..f18c1b9 100644 --- a/src/service.rs +++ b/src/service.rs @@ -18,16 +18,27 @@ pub struct ServiceConfig { #[serde(default)] pub volumes: Vec, - pub user: Option + #[serde(default)] + pub mounts: Vec, + + pub user: Option, + + #[serde(default)] + pub capabilities: Vec, } #[derive(Debug, Deserialize)] pub struct Service { pub name: String, + pub hostname: Option, pub image: String, pub network: Option, + pub restart: Option, + pub detach: Option, + pub healthcheck: Option, + #[serde(default)] - pub depend: Vec + pub depend: Vec, } #[derive(Debug, Deserialize)] @@ -47,4 +58,22 @@ pub struct PortMapping { pub struct VolumeMapping { pub volume: String, pub path: String +} + +#[derive(Debug, Deserialize)] +pub struct MountMapping { + pub typ: String, // e.g., "bind", "volume" + pub source: String, + pub target: String, + pub read_only: Option +} + +// --health-cmd /healthcheck --health-on-failure=none --health-retries=1 +#[derive(Debug, Deserialize)] +pub struct HealthCheck { + pub cmd: String, + pub interval: Option, + pub start_period: Option, + pub retries: Option, + pub on_failure: Option, } \ No newline at end of file