diff --git a/Cargo.lock b/Cargo.lock index b055298..dc8b79e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,7 +107,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -196,7 +196,7 @@ checksum = "e3ff2de1c418b9a8db3f062ab918fb5c478fa0377e048432b46aaaeef72e7a8f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -229,7 +229,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", "synstructure", ] @@ -241,7 +241,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -282,7 +282,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -445,7 +445,7 @@ dependencies = [ "axum", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -694,7 +694,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -792,7 +792,7 @@ checksum = "1c7e7913ec01ed98b697e62f8d3fd63c86dc6cccaf983c7eebc64d0e563b0ad9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -919,7 +919,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -942,7 +942,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.118", ] [[package]] @@ -953,7 +953,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -993,7 +993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" dependencies = [ "data-encoding", - "syn", + "syn 2.0.118", ] [[package]] @@ -1066,7 +1066,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1141,7 +1141,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1324,7 +1324,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1373,6 +1373,17 @@ dependencies = [ "slab", ] +[[package]] +name = "fyra-proc-macros" +version = "0.1.0" +source = "git+https://github.com/FyraLabs/fyra-proc-macros#c739d1ed4eedfa47d28b048ca8d5724b4dcdd57c" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2006,7 +2017,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn", + "syn 2.0.118", ] [[package]] @@ -2025,7 +2036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2079,7 +2090,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2404,7 +2415,7 @@ checksum = "dd297cf53f0cb3dee4d2620bb319ae47ef27c702684309f682bdb7e55a18ae9c" dependencies = [ "heck", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2498,7 +2509,7 @@ checksum = "32d59e20403c7d08fe62b4376edfe5c7fb2ef1e6b1465379686d0f21c8df444b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2542,7 +2553,7 @@ checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2884,6 +2895,7 @@ dependencies = [ "dashmap", "dirs", "futures-util", + "fyra-proc-macros", "http 1.4.2", "http-body-util", "hyper", @@ -3041,7 +3053,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3133,6 +3145,30 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -3162,7 +3198,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3185,7 +3221,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3436,14 +3472,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" dependencies = [ "aho-corasick", "memchr", @@ -3453,9 +3489,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" dependencies = [ "aho-corasick", "memchr", @@ -3783,7 +3819,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.118", ] [[package]] @@ -3848,7 +3884,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3859,7 +3895,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3907,7 +3943,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3924,9 +3960,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -4103,7 +4139,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4112,6 +4148,16 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.118" @@ -4140,7 +4186,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4210,7 +4256,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4221,7 +4267,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4314,7 +4360,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4435,7 +4481,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4701,7 +4747,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.118", "wasm-bindgen-shared", ] @@ -4833,7 +4879,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4844,7 +4890,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -5098,7 +5144,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", "synstructure", ] @@ -5119,7 +5165,7 @@ checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -5139,7 +5185,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", "synstructure", ] @@ -5160,7 +5206,7 @@ checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -5193,7 +5239,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 50129f0..a547355 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,8 @@ bytesize = { version = "2.3", features = ["serde"] } # our crates odorobo = { path = "odorobo" } - +fyra-proc-macros = { git = "https://github.com/FyraLabs/fyra-proc-macros" } +# fyra-proc-macros = { path = "../fyra-proc-macros/" } # these are for performance optimizations, based on https://nnethercote.github.io/perf-book/build-configuration.html#optimization-level diff --git a/odorobo/Cargo.toml b/odorobo/Cargo.toml index 61b79f7..afd7777 100644 --- a/odorobo/Cargo.toml +++ b/odorobo/Cargo.toml @@ -6,7 +6,8 @@ license = "AGPL-3.0-or-later" [dependencies] stable-eyre = { workspace = true } -clap = { workspace = true, features = ["derive", "env"] } +clap = { workspace = true, features = ["derive", "env"] } +fyra-proc-macros = { workspace = true } tokio = { workspace = true, features = ["full"] } reqwest = { workspace = true, features = ["json"] } serde_json = { workspace = true } @@ -40,7 +41,7 @@ tower-http = { version = "0.7", features = ["trace"] } kameo = { version = "0.22", features = ["remote"] } ahash = { version = "0.8", features = ["serde"] } dirs = "6" -ipnet = {version = "2.12", features = ["serde", "schemars08"]} +ipnet = { version = "2.12", features = ["serde", "schemars08"] } url = { version = "2.5", features = ["serde"] } async-trait = "0.1" dashmap = "6.1" @@ -60,7 +61,6 @@ aide = { version = "0.16.0-alpha.4", features = [ schemars = "1.2" - cloud-hypervisor-client = { git = "https://github.com/FyraStack/cloud-hypervisor-client.git" } [target.'cfg(target_os = "linux")'.dependencies] diff --git a/odorobo/src/actors/agent_actor.rs b/odorobo/src/actors/agent_actor.rs index 4f54cbe..87c8518 100644 --- a/odorobo/src/actors/agent_actor.rs +++ b/odorobo/src/actors/agent_actor.rs @@ -310,11 +310,11 @@ impl Message for AgentActor { .unwrap_or(0); AgentStatus { - hostname: self.config.hostname.clone(), + hostname: self.config.get_hostname().to_owned(), vcpus: self.vcpus, ram: self.memory, vms: self.vms.keys().copied().collect(), - used_vcpus: vcpus_used_by_vms + self.config.reserved_vcpus, + used_vcpus: vcpus_used_by_vms + self.config.get_reserved_vcpus(), used_ram: ByteSize::b(ram_used_by_vms), } } diff --git a/odorobo/src/config.rs b/odorobo/src/config.rs index 7f9ebb8..9ebc281 100644 --- a/odorobo/src/config.rs +++ b/odorobo/src/config.rs @@ -2,30 +2,11 @@ use ahash::AHashMap; use clap::Parser; use ipnet::Ipv4Net; use serde::{Deserialize, Serialize}; -use std::net::Ipv4Addr; +use std::{net::Ipv4Addr, sync::LazyLock}; use sysinfo::System; use tracing::{info, warn}; -/// Gets the system hostname -pub fn hostname() -> String { - System::host_name().unwrap_or("odorobo".into()) -} - -/// This was requested by katherine. Do not change without asking her. -pub fn default_reserved_vcpus() -> u32 { - 2 -} - -fn default_datacenter() -> String { - warn!("No datacenter specified, defaulting to Dev"); - - "Dev".into() -} - -fn default_region() -> String { - warn!("No region specified, defaulting to Local"); - "Local".into() -} +const CONFIG_PATH: &str = "config.json"; fn default_bridge_name() -> String { "vmbr0".into() @@ -118,43 +99,84 @@ impl Default for NetworkMode { } } -/// Additional runtime options for the agent that aren't applicable to a JSON config file -#[derive(Parser)] -pub struct CliConfig { - /// Whether the manager should be enabled on this instance - #[clap(long, default_value = "false", env = "ODOROBO_MANAGER_ENABLED")] - pub manager_enabled: bool, -} - -// The infra team wants a config file on the box where they can set info specific for the box its on. -// TODO: Double check with infra team (katherine) if they want any other config on the box. -#[derive(Serialize, Deserialize, Default, Debug, Clone)] +/// Odorobo configurations. +/// These fields are available as command-line arguments, environment variables, and json fields, +/// with fallbacks set in the above order. +#[fyra_proc_macros::cli(env_prefix = "ODOROBO_", serde_merge_fn)] +#[derive(Parser, Serialize, Deserialize, Default, Debug, Clone)] pub struct Config { + /// Whether the manager should be enabled on this instance + #[clap(long)] + pub manager_enabled: Option, /// The hostname of the agent. Defaults to the system hostname /// if not specified in the config file. - #[serde(default = "hostname")] - pub hostname: String, + #[clap(long)] + pub hostname: Option, /// The datacenter the agent is running in. - #[serde(default = "default_datacenter")] - pub datacenter: String, + #[clap(long)] + pub datacenter: Option, /// The region the agent is running in. - #[serde(default = "default_region")] - pub region: String, + #[clap(long)] + pub region: Option, /// The number of VCPUs reserved for the agent. Defaults to 2. - #[serde(default = "default_reserved_vcpus")] - pub reserved_vcpus: u32, + #[clap(long)] + pub reserved_vcpus: Option, /// this is just arbitrary data that will be shown but does no config /// Arbitrary labels that can be used + #[clap(skip)] #[serde(default)] pub labels: AHashMap, /// Arbitrary annotations that can be used + #[clap(skip)] #[serde(default)] pub annotations: AHashMap, + #[clap(skip)] #[serde(default)] pub network: NetworkConfig, } +impl Config { + pub fn init() -> Self { + let mut result = Self::parse(); + if let Ok(fd) = + std::fs::File::open(CONFIG_PATH).inspect_err(|e| warn!(?e, "cannot open {CONFIG_PATH}")) + { + let Ok(json) = + serde_json::from_reader(fd).inspect_err(|e| warn!("cannot parse json: {e}")) + else { + return result; + }; + result.serde_merge_fn(json); + } + result + } + pub fn get_manager_enabled(&self) -> bool { + self.manager_enabled.unwrap_or(false) + } + pub fn get_hostname(&self) -> &str { + static HOSTNAME: LazyLock> = LazyLock::new(System::host_name); + (self.hostname.as_deref()).unwrap_or_else(|| HOSTNAME.as_deref().unwrap_or("odorobo")) + } + pub fn get_datacenter(&self) -> &str { + static DEFAULT_DATACENTER: LazyLock<&'static str> = LazyLock::new(|| { + warn!("No datacenter specified, defaulting to Dev"); + "Dev" + }); + (self.datacenter.as_deref()).unwrap_or_else(|| *DEFAULT_DATACENTER) + } + pub fn get_region(&self) -> &str { + static DEFAULT_REGION: LazyLock<&'static str> = LazyLock::new(|| { + warn!("No region specified, defaulting to Local"); + "Local" + }); + (self.region.as_deref()).unwrap_or_else(|| *DEFAULT_REGION) + } + pub fn get_reserved_vcpus(&self) -> u32 { + self.reserved_vcpus.unwrap_or(2) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/odorobo/src/main.rs b/odorobo/src/main.rs index ffb57c5..90442c5 100644 --- a/odorobo/src/main.rs +++ b/odorobo/src/main.rs @@ -9,7 +9,6 @@ mod utils; use std::fs; -use clap::Parser; use kameo::actor::Spawn; use stable_eyre::Result; @@ -22,7 +21,7 @@ use crate::utils::{actor_names::AGENT, connect_to_swarm, init}; #[tokio::main] async fn main() -> Result<()> { - let cli_config = config::CliConfig::parse(); + let cli_config = config::Config::init(); // TODO: ask infra team where they want this on the box let config: Config = if let Ok(file) = fs::File::open("config.json") { serde_json::from_reader(file).expect("unable to parse config.json") @@ -41,7 +40,7 @@ async fn main() -> Result<()> { let agent_actor = AgentActor::spawn(config.clone()); agent_actor.register(AGENT).await?; - if cli_config.manager_enabled { + if cli_config.get_manager_enabled() { let scheduler_actor = SchedulerActor::spawn(()); let http_actor = HTTPActor::spawn(scheduler_actor.clone());