hyperi_rustlib/deployment/generate/
manifest.rs1use crate::deployment::contract::{DeploymentContract, ImageProfile};
10
11pub fn generate_container_manifest(contract: &DeploymentContract) -> Result<String, String> {
24 let binary = contract.binary();
25
26 let apt_repos: Vec<serde_json::Value> = contract
27 .native_deps
28 .apt_repos
29 .iter()
30 .map(|r| {
31 serde_json::json!({
32 "key_url": r.key_url,
33 "keyring": r.keyring,
34 "url": r.url,
35 "codename": r.codename,
36 "packages": r.packages,
37 })
38 })
39 .collect();
40
41 let mut expose_ports: Vec<u16> = vec![contract.metrics_port];
42 expose_ports.extend(contract.extra_ports.iter().map(|p| p.port));
43
44 let profile_str = match contract.image_profile {
45 ImageProfile::Production => "production",
46 ImageProfile::Development => "development",
47 };
48
49 let title = if contract.oci_labels.title.is_empty() {
50 &contract.app_name
51 } else {
52 &contract.oci_labels.title
53 };
54
55 let manifest = serde_json::json!({
56 "schema_version": "1",
57 "app_name": contract.app_name,
58 "binary_name": binary,
59 "base_image": contract.base_image,
60 "image_registry": contract.image_registry,
61 "image_profile": profile_str,
62 "runtime_packages": {
63 "apt_repos": apt_repos,
64 "apt_packages": contract.native_deps.apt_packages,
65 },
66 "expose_ports": expose_ports,
67 "healthcheck": {
68 "path": contract.health.liveness_path,
69 "port": contract.metrics_port,
70 "interval": "30s",
71 "timeout": "3s",
72 "start_period": "5s",
73 "retries": 3,
74 },
75 "entrypoint": [binary],
76 "cmd": contract.entrypoint_args,
77 "user": "appuser",
78 "uid": 1000,
79 "labels": {
80 "io.hyperi.profile": profile_str,
81 "io.hyperi.app": contract.app_name,
82 "io.hyperi.metrics_port": contract.metrics_port.to_string(),
83 "org.opencontainers.image.title": title,
84 "org.opencontainers.image.description": contract.oci_labels.description,
85 "org.opencontainers.image.vendor": contract.oci_labels.vendor,
86 "org.opencontainers.image.licenses": contract.oci_labels.licenses,
87 },
88 });
89
90 serde_json::to_string_pretty(&manifest)
91 .map_err(|e| format!("container manifest JSON failed: {e}"))
92}