Compare commits

..

21 Commits

Author SHA1 Message Date
099f0a0488
Add app_name field to AppContract and NewAppReq messages; update AppDeployConfig struct 2025-03-14 09:44:03 +00:00
d6ffc0d4cb
Add ListAllAppContracts RPC to BrainAppCli for super admin commands 2025-03-12 20:11:47 +00:00
a9dcfbe9fe
Add AppNodeFilters and AppNodeListResp messages; implement ListAppNodes and GetOneAppNode RPCs in BrainAppCli 2025-03-12 20:04:15 +00:00
8230e1f831
Rename CreateApp RPC to DeployApp in BrainAppCli and add new fields to AppDeployConfig for hours and private_package 2025-03-12 20:57:26 +05:30
a734b392b7
rename price_per_unit to node_unit_price in AppDeployConfig and update conversion implementations 2025-03-11 17:46:26 +05:30
dc1e2dd0cd
Minor change
new price field in register app node and rename operator_pubkey to operator_wallet
2025-03-08 23:54:48 +00:00
b8f37dec18
Add hratls_pubkey and public_package_mr_enclave fields to NewAppReq, AppDeployConfig and AppContract 2025-03-06 17:38:36 +05:30
aefd292807
Add public_package field to NewAppReq and AppDeployConfig with default serde handling 2025-03-06 16:32:06 +05:30
9ba3bc3186
Add hratls_pubkey to NewAppReq and AppDeployConfig; adjust field indices 2025-03-06 00:59:58 +00:00
a6baa4059d
refactor AppNodeResources fields for clarity and consistency 2025-02-21 10:42:14 +00:00
2507356cae
minor change 2025-02-20 01:37:01 +05:30
54abe74d42
admin pubkey in DelAppReq for authendicate and serde default for AppDeployConfig fields 2025-02-18 20:56:03 +05:30
99c3c83ed3
Rename owner_wallet to admin_pubkey in AppContract and related structures; add price_per_unit and locked_nano fields 2025-02-18 16:28:00 +05:30
e835424049
refactor error handling with thiserror in dtpm module 2025-02-18 13:59:14 +05:30
987bbfd8ec
minor fix
default for owner_wallet in AppDeployConfig
2025-02-17 12:43:04 +05:30
ee592c71d6
Refactor proto file structure to move brain and dtpm modules under sgx for better organization 2025-02-13 17:28:09 +05:30
f2bc29149e
Daemon authendication
Refactor DaemonMessageApp to use DaemonAuth for authentication and update related RPC method
2025-02-11 10:33:46 +00:00
606c0ad395
Rename admin_pubkey to owner_wallet in AppContract and related structures for clarity 2025-02-11 13:20:37 +05:30
65bfa113a4
Rename RegisterNode RPC to RegisterAppNode for consistency in BrainAppDaemon service 2025-02-10 19:03:49 +05:30
fce5788493
Implement From trait for DaemonMessageApp to facilitate conversions from String, NewAppRes, and AppNodeResources 2025-02-07 01:10:12 +05:30
df3a4631dd
Cleanup
Remove unused proto files and related references from the project
2025-02-06 14:57:50 +05:30
13 changed files with 166 additions and 541 deletions

53
Cargo.lock generated

@ -176,7 +176,8 @@ dependencies = [
"base64", "base64",
"prost", "prost",
"serde", "serde",
"serde_yml", "serde_yaml",
"thiserror",
"tonic", "tonic",
"tonic-build", "tonic-build",
] ]
@ -454,16 +455,6 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libyml"
version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
dependencies = [
"anyhow",
"version_check",
]
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.14" version = "0.4.14"
@ -758,9 +749,9 @@ checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]] [[package]]
name = "serde" name = "serde"
@ -783,18 +774,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "serde_yml" name = "serde_yaml"
version = "0.0.12" version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [ dependencies = [
"indexmap 2.7.0", "indexmap 2.7.0",
"itoa", "itoa",
"libyml",
"memchr",
"ryu", "ryu",
"serde", "serde",
"version_check", "unsafe-libyaml",
] ]
[[package]] [[package]]
@ -852,6 +841,26 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "thiserror"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.42.0" version = "1.42.0"
@ -1037,10 +1046,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]] [[package]]
name = "version_check" name = "unsafe-libyaml"
version = "0.9.5" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]] [[package]]
name = "want" name = "want"

