#![allow(clippy::format_push_string)]
use crate::deployment::contract::DeploymentContract;
#[must_use]
pub fn generate_compose_fragment(contract: &DeploymentContract) -> String {
let binary = contract.binary();
let mut out = String::with_capacity(512);
let env_prefix = contract.env_prefix.replace("__", "_");
out.push_str(&format!(
"# Generated by scalo deployment module\nservices:\n {}:\n",
contract.app_name
));
out.push_str(&format!(
" image: {}/{}:${{{env_prefix}_VERSION:-latest}}\n",
contract.image_registry, contract.app_name,
));
if !contract.depends_on.is_empty() {
out.push_str(" depends_on:\n");
for dep in &contract.depends_on {
out.push_str(&format!(
" {dep}:\n condition: service_healthy\n"
));
}
}
out.push_str(" ports:\n");
out.push_str(&format!(
" - \"{}:{}\"\n",
contract.metrics_port, contract.metrics_port
));
for p in &contract.extra_ports {
out.push_str(&format!(" - \"{}:{}\"\n", p.port, p.port));
}
out.push_str(" volumes:\n");
out.push_str(&format!(
" - ./config/{}:{}:ro\n",
contract.config_filename(),
contract.config_mount_path,
));
out.push_str(&format!(
" healthcheck:\n\
\x20 test: [\"CMD\", \"curl\", \"-sf\", \"http://localhost:{}{}\"]
interval: 10s\n\
\x20 timeout: 3s\n\
\x20 retries: 5\n",
contract.metrics_port, contract.health.liveness_path,
));
out.push_str(" deploy:\n");
out.push_str(" resources:\n");
out.push_str(" limits:\n");
out.push_str(&format!(
" cpus: \"${{{env_prefix}_CPU_LIMIT:-2}}\"\n"
));
out.push_str(&format!(
" memory: ${{{env_prefix}_MEM_LIMIT:-1G}}\n"
));
if !contract.entrypoint_args.is_empty() {
out.push_str(&format!(" command: [\"{binary}\""));
for arg in &contract.entrypoint_args {
out.push_str(&format!(", \"{arg}\""));
}
out.push_str("]\n");
}
out
}