Compare commits
	
		
			2 Commits
		
	
	
		
			ff2efc0a66
			...
			0876f4e4f0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0876f4e4f0 | |||
| 6ac0e095a3 | 
							
								
								
									
										252
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										252
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" | ||||
| dependencies = [ | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -182,7 +182,7 @@ dependencies = [ | ||||
|  "actix-router", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -249,6 +249,15 @@ dependencies = [ | ||||
|  "zerocopy", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "aho-corasick" | ||||
| version = "0.6.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "aho-corasick" | ||||
| version = "1.1.3" | ||||
| @ -389,7 +398,7 @@ dependencies = [ | ||||
|  "rustc-hash", | ||||
|  "serde", | ||||
|  "serde_derive", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -451,7 +460,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -462,7 +471,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -849,9 +858,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "clap" | ||||
| version = "4.5.40" | ||||
| version = "4.5.46" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" | ||||
| checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" | ||||
| dependencies = [ | ||||
|  "clap_builder", | ||||
|  "clap_derive", | ||||
| @ -859,9 +868,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "clap_builder" | ||||
| version = "4.5.40" | ||||
| version = "4.5.46" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" | ||||
| checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" | ||||
| dependencies = [ | ||||
|  "anstream", | ||||
|  "anstyle", | ||||
| @ -871,14 +880,14 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "clap_derive" | ||||
| version = "4.5.40" | ||||
| version = "4.5.45" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" | ||||
| checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" | ||||
| dependencies = [ | ||||
|  "heck", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1190,7 +1199,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1214,7 +1223,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "strsim", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1225,7 +1234,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" | ||||
| dependencies = [ | ||||
|  "darling_core", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1263,7 +1272,7 @@ checksum = "2cdc8d50f426189eef89dac62fabfa0abb27d5cc008f25bf4156a0203325becc" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1283,7 +1292,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
|  "unicode-xid", | ||||
| ] | ||||
| 
 | ||||
| @ -1349,7 +1358,20 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "dmidecode" | ||||
| version = "0.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4e529c1bd93d69804dc1e0a0c73aacd12bb13c7a18c659497411abdc6acf5e5f" | ||||
| dependencies = [ | ||||
|  "aho-corasick 0.6.10", | ||||
|  "bitflags 1.3.2", | ||||
|  "failure", | ||||
|  "failure_derive", | ||||
|  "lazy_static", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1378,7 +1400,7 @@ dependencies = [ | ||||
|  "anyhow", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1435,7 +1457,7 @@ dependencies = [ | ||||
|  "enum-ordinalize", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1506,7 +1528,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1780,6 +1802,28 @@ dependencies = [ | ||||
|  "once_cell", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "failure" | ||||
| version = "0.1.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" | ||||
| dependencies = [ | ||||
|  "backtrace", | ||||
|  "failure_derive", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "failure_derive" | ||||
| version = "0.1.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 1.0.109", | ||||
|  "synstructure 0.12.6", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "fastrand" | ||||
| version = "2.3.0" | ||||
| @ -1824,6 +1868,17 @@ dependencies = [ | ||||
|  "miniz_oxide", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "flume" | ||||
| version = "0.11.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" | ||||
| dependencies = [ | ||||
|  "futures-core", | ||||
|  "futures-sink", | ||||
|  "spin", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "flurry" | ||||
| version = "0.5.2" | ||||
| @ -1944,7 +1999,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -2128,6 +2183,7 @@ dependencies = [ | ||||
|  "env_logger", | ||||
|  "fqdn", | ||||
|  "futures-util", | ||||
|  "harmony_inventory_agent", | ||||
|  "harmony_macros", | ||||
|  "harmony_secret_derive", | ||||
|  "harmony_types", | ||||
| @ -2216,9 +2272,12 @@ dependencies = [ | ||||
|  "actix-web", | ||||
|  "env_logger", | ||||
|  "log", | ||||
|  "mdns-sd", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "sysinfo", | ||||
|  "thiserror 2.0.14", | ||||
|  "tokio", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -2230,7 +2289,7 @@ dependencies = [ | ||||
|  "quote", | ||||
|  "serde", | ||||
|  "serde_yaml", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -2259,7 +2318,7 @@ dependencies = [ | ||||
|  "proc-macro-crate", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -2814,6 +2873,16 @@ dependencies = [ | ||||
|  "icu_properties", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "if-addrs" | ||||
| version = "0.14.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bf39cc0423ee66021dc5eccface85580e4a001e0c5288bae8bea7ecb69225e90" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "windows-sys 0.59.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "impl-more" | ||||
| version = "0.1.9" | ||||
| @ -2929,7 +2998,7 @@ dependencies = [ | ||||
|  "indoc", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3001,7 +3070,7 @@ checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3186,7 +3255,7 @@ dependencies = [ | ||||
|  "quote", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3357,6 +3426,34 @@ version = "0.7.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mdns" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "clap", | ||||
|  "dmidecode", | ||||
|  "env_logger", | ||||
|  "futures", | ||||
|  "log", | ||||
|  "mdns-sd", | ||||
|  "tokio", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mdns-sd" | ||||
| version = "0.14.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8e0a59b04e17a195b0674198b3182931801c4759d00f36acad51b5a97210a692" | ||||
| dependencies = [ | ||||
|  "fastrand", | ||||
|  "flume", | ||||
|  "if-addrs", | ||||
|  "log", | ||||
|  "mio 1.0.4", | ||||
|  "socket-pktinfo", | ||||
|  "socket2 0.6.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "memchr" | ||||
| version = "2.7.5" | ||||
| @ -3610,7 +3707,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3854,7 +3951,7 @@ dependencies = [ | ||||
|  "pest_meta", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3884,7 +3981,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4288,7 +4385,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4297,7 +4394,7 @@ version = "1.11.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "aho-corasick 1.1.3", | ||||
|  "memchr", | ||||
|  "regex-automata", | ||||
|  "regex-syntax", | ||||
| @ -4309,7 +4406,7 @@ version = "0.4.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "aho-corasick 1.1.3", | ||||
|  "memchr", | ||||
|  "regex-syntax", | ||||
| ] | ||||
| @ -4796,7 +4893,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "serde_derive_internals", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4928,7 +5025,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4939,7 +5036,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4972,7 +5069,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -4993,7 +5090,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "serde", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5037,7 +5134,7 @@ dependencies = [ | ||||
|  "darling", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5179,7 +5276,18 @@ dependencies = [ | ||||
|  "heck", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "socket-pktinfo" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "927136cc2ae6a1b0e66ac6b1210902b75c3f726db004a73bc18686dcd0dcd22f" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "socket2 0.6.0", | ||||
|  "windows-sys 0.60.2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5207,6 +5315,9 @@ name = "spin" | ||||
| version = "0.9.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" | ||||
| dependencies = [ | ||||
|  "lock_api", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "spki" | ||||
| @ -5315,7 +5426,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "rustversion", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5328,7 +5439,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "rustversion", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5337,6 +5448,17 @@ 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", | ||||
|  "quote", | ||||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "2.0.105" | ||||
| @ -5363,6 +5485,18 @@ dependencies = [ | ||||
|  "futures-core", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "synstructure" | ||||
| version = "0.12.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 1.0.109", | ||||
|  "unicode-xid", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "synstructure" | ||||
| version = "0.13.2" | ||||
| @ -5371,7 +5505,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5505,7 +5639,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5516,7 +5650,7 @@ checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5621,7 +5755,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -5792,7 +5926,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6002,7 +6136,7 @@ checksum = "26b682e8c381995ea03130e381928e0e005b7c9eb483c6c8682f50e07b33c2b7" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6078,7 +6212,7 @@ dependencies = [ | ||||
|  "log", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
| 
 | ||||
| @ -6113,7 +6247,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
|  "wasm-bindgen-backend", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
| @ -6232,7 +6366,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6243,7 +6377,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6587,7 +6721,7 @@ dependencies = [ | ||||
|  "quote", | ||||
|  "serde", | ||||
|  "serde_tokenstream", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
|  "xml-rs", | ||||
| ] | ||||
| 
 | ||||
| @ -6611,8 +6745,8 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "synstructure", | ||||
|  "syn 2.0.105", | ||||
|  "synstructure 0.13.2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6632,7 +6766,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6652,8 +6786,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "synstructure", | ||||
|  "syn 2.0.105", | ||||
|  "synstructure 0.13.2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -6692,7 +6826,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "syn 2.0.105", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | ||||
| @ -14,7 +14,7 @@ members = [ | ||||
|   "harmony_composer", | ||||
|   "harmony_inventory_agent", | ||||
|   "harmony_secret_derive", | ||||
|   "harmony_secret", | ||||
|   "harmony_secret", "adr/agent_discovery/mdns", | ||||
| ] | ||||
| 
 | ||||
| [workspace.package] | ||||
|  | ||||
							
								
								
									
										15
									
								
								adr/agent_discovery/mdns/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								adr/agent_discovery/mdns/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| [package] | ||||
| name = "mdns" | ||||
| edition = "2024" | ||||
| version.workspace = true | ||||
| readme.workspace = true | ||||
| license.workspace = true | ||||
| 
 | ||||
| [dependencies] | ||||
| mdns-sd = "0.14" | ||||
| tokio = { version = "1", features = ["full"] } | ||||
| futures = "0.3" | ||||
| 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"] } | ||||
							
								
								
									
										52
									
								
								adr/agent_discovery/mdns/src/advertise.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								adr/agent_discovery/mdns/src/advertise.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| // harmony-agent/src/main.rs
 | ||||
| 
 | ||||
| use log::info; | ||||
| use mdns_sd::{ServiceDaemon, ServiceInfo}; | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::SERVICE_TYPE; | ||||
| 
 | ||||
| // The service we are advertising.
 | ||||
| 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 instance_name = format!("harmony-agent-{}", motherboard_id); | ||||
|     info!("This agent's instance name: {}", instance_name); | ||||
|     info!("Advertising with ID: {}", motherboard_id); | ||||
| 
 | ||||
|     // Create a new mDNS daemon.
 | ||||
|     let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon"); | ||||
| 
 | ||||
|     // Create a TXT record HashMap to hold our metadata.
 | ||||
|     let mut properties = HashMap::new(); | ||||
|     properties.insert("id".to_string(), motherboard_id.to_string()); | ||||
|     properties.insert("version".to_string(), "1.0".to_string()); | ||||
| 
 | ||||
|     // Create the service information.
 | ||||
|     // The instance name should be unique on the network.
 | ||||
|     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
 | ||||
|         SERVICE_PORT, | ||||
|         Some(properties), | ||||
|     ) | ||||
|     .expect("Failed to create service info"); | ||||
| 
 | ||||
|     // Register our service with the daemon.
 | ||||
|     mdns.register(service_info) | ||||
|         .expect("Failed to register service"); | ||||
| 
 | ||||
|     info!("Service '{}' registered and now being advertised.", instance_name); | ||||
|     info!("Agent is running. Press Ctrl+C to exit."); | ||||
| 
 | ||||
|     // Keep the agent running indefinitely.
 | ||||
|     tokio::signal::ctrl_c().await.unwrap(); | ||||
|     info!("Shutting down agent."); | ||||
| } | ||||
							
								
								
									
										110
									
								
								adr/agent_discovery/mdns/src/discover.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								adr/agent_discovery/mdns/src/discover.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | ||||
| use log::debug; | ||||
| use mdns_sd::{ServiceDaemon, ServiceEvent}; | ||||
| 
 | ||||
| use crate::SERVICE_TYPE; | ||||
| 
 | ||||
| pub async fn discover() { | ||||
|     println!("Starting Harmony Master and browsing for agents..."); | ||||
| 
 | ||||
|     // Create a new mDNS daemon.
 | ||||
|     let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon"); | ||||
| 
 | ||||
|     // Start browsing for the service type.
 | ||||
|     // The receiver will be a stream of events.
 | ||||
|     let receiver = mdns.browse(SERVICE_TYPE).expect("Failed to browse"); | ||||
| 
 | ||||
|     println!( | ||||
|         "Listening for mDNS events for '{}'. Press Ctrl+C to exit.", | ||||
|         SERVICE_TYPE | ||||
|     ); | ||||
| 
 | ||||
|     std::thread::spawn(move || { | ||||
|         while let Ok(event) = receiver.recv() { | ||||
|             match event { | ||||
|                 ServiceEvent::ServiceData(resolved) => { | ||||
|                     println!("Resolved a new service: {}", resolved.fullname); | ||||
|                 } | ||||
|                 other_event => { | ||||
|                     println!("Received other event: {:?}", &other_event); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     // Gracefully shutdown the daemon.
 | ||||
|     std::thread::sleep(std::time::Duration::from_secs(1000000)); | ||||
|     mdns.shutdown().unwrap(); | ||||
| 
 | ||||
|     // Process events as they come in.
 | ||||
|     // while let Ok(event) = receiver.recv_async().await {
 | ||||
|     //     debug!("Received event {event:?}");
 | ||||
|     //     // match event {
 | ||||
|     //     //     ServiceEvent::ServiceFound(svc_type, fullname) => {
 | ||||
|     //     //         println!("\n--- Agent Discovered ---");
 | ||||
|     //     //         println!("  Service Name: {}", fullname());
 | ||||
|     //     //         // You can now resolve this service to get its IP, port, and TXT records
 | ||||
|     //     //         // The resolve operation is a separate network call.
 | ||||
|     //     //         let receiver = mdns.browse(info.get_fullname()).unwrap();
 | ||||
|     //     //         if let Ok(resolve_event) = receiver.recv_timeout(Duration::from_secs(2)) {
 | ||||
|     //     //              if let ServiceEvent::ServiceResolved(info) = resolve_event {
 | ||||
|     //     //                 let ip = info.get_addresses().iter().next().unwrap();
 | ||||
|     //     //                 let port = info.get_port();
 | ||||
|     //     //                 let motherboard_id = info.get_property("id").map_or("N/A", |v| v.val_str());
 | ||||
|     //     //
 | ||||
|     //     //                 println!("  IP: {}:{}", ip, port);
 | ||||
|     //     //                 println!("  Motherboard ID: {}", motherboard_id);
 | ||||
|     //     //                 println!("------------------------");
 | ||||
|     //     //
 | ||||
|     //     //                 // TODO: Add this agent to your central list of discovered hosts.
 | ||||
|     //     //              }
 | ||||
|     //     //         } else {
 | ||||
|     //     //             println!("Could not resolve service '{}' in time.", info.get_fullname());
 | ||||
|     //     //         }
 | ||||
|     //     //     }
 | ||||
|     //     //     ServiceEvent::ServiceRemoved(info) => {
 | ||||
|     //     //         println!("\n--- Agent Removed ---");
 | ||||
|     //     //         println!("  Service Name: {}", info.get_fullname());
 | ||||
|     //     //         println!("---------------------");
 | ||||
|     //     //         // TODO: Remove this agent from your list.
 | ||||
|     //     //     }
 | ||||
|     //     //     _ => {
 | ||||
|     //     //         // We don't care about other event types for this example
 | ||||
|     //     //     }
 | ||||
|     //     // }
 | ||||
|     // }
 | ||||
| } | ||||
| 
 | ||||
| async fn discover_example() { | ||||
|     use mdns_sd::{ServiceDaemon, ServiceEvent}; | ||||
| 
 | ||||
|     // Create a daemon
 | ||||
|     let mdns = ServiceDaemon::new().expect("Failed to create daemon"); | ||||
| 
 | ||||
|     // Use recently added `ServiceEvent::ServiceData`.
 | ||||
|     mdns.use_service_data(true) | ||||
|         .expect("Failed to use ServiceData"); | ||||
| 
 | ||||
|     // Browse for a service type.
 | ||||
|     let service_type = "_mdns-sd-my-test._udp.local."; | ||||
|     let receiver = mdns.browse(service_type).expect("Failed to browse"); | ||||
| 
 | ||||
|     // Receive the browse events in sync or async. Here is
 | ||||
|     // an example of using a thread. Users can call `receiver.recv_async().await`
 | ||||
|     // if running in async environment.
 | ||||
|     std::thread::spawn(move || { | ||||
|         while let Ok(event) = receiver.recv() { | ||||
|             match event { | ||||
|                 ServiceEvent::ServiceData(resolved) => { | ||||
|                     println!("Resolved a new service: {}", resolved.fullname); | ||||
|                 } | ||||
|                 other_event => { | ||||
|                     println!("Received other event: {:?}", &other_event); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     // Gracefully shutdown the daemon.
 | ||||
|     std::thread::sleep(std::time::Duration::from_secs(1)); | ||||
|     mdns.shutdown().unwrap(); | ||||
| } | ||||
							
								
								
									
										31
									
								
								adr/agent_discovery/mdns/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								adr/agent_discovery/mdns/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| use clap::{Parser, ValueEnum}; | ||||
| 
 | ||||
| mod advertise; | ||||
| mod discover; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| #[command(version, about, long_about = None)] | ||||
| struct Args { | ||||
|     #[arg(value_enum)] | ||||
|     profile: Profiles, | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] | ||||
| enum Profiles { | ||||
|     Advertise, | ||||
|     Discover, | ||||
| } | ||||
| 
 | ||||
| // The service type we are looking for.
 | ||||
| const SERVICE_TYPE: &str = "_harmory._tcp.local."; | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|     env_logger::init(); | ||||
|     let args = Args::parse(); | ||||
| 
 | ||||
|     match args.profile { | ||||
|         Profiles::Advertise => advertise::advertise().await, | ||||
|         Profiles::Discover => discover::discover().await, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1
									
								
								check.sh
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								check.sh
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| #!/bin/sh | ||||
| set -e | ||||
| 
 | ||||
| rustc --version | ||||
| cargo check --all-targets --all-features --keep-going | ||||
| cargo fmt --check | ||||
| cargo clippy | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| use harmony::{ | ||||
|     inventory::Inventory, | ||||
|     modules::dummy::{ErrorScore, PanicScore, SuccessScore}, | ||||
|     modules::{ | ||||
|         dummy::{ErrorScore, PanicScore, SuccessScore}, | ||||
|         inventory::DiscoverInventoryAgentScore, | ||||
|     }, | ||||
|     topology::LocalhostTopology, | ||||
| }; | ||||
| 
 | ||||
| @ -13,6 +16,7 @@ async fn main() { | ||||
|             Box::new(SuccessScore {}), | ||||
|             Box::new(ErrorScore {}), | ||||
|             Box::new(PanicScore {}), | ||||
|             Box::new(DiscoverInventoryAgentScore { discovery_timeout: Some(10) }), | ||||
|         ], | ||||
|         None, | ||||
|     ) | ||||
|  | ||||
| @ -67,6 +67,7 @@ bollard.workspace = true | ||||
| tar.workspace = true | ||||
| base64.workspace = true | ||||
| once_cell = "1.21.3" | ||||
| harmony_inventory_agent = { path = "../harmony_inventory_agent" } | ||||
| harmony_secret_derive = { version = "0.1.0", path = "../harmony_secret_derive" } | ||||
| 
 | ||||
| [dev-dependencies] | ||||
|  | ||||
| @ -32,6 +32,7 @@ pub enum InterpretName { | ||||
|     Lamp, | ||||
|     ApplicationMonitoring, | ||||
|     K8sPrometheusCrdAlerting, | ||||
|     DiscoverInventoryAgent, | ||||
| } | ||||
| 
 | ||||
| impl std::fmt::Display for InterpretName { | ||||
| @ -58,6 +59,7 @@ impl std::fmt::Display for InterpretName { | ||||
|             InterpretName::Lamp => f.write_str("LAMP"), | ||||
|             InterpretName::ApplicationMonitoring => f.write_str("ApplicationMonitoring"), | ||||
|             InterpretName::K8sPrometheusCrdAlerting => f.write_str("K8sPrometheusCrdAlerting"), | ||||
|             InterpretName::DiscoverInventoryAgent => f.write_str("DiscoverInventoryAgent"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										72
									
								
								harmony/src/modules/inventory/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								harmony/src/modules/inventory/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| use async_trait::async_trait; | ||||
| use harmony_inventory_agent::local_presence::DiscoveryEvent; | ||||
| use log::info; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use crate::{ | ||||
|     data::{Id, Version}, | ||||
|     interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, | ||||
|     inventory::Inventory, | ||||
|     score::Score, | ||||
|     topology::Topology, | ||||
| }; | ||||
| 
 | ||||
| /// This launches an harmony_inventory_agent discovery process
 | ||||
| /// This will allow us to register/update hosts running harmony_inventory_agent
 | ||||
| /// from LAN in the Harmony inventory
 | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct DiscoverInventoryAgentScore { | ||||
|     pub discovery_timeout: Option<u64>, | ||||
| } | ||||
| 
 | ||||
| impl<T: Topology> Score<T> for DiscoverInventoryAgentScore { | ||||
|     fn name(&self) -> String { | ||||
|         "DiscoverInventoryAgentScore".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn create_interpret(&self) -> Box<dyn Interpret<T>> { | ||||
|         Box::new(DiscoverInventoryAgentInterpret { | ||||
|             score: self.clone(), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| struct DiscoverInventoryAgentInterpret { | ||||
|     score: DiscoverInventoryAgentScore, | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| impl<T: Topology> Interpret<T> for DiscoverInventoryAgentInterpret { | ||||
|     async fn execute( | ||||
|         &self, | ||||
|         inventory: &Inventory, | ||||
|         topology: &T, | ||||
|     ) -> Result<Outcome, InterpretError> { | ||||
|         harmony_inventory_agent::local_presence::discover_agents( | ||||
|             self.score.discovery_timeout, | ||||
|             on_discover_event, | ||||
|         ); | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     fn get_name(&self) -> InterpretName { | ||||
|         InterpretName::DiscoverInventoryAgent | ||||
|     } | ||||
| 
 | ||||
|     fn get_version(&self) -> Version { | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     fn get_status(&self) -> InterpretStatus { | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     fn get_children(&self) -> Vec<Id> { | ||||
|         todo!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn on_discover_event(event: &DiscoveryEvent) { | ||||
|     info!("got discovery event {event:?}"); | ||||
| } | ||||
| @ -17,3 +17,4 @@ pub mod prometheus; | ||||
| pub mod storage; | ||||
| pub mod tenant; | ||||
| pub mod tftp; | ||||
| pub mod inventory; | ||||
|  | ||||
| @ -10,3 +10,6 @@ serde.workspace = true | ||||
| serde_json.workspace = true | ||||
| log.workspace = true | ||||
| env_logger.workspace = true | ||||
| tokio.workspace = true | ||||
| thiserror.workspace = true | ||||
| mdns-sd = "0.14.1" | ||||
|  | ||||
							
								
								
									
										2
									
								
								harmony_inventory_agent/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								harmony_inventory_agent/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| pub mod local_presence; | ||||
| mod hwinfo; | ||||
							
								
								
									
										73
									
								
								harmony_inventory_agent/src/local_presence/advertise.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								harmony_inventory_agent/src/local_presence/advertise.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| use log::{error, info, warn}; | ||||
| use mdns_sd::{ServiceDaemon, ServiceInfo}; | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::{hwinfo::PhysicalHost, local_presence::{PresenceError, SERVICE_NAME, VERSION}}; | ||||
| 
 | ||||
| /// Advertises the agent's presence on the local network.
 | ||||
| ///
 | ||||
| /// This function is synchronous and non-blocking. It spawns a background Tokio task
 | ||||
| /// to handle the mDNS advertisement for the lifetime of the application.
 | ||||
| pub fn advertise(service_port: u16) -> Result<(), PresenceError> { | ||||
|     let host_id = match PhysicalHost::gather() { | ||||
|         Ok(host) => Some(host.host_uuid), | ||||
|         Err(e) => { | ||||
|             error!("Could not build physical host, harmony presence id will be unavailable : {e}"); | ||||
|             None | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     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}'."); | ||||
| 
 | ||||
|     tokio::spawn(async move { | ||||
|         info!( | ||||
|             "Local presence task started. Advertising as '{}'.", | ||||
|             instance_name | ||||
|         ); | ||||
| 
 | ||||
|         // The ServiceDaemon must live for the entire duration of the advertisement.
 | ||||
|         // If it's dropped, the advertisement stops.
 | ||||
|         let mdns = match ServiceDaemon::new() { | ||||
|             Ok(daemon) => daemon, | ||||
|             Err(e) => { | ||||
|                 warn!("Failed to create mDNS daemon: {}. Task shutting down.", e); | ||||
|                 return; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         let mut props = HashMap::new(); | ||||
|         if let Some(host_id) = host_id { | ||||
|             props.insert("id".to_string(), host_id); | ||||
|         } | ||||
|         props.insert("version".to_string(), VERSION.to_string()); | ||||
| 
 | ||||
|         let service_info = ServiceInfo::new( | ||||
|             SERVICE_NAME, | ||||
|             &instance_name, | ||||
|             &format!("{}.local.", instance_name), | ||||
|             (), // Let the daemon determine the host IPs
 | ||||
|             service_port, | ||||
|             Some(props), | ||||
|         ) | ||||
|         .expect("ServiceInfo creation should not fail with valid inputs"); | ||||
| 
 | ||||
|         // The registration handle must also be kept alive.
 | ||||
|         let _registration_handle = match mdns.register(service_info) { | ||||
|             Ok(handle) => { | ||||
|                 info!("Service successfully registered on the local network."); | ||||
|                 handle | ||||
|             } | ||||
|             Err(e) => { | ||||
|                 warn!("Failed to register service: {}. Task shutting down.", e); | ||||
|                 return; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|     }); | ||||
| 
 | ||||
|     info!("{spawned_msg}"); | ||||
| 
 | ||||
|     Ok(()) | ||||
| } | ||||
							
								
								
									
										34
									
								
								harmony_inventory_agent/src/local_presence/discover.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								harmony_inventory_agent/src/local_presence/discover.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| use mdns_sd::{ServiceDaemon, ServiceEvent}; | ||||
| 
 | ||||
| use crate::local_presence::SERVICE_NAME; | ||||
| 
 | ||||
| pub type DiscoveryEvent = ServiceEvent; | ||||
| 
 | ||||
| pub fn discover_agents(timeout: Option<u64>, on_event: fn(&DiscoveryEvent)) { | ||||
|     // Create a new mDNS daemon.
 | ||||
|     let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon"); | ||||
| 
 | ||||
|     // Start browsing for the service type.
 | ||||
|     // The receiver will be a stream of events.
 | ||||
|     let receiver = mdns.browse(SERVICE_NAME).expect("Failed to browse"); | ||||
| 
 | ||||
|     std::thread::spawn(move || { | ||||
|         while let Ok(event) = receiver.recv() { | ||||
|             on_event(&event); | ||||
|             match event { | ||||
|                 ServiceEvent::ServiceData(resolved) => { | ||||
|                     println!("Resolved a new service: {}", resolved.fullname); | ||||
|                 } | ||||
|                 other_event => { | ||||
|                     println!("Received other event: {:?}", &other_event); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     if let Some(timeout) = timeout { | ||||
|     // Gracefully shutdown the daemon.
 | ||||
|     std::thread::sleep(std::time::Duration::from_secs(timeout)); | ||||
|     mdns.shutdown().unwrap(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										16
									
								
								harmony_inventory_agent/src/local_presence/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								harmony_inventory_agent/src/local_presence/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| mod discover; | ||||
| pub use discover::*; | ||||
| mod advertise; | ||||
| pub use advertise::*; | ||||
| 
 | ||||
| pub const SERVICE_NAME: &str = "_harmony._tcp.local."; | ||||
| const VERSION: &str = env!("CARGO_PKG_VERSION"); | ||||
| 
 | ||||
| // A specific error type for our module enhances clarity and usability.
 | ||||
| #[derive(thiserror::Error, Debug)] | ||||
| pub enum PresenceError { | ||||
|     #[error("Failed to create mDNS daemon")] | ||||
|     DaemonCreationFailed(#[from] mdns_sd::Error), | ||||
|     #[error("The shutdown signal has already been sent")] | ||||
|     ShutdownFailed, | ||||
| } | ||||
| @ -1,9 +1,15 @@ | ||||
| // src/main.rs
 | ||||
| use actix_web::{App, HttpServer, Responder, get}; | ||||
| use hwinfo::PhysicalHost; | ||||
| use log::error; | ||||
| use std::env; | ||||
| 
 | ||||
| use crate::hwinfo::PhysicalHost; | ||||
| 
 | ||||
| mod hwinfo; | ||||
| mod local_presence; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #[get("/inventory")] | ||||
| async fn inventory() -> impl Responder { | ||||
| @ -26,10 +32,15 @@ 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::<u16>().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); | ||||
| 
 | ||||
|     if let Err(e) = local_presence::advertise(port) { | ||||
|         error!("Could not start advertise local presence : {e}"); | ||||
|     } | ||||
| 
 | ||||
|     HttpServer::new(|| App::new().service(inventory)) | ||||
|         .bind(&bind_addr)? | ||||
|         .run() | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user