@ -7,7 +7,8 @@ edition = "2021"
base64 = "0.22.1" base64 = "0.22.1"
prost = "0.13.4" prost = "0.13.4"
serde = { version = "1.0.216", features = ["derive"] } serde = { version = "1.0.216", features = ["derive"] }
serde_yml = "0.0.12" serde_yaml = "0.9.34"
thiserror = "2.0.11"
tonic = "0.12.3" tonic = "0.12.3"
[build-dependencies] [build-dependencies]

@ -3,12 +3,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.build_server(true) .build_server(true)
.protoc_arg("--experimental_allow_proto3_optional") .protoc_arg("--experimental_allow_proto3_optional")
.compile_protos( .compile_protos(
&[ &["proto/sgx/brain.proto", "proto/sgx/dtpm.proto"],
"proto/daemon.proto",
"proto/shared.proto",
"proto/brain.proto",
"proto/dtpm.proto",
],
&["proto"], &["proto"],
)?; )?;

@ -1,88 +0,0 @@
syntax = "proto3";
package deamon;
import "shared.proto";
message NewContainerRes {
string uuid = 1;
string status = 2;
string ip_address = 3;
repeated shared.MappedPort mapped_ports = 4;
string error = 5;
}
message ContainerInspectResp {
shared.Container containers = 1;
repeated shared.MappedPort mapped_ports = 2;
string crated_time = 3;
optional string ratls_pubkey = 4;
optional string mr_signer = 5;
optional string mr_enclave = 6;
string state = 7;
string disk_usage = 8;
}
message LogResp {
string std_out = 1;
string std_err = 2;
}
message ContainerFilters {
string admin_pubkey = 1;
optional string uuid= 2;
}
message ContainerListResp {
repeated shared.Container containers = 1;
}
message DeleteContainerRes {
string uuid = 1;
string status = 2;
}
message BrainMessage {
oneof Msg {
shared.Container new_container_req = 1;
ContainerFilters delete_container = 2;
ContainerFilters list_container = 3;
}
}
message DaemonMessage {
oneof Msg {
shared.Pubkey pubkey = 1;
NewContainerRes new_container_resp = 2;
}
}
// service DaemonService {
// rpc CreateContainer (shared.Container) returns (NewContainerRes);
// rpc DeleteContainer (ContainerFilters) returns (DeleteContainerRes);
// rpc ListContainers (ContainerFilters) returns (ContainerListResp);
// rpc InspectContainer (shared.UUID) returns (ContainerInspectResp);
// rpc ContainerLog (shared.UUID) returns (stream LogResp);
// }
service BrainSgxCli {
rpc CreateContainer (shared.Container) returns (NewContainerRes);
rpc DeleteContainer (ContainerFilters) returns (shared.Empty);
rpc ListContainers (ContainerFilters) returns (ContainerListResp);
// rpc InspectContainer (shared.UUID) returns (ContainerInspectResp);
// rpc ContainerLog (shared.UUID) returns (stream LogResp);
}
service BrainSgxDaemon {
rpc RegisterNode (shared.RegisterNodeReq) returns
(stream shared.ContainerContracts);
rpc BrainMessages (shared.Pubkey) returns (stream BrainMessage);
rpc DaemonMessages (stream DaemonMessage) returns (shared.Empty);
}

