pub mod pb { pub mod shared { tonic::include_proto!("shared"); } pub mod daemon { tonic::include_proto!("deamon"); } } pub mod config { use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; use serde::{Deserialize, Serialize}; #[derive(Clone, Serialize, Deserialize, prost::Oneof)] pub enum FileContent { #[serde(rename = "path")] #[prost(string, tag = "2")] Path(String), #[serde(rename = "data")] #[prost(string, tag = "3")] Data(String), } impl Default for FileContent { fn default() -> Self { FileContent::Data("".to_string()) } } #[derive(Clone, Serialize, Deserialize, prost::Message)] pub struct FileEntry { #[prost(string, tag = "1")] pub path: String, #[prost(oneof = "FileContent", tags = "2, 3")] pub content: Option, } #[derive(Clone, Serialize, Deserialize, prost::Message)] pub struct EnvironmentEntry { #[prost(string, tag = "1")] pub name: String, #[prost(string, tag = "2")] pub value: String, } #[derive(Clone, Copy, Serialize, Deserialize, prost::Message)] pub struct RestartPolicy { #[prost(uint32, tag = "1")] pub max_retries: u32, #[prost(uint32, tag = "2")] pub delay_seconds: u32, #[prost(oneof = "RestartPolicyType", tags = "3, 4")] pub policy: Option, } #[derive(Clone, Copy, Serialize, Deserialize, prost::Oneof)] pub enum RestartPolicyType { #[prost(bool, tag = "3")] Always(bool), #[prost(bool, tag = "4")] OnNonZeroExit(bool), } impl Default for RestartPolicyType { fn default() -> Self { RestartPolicyType::Always(true) } } #[derive(Clone, Serialize, Deserialize, prost::Message)] pub struct ChildProcess { #[prost(string, tag = "1")] pub path: String, #[prost(string, repeated, tag = "2")] pub arguments: Vec, #[prost(message, optional, tag = "3")] pub restart: Option, } #[derive(Clone, Serialize, Deserialize, prost::Message)] pub struct Container { #[prost(string, optional, tag = "1")] pub package_url: Option, #[prost(string, tag = "2")] pub node: String, #[prost(message, optional, tag = "3")] pub resource: Option, } #[derive(Clone, Serialize, Deserialize, PartialEq, prost::Message)] pub struct Resource { #[prost(uint32, tag = "1")] pub memory_mb: u32, #[prost(uint32, tag = "2")] pub disk_mb: u32, #[prost(uint32, tag = "3")] pub vcpu: u32, #[prost(uint32, repeated, tag = "4")] pub port: Vec, } #[derive(Clone, Serialize, Deserialize, prost::Message)] pub struct Config { #[prost(message, repeated, tag = "1")] pub filesystem: Vec, #[prost(message, repeated, tag = "2")] pub environment: Vec, #[prost(message, repeated, tag = "3")] pub child_processes: Vec, #[prost(message, optional, tag = "4")] pub container: Option, } impl Config { pub fn from_path(path: &str) -> Result> { let config_str = std::fs::read_to_string(path)?; Ok(serde_yml::from_str(&config_str)?) } pub fn load_data(mut self) -> Result> { self.filesystem.iter_mut().for_each(|x| { if let Some(FileContent::Path(path)) = &x.content { let content = std::fs::read(path).expect("Unable to read file {path}"); let encoded = BASE64.encode(content); x.content = Some(FileContent::Data(encoded)); } }); Ok(self) } } }