feat(inventory agent): Local presence advertisement and discovery now works! Must be within the same LAN to share the multicast address though
This commit is contained in:
parent
b857412151
commit
05e7b8075c
112
Cargo.lock
generated
112
Cargo.lock
generated
@ -641,7 +641,7 @@ dependencies = [
|
|||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -715,6 +715,12 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "c_linked_list"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "camino"
|
name = "camino"
|
||||||
version = "1.1.10"
|
version = "1.1.10"
|
||||||
@ -1102,7 +1108,7 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1119,7 +1125,7 @@ dependencies = [
|
|||||||
"rustix 0.38.44",
|
"rustix 0.38.44",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1128,7 +1134,7 @@ version = "0.9.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2049,6 +2055,12 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gcc"
|
||||||
|
version = "0.3.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
@ -2060,6 +2072,28 @@ dependencies = [
|
|||||||
"zeroize",
|
"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]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -2271,8 +2305,9 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"local-ip-address",
|
||||||
"log",
|
"log",
|
||||||
"mdns-sd",
|
"mdns-sd 0.14.1 (git+https://github.com/jggc/mdns-sd.git?branch=patch-1)",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
@ -2631,7 +2666,7 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3365,6 +3400,18 @@ dependencies = [
|
|||||||
"local-waker",
|
"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]]
|
[[package]]
|
||||||
name = "local-waker"
|
name = "local-waker"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@ -3434,8 +3481,10 @@ dependencies = [
|
|||||||
"dmidecode",
|
"dmidecode",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
|
"get_if_addrs",
|
||||||
|
"local-ip-address",
|
||||||
"log",
|
"log",
|
||||||
"mdns-sd",
|
"mdns-sd 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3454,6 +3503,20 @@ dependencies = [
|
|||||||
"socket2 0.6.0",
|
"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]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.5"
|
version = "2.7.5"
|
||||||
@ -3516,6 +3579,31 @@ dependencies = [
|
|||||||
"tempfile",
|
"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]]
|
[[package]]
|
||||||
name = "newline-converter"
|
name = "newline-converter"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -3540,7 +3628,7 @@ version = "0.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4606,7 +4694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fadd2c0ab350e21c66556f94ee06f766d8bdae3213857ba7610bfd8e10e51880"
|
checksum = "fadd2c0ab350e21c66556f94ee06f766d8bdae3213857ba7610bfd8e10e51880"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6304,6 +6392,12 @@ dependencies = [
|
|||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -13,3 +13,5 @@ dmidecode = "0.2" # For getting the motherboard ID on the agent
|
|||||||
log.workspace=true
|
log.workspace=true
|
||||||
env_logger.workspace=true
|
env_logger.workspace=true
|
||||||
clap = { version = "4.5.46", features = ["derive"] }
|
clap = { version = "4.5.46", features = ["derive"] }
|
||||||
|
get_if_addrs = "0.5.3"
|
||||||
|
local-ip-address = "0.6.5"
|
||||||
|
@ -10,7 +10,6 @@ use crate::SERVICE_TYPE;
|
|||||||
const SERVICE_PORT: u16 = 43210; // A port for the service. It needs one, even if unused.
|
const SERVICE_PORT: u16 = 43210; // A port for the service. It needs one, even if unused.
|
||||||
|
|
||||||
pub async fn advertise() {
|
pub async fn advertise() {
|
||||||
|
|
||||||
info!("Starting Harmony Agent...");
|
info!("Starting Harmony Agent...");
|
||||||
|
|
||||||
// Get a unique ID for this machine.
|
// Get a unique ID for this machine.
|
||||||
@ -29,11 +28,13 @@ pub async fn advertise() {
|
|||||||
|
|
||||||
// Create the service information.
|
// Create the service information.
|
||||||
// The instance name should be unique on the network.
|
// The instance name should be unique on the network.
|
||||||
|
let local_ip = local_ip_address::local_ip().unwrap();
|
||||||
let service_info = ServiceInfo::new(
|
let service_info = ServiceInfo::new(
|
||||||
SERVICE_TYPE,
|
SERVICE_TYPE,
|
||||||
&instance_name,
|
&instance_name,
|
||||||
"harmony-host.local.", // A hostname for the service
|
"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,
|
SERVICE_PORT,
|
||||||
Some(properties),
|
Some(properties),
|
||||||
)
|
)
|
||||||
@ -43,9 +44,16 @@ pub async fn advertise() {
|
|||||||
mdns.register(service_info)
|
mdns.register(service_info)
|
||||||
.expect("Failed to register service");
|
.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.");
|
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.
|
// Keep the agent running indefinitely.
|
||||||
tokio::signal::ctrl_c().await.unwrap();
|
tokio::signal::ctrl_c().await.unwrap();
|
||||||
info!("Shutting down agent.");
|
info!("Shutting down agent.");
|
||||||
|
@ -16,7 +16,9 @@ async fn main() {
|
|||||||
Box::new(SuccessScore {}),
|
Box::new(SuccessScore {}),
|
||||||
Box::new(ErrorScore {}),
|
Box::new(ErrorScore {}),
|
||||||
Box::new(PanicScore {}),
|
Box::new(PanicScore {}),
|
||||||
Box::new(DiscoverInventoryAgentScore { discovery_timeout: Some(10) }),
|
Box::new(DiscoverInventoryAgentScore {
|
||||||
|
discovery_timeout: Some(10),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,7 @@ pub mod dns;
|
|||||||
pub mod dummy;
|
pub mod dummy;
|
||||||
pub mod helm;
|
pub mod helm;
|
||||||
pub mod http;
|
pub mod http;
|
||||||
|
pub mod inventory;
|
||||||
pub mod ipxe;
|
pub mod ipxe;
|
||||||
pub mod k3d;
|
pub mod k3d;
|
||||||
pub mod k8s;
|
pub mod k8s;
|
||||||
@ -17,4 +18,3 @@ pub mod prometheus;
|
|||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod tenant;
|
pub mod tenant;
|
||||||
pub mod tftp;
|
pub mod tftp;
|
||||||
pub mod inventory;
|
|
||||||
|
@ -12,4 +12,6 @@ log.workspace = true
|
|||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
thiserror.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"
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
pub mod local_presence;
|
|
||||||
mod hwinfo;
|
mod hwinfo;
|
||||||
|
pub mod local_presence;
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use log::{error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use mdns_sd::{ServiceDaemon, ServiceInfo};
|
use mdns_sd::{ServiceDaemon, ServiceInfo};
|
||||||
use std::collections::HashMap;
|
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.
|
/// 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}'.");
|
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());
|
props.insert("version".to_string(), VERSION.to_string());
|
||||||
|
|
||||||
|
let local_ip: Box<dyn mdns_sd::AsIpAddrs> = 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(
|
let service_info = ServiceInfo::new(
|
||||||
SERVICE_NAME,
|
SERVICE_NAME,
|
||||||
&instance_name,
|
&instance_name,
|
||||||
&format!("{}.local.", instance_name),
|
&format!("{}.local.", instance_name),
|
||||||
(), // Let the daemon determine the host IPs
|
local_ip,
|
||||||
service_port,
|
service_port,
|
||||||
Some(props),
|
Some(props),
|
||||||
)
|
)
|
||||||
@ -64,7 +82,6 @@ pub fn advertise(service_port: u16) -> Result<(), PresenceError> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("{spawned_msg}");
|
info!("{spawned_msg}");
|
||||||
|
@ -16,7 +16,7 @@ pub fn discover_agents(timeout: Option<u64>, on_event: fn(&DiscoveryEvent)) {
|
|||||||
while let Ok(event) = receiver.recv() {
|
while let Ok(event) = receiver.recv() {
|
||||||
on_event(&event);
|
on_event(&event);
|
||||||
match event {
|
match event {
|
||||||
ServiceEvent::ServiceData(resolved) => {
|
ServiceEvent::ServiceResolved(resolved) => {
|
||||||
println!("Resolved a new service: {}", resolved.fullname);
|
println!("Resolved a new service: {}", resolved.fullname);
|
||||||
}
|
}
|
||||||
other_event => {
|
other_event => {
|
||||||
@ -27,8 +27,8 @@ pub fn discover_agents(timeout: Option<u64>, on_event: fn(&DiscoveryEvent)) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(timeout) = timeout {
|
if let Some(timeout) = timeout {
|
||||||
// Gracefully shutdown the daemon.
|
// Gracefully shutdown the daemon.
|
||||||
std::thread::sleep(std::time::Duration::from_secs(timeout));
|
std::thread::sleep(std::time::Duration::from_secs(timeout));
|
||||||
mdns.shutdown().unwrap();
|
mdns.shutdown().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,6 @@ use crate::hwinfo::PhysicalHost;
|
|||||||
mod hwinfo;
|
mod hwinfo;
|
||||||
mod local_presence;
|
mod local_presence;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[get("/inventory")]
|
#[get("/inventory")]
|
||||||
async fn inventory() -> impl Responder {
|
async fn inventory() -> impl Responder {
|
||||||
log::info!("Received inventory request");
|
log::info!("Received inventory request");
|
||||||
@ -32,7 +29,9 @@ async fn main() -> std::io::Result<()> {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let port = env::var("HARMONY_INVENTORY_AGENT_PORT").unwrap_or_else(|_| "8080".to_string());
|
let port = env::var("HARMONY_INVENTORY_AGENT_PORT").unwrap_or_else(|_| "8080".to_string());
|
||||||
let port = port.parse::<u16>().expect(&format!("Invalid port number, cannot parse to u16 {port}"));
|
let port = port
|
||||||
|
.parse::<u16>()
|
||||||
|
.expect(&format!("Invalid port number, cannot parse to u16 {port}"));
|
||||||
let bind_addr = format!("0.0.0.0:{}", port);
|
let bind_addr = format!("0.0.0.0:{}", port);
|
||||||
|
|
||||||
log::info!("Starting inventory agent on {}", bind_addr);
|
log::info!("Starting inventory agent on {}", bind_addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user