@ -12,12 +12,15 @@ message AppContract {
string node_pubkey = 4; string node_pubkey = 4;
string public_ipv4 = 5; string public_ipv4 = 5;
AppResource resource = 6; AppResource resource = 6;
repeated MappedPort exposed_ports = 7; repeated MappedPort mapped_ports = 7;
string created_at = 8; string created_at = 8;
string updated_at = 9; string updated_at = 9;
uint64 nano_per_minute = 10; uint64 nano_per_minute = 10;
uint64 locked_nano = 11; uint64 locked_nano = 11;
string collected_at = 12; string collected_at = 12;
string hratls_pubkey = 13;
optional bytes public_package_mr_enclave = 14;
string app_name = 15;
} }
message NewAppReq { message NewAppReq {
@ -26,6 +29,11 @@ message NewAppReq {
AppResource resource = 3; AppResource resource = 3;
string uuid = 4; string uuid = 4;
string admin_pubkey = 5; string admin_pubkey = 5;
uint64 price_per_unit = 6;
uint64 locked_nano = 7;
string hratls_pubkey = 8;
optional bytes public_package_mr_enclave = 9;
string app_name = 10;
} }
message AppResource { message AppResource {
@ -50,6 +58,7 @@ message MappedPort {
message DelAppReq { message DelAppReq {
string uuid= 1; string uuid= 1;
string admin_pubkey = 2;
} }
message ListAppContractsReq { message ListAppContractsReq {
@ -58,30 +67,57 @@ message ListAppContractsReq {
// string node_pubkey = 3; // string node_pubkey = 3;
} }
message AppNodeFilters {
uint32 vcpus = 1;
uint32 memory_mb = 2;
uint32 storage_mb = 3;
string country = 4;
string region = 5;
string city = 6;
string ip = 7;
string node_pubkey = 8;
}
message AppNodeListResp {
string operator = 1;
string node_pubkey = 2;
string country = 3;
string region = 4;
string city = 5;
string ip = 6; // required for latency test
uint64 price = 7; // nanoLP per unit per minute
repeated string reports = 8; // TODO: this will become an enum
}
service BrainAppCli { service BrainAppCli {
rpc CreateApp (NewAppReq) returns (NewAppRes); rpc DeployApp (NewAppReq) returns (NewAppRes);
rpc DeleteApp (DelAppReq) returns (Empty); rpc DeleteApp (DelAppReq) returns (Empty);
rpc ListAppContracts (ListAppContractsReq) returns (stream AppContract); rpc ListAppContracts (ListAppContractsReq) returns (stream AppContract);
rpc ListAppNodes (AppNodeFilters) returns (stream AppNodeListResp);
rpc GetOneAppNode (AppNodeFilters) returns (AppNodeListResp);
// super admin commands
rpc ListAllAppContracts (Empty) returns (stream AppContract);
} }
message RegisterAppNodeReq { message RegisterAppNodeReq {
string node_pubkey = 1; string node_pubkey = 1;
string owner_pubkey = 2; string operator_wallet = 2;
string main_ip = 3; string main_ip = 3;
string country = 4; string country = 4;
string region = 5; string region = 5;
string city = 6; string city = 6;
uint64 price = 7;
} }
message AppNodeResources { message AppNodeResources {
string node_pubkey = 1; string node_pubkey = 1;
uint32 avail_ports = 2; uint32 avail_no_of_port = 2;
uint32 avail_ipv4 = 3; uint32 avail_vcpus = 3;
uint32 avail_ipv6 = 4; uint32 avail_memory_mb = 4;
uint32 avail_vcpus = 5; uint32 avail_storage_mb = 5;
uint32 avail_memory_mb = 6; uint32 max_ports_per_app = 6;
uint32 avail_storage_gb = 7;
uint32 max_ports_per_vm = 8;
} }
message BrainMessageApp { message BrainMessageApp {
@ -91,20 +127,23 @@ message BrainMessageApp {
// resource usage // resource usage
} }
} }
message DaemonAuth {
string timestamp = 1;
string pubkey = 2;
repeated string contracts = 3;
string signature = 4;
}
message DaemonMessageApp { message DaemonMessageApp {
oneof Msg { oneof Msg {
string pubkey = 1; DaemonAuth auth = 1;
NewAppRes new_app_res = 2; NewAppRes new_app_res = 2;
AppNodeResources app_node_resources = 3; AppNodeResources app_node_resources = 3;
} }
} }
message Pubkey {
string pubkey = 1;
}
service BrainAppDaemon { service BrainAppDaemon {
rpc RegisterNode (RegisterAppNodeReq) returns (stream AppContract); rpc RegisterAppNode (RegisterAppNodeReq) returns (stream AppContract);
rpc BrainMessages (Pubkey) returns (stream BrainMessageApp); rpc BrainMessages (DaemonAuth) returns (stream BrainMessageApp);
rpc DaemonMessages (stream DaemonMessageApp) returns (Empty); rpc DaemonMessages (stream DaemonMessageApp) returns (Empty);
} }

@ -1,91 +0,0 @@
syntax = "proto3";
package shared;
message SetConfigResponse {
string status = 1;
}
message Empty {
}
message ManagerConfigPB {
repeated FileEntry filesystems = 1;
repeated EnvironmentEntry environments = 2;
repeated ChildProcess child_processes = 3;
Container container = 4;
}
message FileEntry {
string path = 1;
string content = 2;
}
message EnvironmentEntry {
string name = 1;
string value = 2;
}
message RestartPolicy {
uint32 max_retries = 1;
uint32 delay_seconds = 2;
oneof policy_type {
bool Always = 3;
bool OnNonZeroExit = 4;
}
}
message ChildProcess {
string path = 1;
repeated string arguments = 2;
RestartPolicy restart= 3;
}
service ConfigManager {
rpc SetConfig(ManagerConfigPB) returns (SetConfigResponse) {}
rpc GetConfig(Empty) returns (ManagerConfigPB) {}
}
message MappedPort {
uint32 host_port = 1;
uint32 container_port = 2;
}
message ContainerContracts {
string uuid = 1;
string package_url = 2;
string admin_pubkey = 3;
string node_pubkey = 4;
repeated MappedPort exposed_ports = 5;
string created_at = 13;
}
message Container {
string package_url = 1;
string node_pubkey = 2;
Resource resource = 3;
string uuid = 4;
string admin_pubkey = 5;
}
message Resource {
uint32 memory_mb = 1;
uint32 disk_mb = 2;
uint32 vcpu = 3;
repeated uint32 ports = 4;
}
message RegisterNodeReq {
string node_pubkey = 1;
string owner_pubkey = 2;
string main_ip = 3;
string country = 4;
string region = 5;
string city = 6;
}
message Pubkey {
string pubkey = 1;
}

@ -1,18 +1 @@
pub mod pb { pub mod sgx;
pub mod shared {
tonic::include_proto!("shared");
}
pub mod daemon {
tonic::include_proto!("deamon");
}
pub mod brain {
tonic::include_proto!("brain");
}
pub mod dtpm {
tonic::include_proto!("dtpm");
}
}
pub mod types;

12
src/sgx/mod.rs Normal file

@ -0,0 +1,12 @@
pub mod types;
pub mod pb {
pub mod brain {
tonic::include_proto!("brain");
}
pub mod dtpm {
tonic::include_proto!("dtpm");
}
}

@ -1,3 +1,2 @@
pub mod brain; pub mod brain;
pub mod dtpm; pub mod dtpm;
pub mod shared;

@ -1,4 +1,5 @@
use crate::pb::brain::{AppResource, MappedPort, NewAppReq}; use crate::sgx::pb::brain::{daemon_message_app, AppNodeResources, DaemonMessageApp, NewAppRes};
use crate::sgx::pb::brain::{AppResource, DaemonAuth, MappedPort, NewAppReq};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
@ -36,9 +37,22 @@ pub struct AppDeployConfig {
pub resource: Resource, pub resource: Resource,
#[serde(default)] #[serde(default)]
pub uuid: String, pub uuid: String,
// #[serde(default)] #[serde(default)]
pub admin_pubkey: String, pub admin_pubkey: String,
pub node_pubkey: String, pub node_pubkey: String,
pub node_unit_price: u64,
#[serde(default)]
pub locked_nano: u64,
#[serde(default)]
pub hratls_pubkey: String,
#[serde(default)]
pub public_package_mr_enclave: Option<Vec<u8>>,
pub hours: u64,
#[serde(default)]
pub private_package: bool,
#[serde(default)]
pub app_name: String,
} }
impl From<NewAppReq> for AppDeployConfig { impl From<NewAppReq> for AppDeployConfig {
@ -49,6 +63,11 @@ impl From<NewAppReq> for AppDeployConfig {
uuid: pb_val.uuid, uuid: pb_val.uuid,
admin_pubkey: pb_val.admin_pubkey, admin_pubkey: pb_val.admin_pubkey,
node_pubkey: pb_val.node_pubkey, node_pubkey: pb_val.node_pubkey,
node_unit_price: pb_val.price_per_unit,
locked_nano: pb_val.locked_nano,
hratls_pubkey: pb_val.hratls_pubkey,
public_package_mr_enclave: pb_val.public_package_mr_enclave,
..Default::default()
} }
} }
} }
@ -61,6 +80,11 @@ impl From<AppDeployConfig> for NewAppReq {
uuid: val.uuid, uuid: val.uuid,
admin_pubkey: val.admin_pubkey, admin_pubkey: val.admin_pubkey,
node_pubkey: val.node_pubkey, node_pubkey: val.node_pubkey,
price_per_unit: val.node_unit_price,
locked_nano: val.locked_nano,
hratls_pubkey: val.hratls_pubkey,
public_package_mr_enclave: val.public_package_mr_enclave,
app_name: val.app_name,
} }
} }
} }
@ -79,3 +103,27 @@ impl From<MappedPort> for (u16, u16) {
(val.host_port as u16, val.app_port as u16) (val.host_port as u16, val.app_port as u16)
} }
} }
impl From<DaemonAuth> for DaemonMessageApp {
fn from(val: DaemonAuth) -> Self {
Self {
msg: Some(daemon_message_app::Msg::Auth(val)),
}
}
}
impl From<NewAppRes> for DaemonMessageApp {
fn from(value: NewAppRes) -> Self {
Self {
msg: Some(daemon_message_app::Msg::NewAppRes(value)),
}
}
}
impl From<AppNodeResources> for DaemonMessageApp {
fn from(value: AppNodeResources) -> Self {
Self {
msg: Some(daemon_message_app::Msg::AppNodeResources(value)),
}
}
}

