diff --git a/Cargo.lock b/Cargo.lock index de204b3..9264ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,7 +641,7 @@ dependencies = [ "tokio-util", "tower-service", "url", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -715,6 +715,12 @@ dependencies = [ "bytes", ] +[[package]] +name = "c_linked_list" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" + [[package]] name = "camino" version = "1.1.10" @@ -1102,7 +1108,7 @@ dependencies = [ "parking_lot", "signal-hook", "signal-hook-mio", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1119,7 +1125,7 @@ dependencies = [ "rustix 0.38.44", "signal-hook", "signal-hook-mio", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1128,7 +1134,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2049,6 +2055,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + [[package]] name = "generic-array" version = "0.14.7" @@ -2060,6 +2072,28 @@ dependencies = [ "zeroize", ] +[[package]] +name = "get_if_addrs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +dependencies = [ + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi 0.2.8", +] + +[[package]] +name = "get_if_addrs-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +dependencies = [ + "gcc", + "libc", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -2271,8 +2305,9 @@ version = "0.1.0" dependencies = [ "actix-web", "env_logger", + "local-ip-address", "log", - "mdns-sd", + "mdns-sd 0.14.1 (git+https://github.com/jggc/mdns-sd.git?branch=patch-1)", "serde", "serde_json", "sysinfo", @@ -2631,7 +2666,7 @@ dependencies = [ "pin-project-lite", "tokio", "tower-service", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -3365,6 +3400,18 @@ dependencies = [ "local-waker", ] +[[package]] +name = "local-ip-address" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "656b3b27f8893f7bbf9485148ff9a65f019e3f33bd5cdc87c83cab16b3fd9ec8" +dependencies = [ + "libc", + "neli", + "thiserror 2.0.14", + "windows-sys 0.59.0", +] + [[package]] name = "local-waker" version = "0.1.4" @@ -3434,8 +3481,10 @@ dependencies = [ "dmidecode", "env_logger", "futures", + "get_if_addrs", + "local-ip-address", "log", - "mdns-sd", + "mdns-sd 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", ] @@ -3454,6 +3503,20 @@ dependencies = [ "socket2 0.6.0", ] +[[package]] +name = "mdns-sd" +version = "0.14.1" +source = "git+https://github.com/jggc/mdns-sd.git?branch=patch-1#9e4619599d1493ec15395d62d82d40a43fbef9e7" +dependencies = [ + "fastrand", + "flume", + "if-addrs", + "log", + "mio 1.0.4", + "socket-pktinfo", + "socket2 0.6.0", +] + [[package]] name = "memchr" version = "2.7.5" @@ -3516,6 +3579,31 @@ dependencies = [ "tempfile", ] +[[package]] +name = "neli" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93062a0dce6da2517ea35f301dfc88184ce18d3601ec786a727a87bf535deca9" +dependencies = [ + "byteorder", + "libc", + "log", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8034b7fbb6f9455b2a96c19e6edf8dc9fc34c70449938d8ee3b4df363f61fe" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", +] + [[package]] name = "newline-converter" version = "0.3.0" @@ -3540,7 +3628,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -4606,7 +4694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fadd2c0ab350e21c66556f94ee06f766d8bdae3213857ba7610bfd8e10e51880" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -6304,6 +6392,12 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" diff --git a/adr/agent_discovery/mdns/Cargo.toml b/adr/agent_discovery/mdns/Cargo.toml index ec97a88..b5fc525 100644 --- a/adr/agent_discovery/mdns/Cargo.toml +++ b/adr/agent_discovery/mdns/Cargo.toml @@ -13,3 +13,5 @@ dmidecode = "0.2" # For getting the motherboard ID on the agent log.workspace=true env_logger.workspace=true clap = { version = "4.5.46", features = ["derive"] } +get_if_addrs = "0.5.3" +local-ip-address = "0.6.5" diff --git a/adr/agent_discovery/mdns/src/advertise.rs b/adr/agent_discovery/mdns/src/advertise.rs index ee8e4ce..a98f237 100644 --- a/adr/agent_discovery/mdns/src/advertise.rs +++ b/adr/agent_discovery/mdns/src/advertise.rs @@ -10,11 +10,10 @@ use crate::SERVICE_TYPE; const SERVICE_PORT: u16 = 43210; // A port for the service. It needs one, even if unused. pub async fn advertise() { - info!("Starting Harmony Agent..."); // Get a unique ID for this machine. - let motherboard_id = "some motherboard id"; + let motherboard_id = "some motherboard id"; let instance_name = format!("harmony-agent-{}", motherboard_id); info!("This agent's instance name: {}", instance_name); info!("Advertising with ID: {}", motherboard_id); @@ -29,11 +28,13 @@ pub async fn advertise() { // Create the service information. // The instance name should be unique on the network. + let local_ip = local_ip_address::local_ip().unwrap(); let service_info = ServiceInfo::new( SERVICE_TYPE, &instance_name, "harmony-host.local.", // A hostname for the service - (), // No specific IP addresses, let the daemon figure it out + local_ip, + // "0.0.0.0", SERVICE_PORT, Some(properties), ) @@ -43,9 +44,16 @@ pub async fn advertise() { mdns.register(service_info) .expect("Failed to register service"); - info!("Service '{}' registered and now being advertised.", instance_name); + info!( + "Service '{}' registered and now being advertised.", + instance_name + ); info!("Agent is running. Press Ctrl+C to exit."); + for iface in get_if_addrs::get_if_addrs().unwrap() { + println!("{:#?}", iface); + } + // Keep the agent running indefinitely. tokio::signal::ctrl_c().await.unwrap(); info!("Shutting down agent."); diff --git a/examples/cli/src/main.rs b/examples/cli/src/main.rs index 03c4e00..524d69c 100644 --- a/examples/cli/src/main.rs +++ b/examples/cli/src/main.rs @@ -16,7 +16,9 @@ async fn main() { Box::new(SuccessScore {}), Box::new(ErrorScore {}), Box::new(PanicScore {}), - Box::new(DiscoverInventoryAgentScore { discovery_timeout: Some(10) }), + Box::new(DiscoverInventoryAgentScore { + discovery_timeout: Some(10), + }), ], None, ) diff --git a/harmony/src/modules/mod.rs b/harmony/src/modules/mod.rs index c613233..8935278 100644 --- a/harmony/src/modules/mod.rs +++ b/harmony/src/modules/mod.rs @@ -5,6 +5,7 @@ pub mod dns; pub mod dummy; pub mod helm; pub mod http; +pub mod inventory; pub mod ipxe; pub mod k3d; pub mod k8s; @@ -17,4 +18,3 @@ pub mod prometheus; pub mod storage; pub mod tenant; pub mod tftp; -pub mod inventory; diff --git a/harmony_inventory_agent/Cargo.toml b/harmony_inventory_agent/Cargo.toml index 03810ae..9ffe37e 100644 --- a/harmony_inventory_agent/Cargo.toml +++ b/harmony_inventory_agent/Cargo.toml @@ -12,4 +12,6 @@ log.workspace = true env_logger.workspace = true tokio.workspace = true thiserror.workspace = true -mdns-sd = "0.14.1" +# mdns-sd = "0.14.1" +mdns-sd = { git = "https://github.com/jggc/mdns-sd.git", branch = "patch-1" } +local-ip-address = "0.6.5" diff --git a/harmony_inventory_agent/src/lib.rs b/harmony_inventory_agent/src/lib.rs index eeb21bb..cbf208b 100644 --- a/harmony_inventory_agent/src/lib.rs +++ b/harmony_inventory_agent/src/lib.rs @@ -1,2 +1,2 @@ -pub mod local_presence; mod hwinfo; +pub mod local_presence; diff --git a/harmony_inventory_agent/src/local_presence/advertise.rs b/harmony_inventory_agent/src/local_presence/advertise.rs index 82e26f8..3ccb4f6 100644 --- a/harmony_inventory_agent/src/local_presence/advertise.rs +++ b/harmony_inventory_agent/src/local_presence/advertise.rs @@ -1,8 +1,11 @@ -use log::{error, info, warn}; +use log::{debug, error, info, warn}; use mdns_sd::{ServiceDaemon, ServiceInfo}; use std::collections::HashMap; -use crate::{hwinfo::PhysicalHost, local_presence::{PresenceError, SERVICE_NAME, VERSION}}; +use crate::{ + hwinfo::PhysicalHost, + local_presence::{PresenceError, SERVICE_NAME, VERSION}, +}; /// Advertises the agent's presence on the local network. /// @@ -17,7 +20,10 @@ pub fn advertise(service_port: u16) -> Result<(), PresenceError> { } }; - let instance_name = format!("inventory-agent-{}", host_id.clone().unwrap_or("unknown".to_string())); + let instance_name = format!( + "inventory-agent-{}", + host_id.clone().unwrap_or("unknown".to_string()) + ); let spawned_msg = format!("Spawned local presence advertisement task for '{instance_name}'."); @@ -43,11 +49,23 @@ pub fn advertise(service_port: u16) -> Result<(), PresenceError> { } props.insert("version".to_string(), VERSION.to_string()); + let local_ip: Box = match local_ip_address::local_ip() { + Ok(ip) => Box::new(ip), + Err(e) => { + error!( + "Could not figure out local ip, mdns will have to try to figure it out by itself : {e}" + ); + Box::new(()) + } + }; + + debug!("Using local ip {:?}", local_ip.as_ip_addrs()); + let service_info = ServiceInfo::new( SERVICE_NAME, &instance_name, &format!("{}.local.", instance_name), - (), // Let the daemon determine the host IPs + local_ip, service_port, Some(props), ) @@ -64,7 +82,6 @@ pub fn advertise(service_port: u16) -> Result<(), PresenceError> { return; } }; - }); info!("{spawned_msg}"); diff --git a/harmony_inventory_agent/src/local_presence/discover.rs b/harmony_inventory_agent/src/local_presence/discover.rs index 6bd1141..fd7d2b3 100644 --- a/harmony_inventory_agent/src/local_presence/discover.rs +++ b/harmony_inventory_agent/src/local_presence/discover.rs @@ -16,7 +16,7 @@ pub fn discover_agents(timeout: Option, on_event: fn(&DiscoveryEvent)) { while let Ok(event) = receiver.recv() { on_event(&event); match event { - ServiceEvent::ServiceData(resolved) => { + ServiceEvent::ServiceResolved(resolved) => { println!("Resolved a new service: {}", resolved.fullname); } other_event => { @@ -27,8 +27,8 @@ pub fn discover_agents(timeout: Option, on_event: fn(&DiscoveryEvent)) { }); if let Some(timeout) = timeout { - // Gracefully shutdown the daemon. - std::thread::sleep(std::time::Duration::from_secs(timeout)); - mdns.shutdown().unwrap(); + // Gracefully shutdown the daemon. + std::thread::sleep(std::time::Duration::from_secs(timeout)); + mdns.shutdown().unwrap(); } } diff --git a/harmony_inventory_agent/src/main.rs b/harmony_inventory_agent/src/main.rs index faaaeff..d93ea4f 100644 --- a/harmony_inventory_agent/src/main.rs +++ b/harmony_inventory_agent/src/main.rs @@ -8,9 +8,6 @@ use crate::hwinfo::PhysicalHost; mod hwinfo; mod local_presence; - - - #[get("/inventory")] async fn inventory() -> impl Responder { log::info!("Received inventory request"); @@ -32,7 +29,9 @@ async fn main() -> std::io::Result<()> { env_logger::init(); let port = env::var("HARMONY_INVENTORY_AGENT_PORT").unwrap_or_else(|_| "8080".to_string()); - let port = port.parse::().expect(&format!("Invalid port number, cannot parse to u16 {port}")); + let port = port + .parse::() + .expect(&format!("Invalid port number, cannot parse to u16 {port}")); let bind_addr = format!("0.0.0.0:{}", port); log::info!("Starting inventory agent on {}", bind_addr);