@ -1,4 +1,4 @@
use crate::pb::dtpm as pb_dtpm; use crate::sgx::pb::dtpm as pb_dtpm;
use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -180,13 +180,23 @@ impl From<RestartPolicy> for pb_dtpm::RestartPolicy {
} }
} }
impl DtpmConfig { #[derive(thiserror::Error, Debug)]
pub fn from_path(path: &str) -> Result<Self, Box<dyn std::error::Error>> { pub enum Error {
let config_str = std::fs::read_to_string(path)?; #[error("Disk Access Error: {0}")]
Ok(serde_yml::from_str(&config_str)?) DiskAccess(#[from] std::io::Error),
#[error("Yaml Error: {0}")]
SerdeYaml(#[from] serde_yaml::Error),
} }
pub fn load_data(mut self) -> Result<Self, Box<dyn std::error::Error>> { type Result<T> = std::result::Result<T, Error>;
impl DtpmConfig {
pub fn from_path(path: &str) -> Result<Self> {
let config_str = std::fs::read_to_string(path)?;
Ok(serde_yaml::from_str(&config_str)?)
}
pub fn load_data(mut self) -> Result<Self> {
self.filesystems.iter_mut().for_each(|x| { self.filesystems.iter_mut().for_each(|x| {
if let FileContent::Path(path) = &x.content { if let FileContent::Path(path) = &x.content {
let content = let content =

@ -1,292 +0,0 @@
use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
use serde::{Deserialize, Serialize};
use crate::pb::shared as pb_shared;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Config {
pub filesystems: Vec<FileEntry>,
pub environments: Vec<EnvironmentEntry>,
pub child_processes: Vec<ChildProcess>,
pub container: Option<Container>,
}
impl From<pb_shared::ManagerConfigPb> for Config {
fn from(pb_val: pb_shared::ManagerConfigPb) -> Self {
Config {
filesystems: pb_val
.filesystems
.into_iter()
.map(FileEntry::from)
.collect(),
environments: pb_val
.environments
.into_iter()
.map(EnvironmentEntry::from)
.collect(),
child_processes: pb_val
.child_processes
.into_iter()
.map(ChildProcess::from)
.collect(),
container: pb_val.container.map(Container::from),
}
}
}
impl From<Config> for pb_shared::ManagerConfigPb {
fn from(val: Config) -> pb_shared::ManagerConfigPb {
pb_shared::ManagerConfigPb {
filesystems: val.filesystems.into_iter().map(Into::into).collect(),
environments: val.environments.into_iter().map(Into::into).collect(),
child_processes: val.child_processes.into_iter().map(Into::into).collect(),
container: val.container.map(Into::into),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileEntry {
pub path: String,
pub content: Option<FileContent>,
}
impl From<pb_shared::FileEntry> for FileEntry {
fn from(pb_val: pb_shared::FileEntry) -> Self {
FileEntry {
path: pb_val.path,
content: Some(FileContent::Data(pb_val.content)),
}
}
}
impl From<FileEntry> for pb_shared::FileEntry {
fn from(val: FileEntry) -> pb_shared::FileEntry {
pb_shared::FileEntry {
path: val.path,
content: match val.content {
Some(FileContent::Data(data)) => data,
Some(FileContent::Path(path)) => path,
None => String::new(),
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FileContent {
#[serde(rename = "path")]
Path(String),
#[serde(rename = "data")]
Data(String),
}
impl Default for FileContent {
fn default() -> Self {
FileContent::Data("".to_string())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentEntry {
pub name: String,
pub value: String,
}
impl From<pb_shared::EnvironmentEntry> for EnvironmentEntry {
fn from(pb_val: pb_shared::EnvironmentEntry) -> Self {
EnvironmentEntry {
name: pb_val.name,
value: pb_val.value,
}
}
}
impl From<EnvironmentEntry> for pb_shared::EnvironmentEntry {
fn from(val: EnvironmentEntry) -> pb_shared::EnvironmentEntry {
pb_shared::EnvironmentEntry {
name: val.name,
value: val.value,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChildProcess {
pub path: String,
pub arguments: Vec<String>,
pub restart: Option<RestartPolicy>,
}
impl From<pb_shared::ChildProcess> for ChildProcess {
fn from(pb_val: pb_shared::ChildProcess) -> Self {
ChildProcess {
path: pb_val.path,
arguments: pb_val.arguments,
restart: pb_val.restart.map(RestartPolicy::from),
}
}
}
impl From<ChildProcess> for pb_shared::ChildProcess {
fn from(val: ChildProcess) -> pb_shared::ChildProcess {
pb_shared::ChildProcess {
path: val.path,
arguments: val.arguments,
restart: val.restart.map(Into::into),
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
pub struct RestartPolicy {
pub max_retries: u32,
pub delay_seconds: u32,
pub policy: Option<RestartPolicyType>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum RestartPolicyType {
Always(bool),
OnNonZeroExit(bool),
}
impl Default for RestartPolicyType {
fn default() -> Self {
RestartPolicyType::Always(true)
}
}
impl From<pb_shared::RestartPolicy> for RestartPolicy {
fn from(pb_val: pb_shared::RestartPolicy) -> Self {
RestartPolicy {
max_retries: pb_val.max_retries,
delay_seconds: pb_val.delay_seconds,
policy: match pb_val.policy_type {
Some(pb_shared::restart_policy::PolicyType::Always(_)) => {
Some(RestartPolicyType::Always(true))
}
Some(pb_shared::restart_policy::PolicyType::OnNonZeroExit(_)) => {
Some(RestartPolicyType::OnNonZeroExit(true))
}
None => None,
},
}
}
}
impl From<RestartPolicy> for pb_shared::RestartPolicy {
fn from(val: RestartPolicy) -> pb_shared::RestartPolicy {
pb_shared::RestartPolicy {
max_retries: val.max_retries,
delay_seconds: val.delay_seconds,
policy_type: match val.policy {
Some(RestartPolicyType::Always(_)) => {
Some(pb_shared::restart_policy::PolicyType::Always(true))
}
Some(RestartPolicyType::OnNonZeroExit(_)) => {
Some(pb_shared::restart_policy::PolicyType::OnNonZeroExit(true))
}
None => None,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Container {
pub package_url: String,
pub resource: Option<Resource>,
#[serde(default)]
pub uuid: String,
#[serde(default)]
pub admin_pubkey: String,
pub node_pubkey: String,
}
impl From<pb_shared::Container> for Container {
fn from(pb_val: pb_shared::Container) -> Self {
Self {
package_url: pb_val.package_url,
resource: pb_val.resource.map(Resource::from),
uuid: pb_val.uuid,
admin_pubkey: pb_val.admin_pubkey,
node_pubkey: pb_val.node_pubkey,
}
}
}
impl From<Container> for pb_shared::Container {
fn from(val: Container) -> pb_shared::Container {
pb_shared::Container {
package_url: val.package_url,
resource: val.resource.map(Into::into),
// uuid: val.uuid.map(Into::into),
uuid: val.uuid,
admin_pubkey: val.admin_pubkey,
node_pubkey: val.node_pubkey,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct Resource {
pub memory_mb: u32,
pub disk_mb: u32,
pub vcpu: u32,
pub port: Vec<u32>,
}
impl From<pb_shared::Resource> for Resource {
fn from(pb_val: pb_shared::Resource) -> Self {
Self {
memory_mb: pb_val.memory_mb,
disk_mb: pb_val.disk_mb,
vcpu: pb_val.vcpu,
port: pb_val.ports,
}
}
}
impl From<Resource> for pb_shared::Resource {
fn from(val: Resource) -> pb_shared::Resource {
pb_shared::Resource {
memory_mb: val.memory_mb,
disk_mb: val.disk_mb,
vcpu: val.vcpu,
ports: val.port,
}
}
}
impl From<(u16, u16)> for pb_shared::MappedPort {
fn from(val: (u16, u16)) -> Self {
Self {
host_port: val.0 as u32,
container_port: val.1 as u32,
}
}
}
impl From<pb_shared::MappedPort> for (u16, u16) {
fn from(val: pb_shared::MappedPort) -> Self {
(val.host_port as u16, val.container_port as u16)
}
}
impl Config {
pub fn from_path(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
let config_str = std::fs::read_to_string(path)?;
Ok(serde_yml::from_str(&config_str)?)
}
pub fn load_data(mut self) -> Result<Self, Box<dyn std::error::Error>> {
self.filesystems.iter_mut().for_each(|x| {
if let Some(FileContent::Path(path)) = &x.content {
let content =
std::fs::read(path).unwrap_or_else(|_| panic!("Unable to read file {path}"));
let encoded = BASE64.encode(content);
x.content = Some(FileContent::Data(encoded));
}
});
Ok(self)
}
}