build: split into multiple crates

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I6757cc99a0a5bc0c78193487df1ef52b6a6a6964
This commit is contained in:
raf 2026-05-11 12:47:42 +03:00
commit 2c5210aee7
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
22 changed files with 661 additions and 161 deletions

484
Cargo.lock generated
View file

@ -82,17 +82,6 @@ version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "async-trait"
version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "atoi"
version = "2.0.0"
@ -114,6 +103,28 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "aws-lc-rs"
version = "1.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f"
dependencies = [
"aws-lc-sys",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]]
name = "axum"
version = "0.8.9"
@ -233,6 +244,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
@ -248,6 +261,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chacha20"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
"cfg-if",
"cpufeatures 0.3.0",
"rand_core 0.10.1",
]
[[package]]
name = "chrono"
version = "0.4.44"
@ -302,12 +326,31 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "cmake"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
dependencies = [
"cc",
]
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@ -323,6 +366,16 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "core-foundation"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@ -338,6 +391,15 @@ dependencies = [
"libc",
]
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "3.4.0"
@ -385,7 +447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"curve25519-dalek-derive",
"digest",
"fiat-crypto",
@ -445,6 +507,12 @@ version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dunce"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
name = "ed25519"
version = "2.2.3"
@ -567,6 +635,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "futures-channel"
version = "0.3.32"
@ -696,6 +770,7 @@ dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
"rand_core 0.10.1",
"wasip2",
"wasip3",
]
@ -860,7 +935,6 @@ dependencies = [
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots 1.0.7",
]
[[package]]
@ -1021,12 +1095,12 @@ dependencies = [
[[package]]
name = "if-addrs"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf39cc0423ee66021dc5eccface85580e4a001e0c5288bae8bea7ecb69225e90"
checksum = "c0a05c691e1fae256cf7013d99dad472dc52d5543322761f83ec8d47eab40d2b"
dependencies = [
"libc",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@ -1059,6 +1133,65 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "jni"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
dependencies = [
"cfg-if",
"combine",
"jni-macros",
"jni-sys",
"log",
"simd_cesu8",
"thiserror 2.0.18",
"walkdir",
"windows-link",
]
[[package]]
name = "jni-macros"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"simd_cesu8",
"syn",
]
[[package]]
name = "jni-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
dependencies = [
"jni-sys-macros",
]
[[package]]
name = "jni-sys-macros"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.98"
@ -1181,9 +1314,9 @@ dependencies = [
[[package]]
name = "mdns-sd"
version = "0.15.2"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1856c9bb96761020572ccc972887318aafca947a441e7ee52cd2facb8f9af3be"
checksum = "c2bb8ce26633738d98ffcef71ec58bff967c6675be50229823c2835f6316e67e"
dependencies = [
"fastrand",
"flume",
@ -1223,38 +1356,134 @@ name = "ncro"
version = "1.0.0"
dependencies = [
"anyhow",
"async-trait",
"axum",
"base64",
"bytes",
"chrono",
"clap",
"ed25519-dalek",
"futures-util",
"hex",
"http",
"http-body-util",
"humantime-serde",
"mdns-sd",
"prometheus",
"rand 0.8.6",
"reqwest",
"rmp-serde",
"serde",
"serde_json",
"serde_yaml",
"sqlx",
"ncro-config",
"ncro-db",
"ncro-discovery",
"ncro-health",
"ncro-mesh",
"ncro-metrics",
"ncro-router",
"ncro-server",
"tempfile",
"thiserror 2.0.18",
"tokio",
"tokio-util",
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "ncro-config"
version = "1.0.0"
dependencies = [
"hex",
"humantime-serde",
"serde",
"serde_yaml",
"thiserror 2.0.18",
"url",
]
[[package]]
name = "ncro-db"
version = "1.0.0"
dependencies = [
"chrono",
"serde",
"sqlx",
"thiserror 2.0.18",
"tokio",
]
[[package]]
name = "ncro-discovery"
version = "1.0.0"
dependencies = [
"anyhow",
"mdns-sd",
"ncro-config",
"ncro-health",
"tokio",
"tracing",
]
[[package]]
name = "ncro-health"
version = "1.0.0"
dependencies = [
"ncro-config",
"reqwest",
"tokio",
]
[[package]]
name = "ncro-mesh"
version = "1.0.0"
dependencies = [
"chrono",
"ed25519-dalek",
"hex",
"ncro-db",
"rand 0.10.1",
"rmp-serde",
"serde",
"thiserror 2.0.18",
"tokio",
"tracing",
]
[[package]]
name = "ncro-metrics"
version = "1.0.0"
dependencies = [
"prometheus",
]
[[package]]
name = "ncro-narinfo"
version = "1.0.0"
dependencies = [
"base64",
"ed25519-dalek",
"rand 0.10.1",
"thiserror 2.0.18",
]
[[package]]
name = "ncro-router"
version = "1.0.0"
dependencies = [
"chrono",
"futures-util",
"ncro-db",
"ncro-health",
"ncro-metrics",
"ncro-narinfo",
"reqwest",
"thiserror 2.0.18",
"tokio",
"tracing",
]
[[package]]
name = "ncro-server"
version = "1.0.0"
dependencies = [
"axum",
"bytes",
"futures-util",
"ncro-config",
"ncro-db",
"ncro-health",
"ncro-metrics",
"ncro-router",
"reqwest",
"serde",
"tracing",
]
[[package]]
name = "nu-ansi-term"
version = "0.50.3"
@ -1322,6 +1551,12 @@ version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "parking"
version = "2.2.1"
@ -1503,6 +1738,7 @@ version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"aws-lc-rs",
"bytes",
"getrandom 0.3.4",
"lru-slab",
@ -1574,6 +1810,17 @@ dependencies = [
"rand_core 0.9.5",
]
[[package]]
name = "rand"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [
"chacha20",
"getrandom 0.4.2",
"rand_core 0.10.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@ -1612,6 +1859,12 @@ dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "rand_core"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
[[package]]
name = "redox_syscall"
version = "0.5.18"
@ -1649,9 +1902,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "reqwest"
version = "0.12.28"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0"
dependencies = [
"base64",
"bytes",
@ -1670,9 +1923,7 @@ dependencies = [
"quinn",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"rustls-platform-verifier",
"sync_wrapper",
"tokio",
"tokio-rustls",
@ -1685,7 +1936,6 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots 1.0.7",
]
[[package]]
@ -1775,6 +2025,7 @@ version = "0.23.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
dependencies = [
"aws-lc-rs",
"once_cell",
"ring",
"rustls-pki-types",
@ -1783,6 +2034,18 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pki-types"
version = "1.14.1"
@ -1793,12 +2056,40 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-platform-verifier"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
dependencies = [
"core-foundation",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls",
"rustls-native-certs",
"rustls-platform-verifier-android",
"rustls-webpki",
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
@ -1816,12 +2107,53 @@ version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.28"
@ -1914,7 +2246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"digest",
]
@ -1925,7 +2257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"cpufeatures 0.2.17",
"digest",
]
@ -1964,6 +2296,22 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "simd_cesu8"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
dependencies = [
"rustc_version",
"simdutf8",
]
[[package]]
name = "simdutf8"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "slab"
version = "0.4.12"
@ -2452,7 +2800,6 @@ dependencies = [
"tower",
"tower-layer",
"tower-service",
"tracing",
"url",
]
@ -2642,6 +2989,16 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
@ -2760,9 +3117,9 @@ dependencies = [
[[package]]
name = "wasm-streams"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
dependencies = [
"futures-util",
"js-sys",
@ -2803,6 +3160,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-root-certs"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "webpki-roots"
version = "0.26.11"
@ -2831,6 +3197,15 @@ dependencies = [
"wasite",
]
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "windows-core"
version = "0.62.2"
@ -2908,15 +3283,6 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"

View file

@ -1,49 +1,78 @@
[package]
name = "ncro"
version = "1.0.0"
[workspace]
members = [ "crates/*" ]
resolver = "3"
[workspace.package]
edition = "2024"
license = "MIT"
version = "1.0.0"
[dependencies]
[workspace.dependencies]
anyhow = "1.0.102"
async-trait = "0.1.89"
axum = { version = "0.8.9", features = [ "macros" ] }
axum = "0.8.9"
base64 = "0.22.1"
bytes = "1.11.1"
chrono = { version = "0.4.44", features = [ "serde" ] }
clap = { version = "4.6.1", features = [ "derive", "env" ] }
ed25519-dalek = { version = "2.2.0", features = [ "rand_core" ] }
chrono = "0.4.44"
clap = "4.6.1"
ed25519-dalek = "2.2.0"
futures-util = "0.3.32"
hex = "0.4.3"
http = "1.4.0"
http-body-util = "0.1.3"
humantime-serde = "1.1.1"
mdns-sd = "0.15.2"
mdns-sd = "0.19.1"
prometheus = "0.14.0"
rand = "0.8.6"
reqwest = { version = "0.12.28", default-features = false, features = [ "rustls-tls", "stream" ] }
rand = "0.10.1"
reqwest = { version = "0.13.3", default-features = false }
rmp-serde = "1.3.1"
serde = { version = "1.0.228", features = [ "derive" ] }
serde = "1.0.228"
serde_json = "1.0.149"
serde_yaml = "0.9.34"
sqlx = { version = "0.8.6", default-features = false, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
"chrono",
] }
sqlx = { version = "0.8.6", default-features = false }
tempfile = "3.27.0"
thiserror = "2.0.18"
tokio = { version = "1.52.3", features = [ "macros", "rt-multi-thread", "signal", "time", "net", "fs" ] }
tokio-util = { version = "0.7.18", features = [ "io" ] }
tower-http = { version = "0.6.10", features = [ "trace" ] }
tokio = "1.52.3"
tower = "0.5.3"
tower-http = "0.6.10"
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = [ "env-filter", "json" ] }
tracing-subscriber = "0.3.23"
url = "2.5.8"
ncro-config = { path = "crates/config", version = "1.0.0" }
ncro-db = { path = "crates/db", version = "1.0.0" }
ncro-discovery = { path = "crates/discovery", version = "1.0.0" }
ncro-health = { path = "crates/health", version = "1.0.0" }
ncro-mesh = { path = "crates/mesh", version = "1.0.0" }
ncro-metrics = { path = "crates/metrics", version = "1.0.0" }
ncro-narinfo = { path = "crates/narinfo", version = "1.0.0" }
ncro-router = { path = "crates/router", version = "1.0.0" }
ncro-server = { path = "crates/server", version = "1.0.0" }
[package]
name = "ncro"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
anyhow.workspace = true
axum.workspace = true
clap = { workspace = true, features = [ "derive", "env" ] }
hex.workspace = true
tokio = { workspace = true, features = [ "macros", "rt-multi-thread", "signal", "time", "net", "fs" ] }
tracing.workspace = true
tracing-subscriber = { workspace = true, features = [ "env-filter", "json" ] }
ncro-config.workspace = true
ncro-db.workspace = true
ncro-discovery.workspace = true
ncro-health.workspace = true
ncro-mesh.workspace = true
ncro-metrics.workspace = true
ncro-router.workspace = true
ncro-server.workspace = true
[dev-dependencies]
tempfile = "3.27.0"
tower = { version = "0.5.3", features = [ "util" ] }
tempfile.workspace = true
tower = { workspace = true, features = [ "util" ] }
# See:
# <https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html>

13
crates/config/Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "ncro-config"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
hex.workspace = true
humantime-serde.workspace = true
serde = { workspace = true, features = [ "derive" ] }
serde_yaml.workspace = true
thiserror.workspace = true
url.workspace = true

12
crates/db/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "ncro-db"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
chrono = { workspace = true, features = [ "serde" ] }
serde = { workspace = true, features = [ "derive" ] }
sqlx = { workspace = true, features = [ "runtime-tokio-rustls", "sqlite", "macros", "migrate", "chrono" ] }
thiserror.workspace = true
tokio = { workspace = true, features = [ "fs" ] }

View file

@ -0,0 +1,13 @@
[package]
name = "ncro-discovery"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
anyhow.workspace = true
mdns-sd.workspace = true
ncro-config.workspace = true
ncro-health.workspace = true
tokio = { workspace = true, features = [ "rt", "sync", "time" ] }
tracing.workspace = true

View file

@ -5,10 +5,10 @@ use std::{
};
use mdns_sd::{ServiceDaemon, ServiceEvent};
use ncro_config::DiscoveryConfig;
use ncro_health::Prober;
use tokio::sync::{Mutex, watch};
use crate::{config::DiscoveryConfig, health::Prober};
pub struct Discovery {
cfg: DiscoveryConfig,
prober: Prober,

10
crates/health/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "ncro-health"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
ncro-config.workspace = true
reqwest = { workspace = true, features = [ "rustls" ] }
tokio = { workspace = true, features = [ "sync", "time", "rt" ] }

View file

@ -5,10 +5,9 @@ use std::{
time::{Duration, Instant},
};
use ncro_config::UpstreamConfig;
use tokio::sync::RwLock;
use crate::config::UpstreamConfig;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Status {
Active,

17
crates/mesh/Cargo.toml Normal file
View file

@ -0,0 +1,17 @@
[package]
name = "ncro-mesh"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
chrono.workspace = true
ed25519-dalek = { workspace = true, features = [ "rand_core" ] }
hex.workspace = true
ncro-db.workspace = true
rand.workspace = true
rmp-serde.workspace = true
serde = { workspace = true, features = [ "derive" ] }
thiserror.workspace = true
tokio = { workspace = true, features = [ "fs", "net", "rt", "sync", "time" ] }
tracing.workspace = true

View file

@ -2,13 +2,12 @@ use std::{path::Path, sync::Arc};
use chrono::Utc;
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use rand::rngs::OsRng;
use ncro_db::{Db, RouteEntry};
use rand::RngExt;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio::{net::UdpSocket, time::Duration};
use crate::db::{Db, RouteEntry};
const MAX_PACKET_SIZE: usize = 65_536;
const HEADER_SIZE: usize = 96;
@ -50,7 +49,7 @@ impl Node {
pub async fn new(key_path: &str) -> Result<Self, MeshError> {
if key_path.is_empty() {
return Ok(Self {
signing_key: Arc::new(SigningKey::generate(&mut OsRng)),
signing_key: Arc::new(SigningKey::from_bytes(&random_key_bytes())),
});
}
if let Ok(data) = tokio::fs::read(key_path).await
@ -66,7 +65,7 @@ impl Node {
if let Some(parent) = Path::new(key_path).parent() {
tokio::fs::create_dir_all(parent).await?;
}
let key = SigningKey::generate(&mut OsRng);
let key = SigningKey::from_bytes(&random_key_bytes());
tokio::fs::write(key_path, key.to_bytes()).await?;
Ok(Self {
signing_key: Arc::new(key),
@ -88,6 +87,12 @@ impl Node {
}
}
fn random_key_bytes() -> [u8; 32] {
let mut bytes = [0_u8; 32];
rand::rng().fill(&mut bytes);
bytes
}
pub fn verify(pubkey: &[u8], body: &[u8], sig: &[u8]) -> Result<(), MeshError> {
let pubkey: [u8; 32] =
pubkey.try_into().map_err(|_| MeshError::InvalidSignature)?;

View file

@ -0,0 +1,8 @@
[package]
name = "ncro-metrics"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
prometheus.workspace = true

14
crates/narinfo/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "ncro-narinfo"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
base64.workspace = true
ed25519-dalek.workspace = true
thiserror.workspace = true
[dev-dependencies]
ed25519-dalek = { workspace = true, features = [ "rand_core" ] }
rand.workspace = true

View file

@ -31,7 +31,7 @@ pub enum NarInfoError {
#[cfg(test)]
mod tests {
use ed25519_dalek::{Signer, SigningKey};
use rand::rngs::OsRng;
use rand::RngExt;
use super::*;
@ -50,7 +50,9 @@ mod tests {
#[test]
fn verifies_roundtrip_signature() -> Result<(), NarInfoError> {
let signing = SigningKey::generate(&mut OsRng);
let mut key_bytes = [0_u8; 32];
rand::rng().fill(&mut key_bytes);
let signing = SigningKey::from_bytes(&key_bytes);
let mut ni = NarInfo {
store_path: "/nix/store/abc-test".into(),
nar_hash: "sha256:abc".into(),

17
crates/router/Cargo.toml Normal file
View file

@ -0,0 +1,17 @@
[package]
name = "ncro-router"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
chrono.workspace = true
futures-util.workspace = true
ncro-db.workspace = true
ncro-health.workspace = true
ncro-metrics.workspace = true
ncro-narinfo.workspace = true
reqwest = { workspace = true, features = [ "rustls" ] }
thiserror.workspace = true
tokio = { workspace = true, features = [ "sync", "time", "rt" ] }
tracing.workspace = true

View file

@ -6,16 +6,12 @@ use std::{
use chrono::Utc;
use futures_util::{StreamExt, stream::FuturesUnordered};
use ncro_db::{Db, DbError, RouteEntry};
use ncro_health::{Prober, Status};
use ncro_narinfo::{NarInfo, NarInfoError, parse_public_key};
use thiserror::Error;
use tokio::sync::{Mutex, RwLock};
use crate::{
db::{Db, RouteEntry},
health::{Prober, Status},
metrics,
narinfo::NarInfo,
};
#[derive(Debug, Error)]
pub enum RouterError {
#[error("not found in any upstream")]
@ -27,7 +23,7 @@ pub enum RouterError {
#[error("narinfo signature verification failed")]
SignatureVerificationFailed,
#[error(transparent)]
Db(#[from] crate::db::DbError),
Db(#[from] DbError),
}
#[derive(Debug, Clone)]
@ -89,8 +85,8 @@ impl Router {
&self,
url: String,
public_key: String,
) -> Result<(), crate::narinfo::NarInfoError> {
crate::narinfo::parse_public_key(&public_key)?;
) -> Result<(), NarInfoError> {
parse_public_key(&public_key)?;
self
.inner
.upstream_keys
@ -111,7 +107,7 @@ impl Router {
if let Some(result) = self.valid_cached_route(store_hash).await? {
return Ok(result);
}
metrics::get().narinfo_cache_misses.inc();
ncro_metrics::get().narinfo_cache_misses.inc();
let lock = {
let mut inflight = self.inner.inflight.lock().await;
@ -153,7 +149,7 @@ impl Router {
if !health.as_ref().is_none_or(|h| h.status == Status::Active) {
return Ok(None);
}
metrics::get().narinfo_cache_hits.inc();
ncro_metrics::get().narinfo_cache_hits.inc();
Ok(Some(ResolveResult {
url: entry.upstream_url,
latency_ms: entry.latency_ema,
@ -219,11 +215,11 @@ impl Router {
};
};
metrics::get()
ncro_metrics::get()
.upstream_race_wins
.with_label_values(&[&winner.url])
.inc();
metrics::get()
ncro_metrics::get()
.upstream_latency
.with_label_values(&[&winner.url])
.observe(winner.latency_ms / 1000.0);

18
crates/server/Cargo.toml Normal file
View file

@ -0,0 +1,18 @@
[package]
name = "ncro-server"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
axum = { workspace = true, features = [ "macros" ] }
bytes.workspace = true
futures-util.workspace = true
ncro-config.workspace = true
ncro-db.workspace = true
ncro-health.workspace = true
ncro-metrics.workspace = true
ncro-router.workspace = true
reqwest = { workspace = true, features = [ "rustls", "stream" ] }
serde = { workspace = true, features = [ "derive" ] }
tracing.workspace = true

View file

@ -10,16 +10,12 @@ use axum::{
};
use bytes::Bytes;
use futures_util::TryStreamExt;
use ncro_config::UpstreamConfig;
use ncro_db::Db;
use ncro_health::{Prober, Status};
use ncro_router::{Router, RouterError};
use serde::Serialize;
use crate::{
config::UpstreamConfig,
db::Db,
health::{Prober, Status},
metrics,
router::{Router, RouterError},
};
#[derive(Clone)]
pub struct AppState {
router: Router,
@ -113,7 +109,7 @@ async fn health(State(state): State<Arc<AppState>>) -> Response {
async fn metrics_endpoint() -> Response {
(
[("content-type", "text/plain; version=0.0.4")],
metrics::gather(),
ncro_metrics::gather(),
)
.into_response()
}
@ -133,7 +129,7 @@ async fn narinfo(
latency_ms = result.latency_ms,
"narinfo routed"
);
metrics::get()
ncro_metrics::get()
.narinfo_requests
.with_label_values(&["200"])
.inc();
@ -154,7 +150,7 @@ async fn narinfo(
.await
},
Err(RouterError::NotFound) => {
metrics::get()
ncro_metrics::get()
.narinfo_requests
.with_label_values(&["error"])
.inc();
@ -162,7 +158,7 @@ async fn narinfo(
},
Err(err) => {
tracing::warn!(hash, error = %err, "narinfo resolve failed");
metrics::get()
ncro_metrics::get()
.narinfo_requests
.with_label_values(&["error"])
.inc();
@ -175,7 +171,7 @@ async fn nar(
State(state): State<Arc<AppState>>,
req: Request<Body>,
) -> Response {
metrics::get().nar_requests.inc();
ncro_metrics::get().nar_requests.inc();
let nar_url = req.uri().path().trim_start_matches('/').to_string();
if let Ok(Some(entry)) = state.db.get_route_by_nar_url(&nar_url).await
&& entry.is_valid()

View file

@ -1,18 +1,12 @@
use clap::Parser;
use ncro_config::Config;
use ncro_db::Db;
use ncro_discovery::Discovery;
use ncro_health::Prober;
use ncro_router::Router;
use tokio::net::TcpListener;
use tracing_subscriber::{EnvFilter, fmt};
use crate::{
config::Config,
db::Db,
discovery::Discovery,
health::Prober,
mesh,
metrics,
router::Router,
server,
};
#[derive(Debug, Parser)]
#[command(name = "ncro", version, about = "Nix Cache Route Optimizer")]
pub struct Args {
@ -26,7 +20,7 @@ pub async fn run() -> anyhow::Result<()> {
cfg.validate()?;
init_logging(&cfg.logging.level, &cfg.logging.format);
let _ = metrics::get();
let _ = ncro_metrics::get();
let db = Db::open(&cfg.cache.db_path, cfg.cache.max_entries).await?;
let prober = Prober::new(cfg.cache.latency_alpha);
@ -99,7 +93,7 @@ pub async fn run() -> anyhow::Result<()> {
_ = ticker.tick() => {
let _ = db_for_expiry.expire_old_routes().await;
let _ = db_for_expiry.expire_negatives().await;
if let Ok(count) = db_for_expiry.route_count().await { metrics::get().route_entries.set(count); }
if let Ok(count) = db_for_expiry.route_count().await { ncro_metrics::get().route_entries.set(count); }
}
}
}
@ -114,7 +108,7 @@ pub async fn run() -> anyhow::Result<()> {
}
if cfg.mesh.enabled {
let node = mesh::Node::new(&cfg.mesh.private_key_path).await?;
let node = ncro_mesh::Node::new(&cfg.mesh.private_key_path).await?;
tracing::info!(
node_id = node.id(),
public_key = hex::encode(node.public_key()),
@ -126,7 +120,7 @@ pub async fn run() -> anyhow::Result<()> {
.iter()
.filter_map(|p| hex::decode(&p.public_key).ok()?.try_into().ok())
.collect::<Vec<[u8; 32]>>();
mesh::listen_and_serve(
ncro_mesh::listen_and_serve(
&cfg.mesh.bind_addr,
db.clone(),
allowed,
@ -139,7 +133,7 @@ pub async fn run() -> anyhow::Result<()> {
.iter()
.map(|p| p.addr.clone())
.collect::<Vec<_>>();
tokio::spawn(mesh::run_gossip_loop(
tokio::spawn(ncro_mesh::run_gossip_loop(
node,
db.clone(),
peers,
@ -148,7 +142,7 @@ pub async fn run() -> anyhow::Result<()> {
));
}
let app = server::app(
let app = ncro_server::app(
router,
prober,
db,

View file

@ -1,13 +1,4 @@
mod cli;
mod config;
mod db;
mod discovery;
mod health;
mod mesh;
mod metrics;
mod narinfo;
mod router;
mod server;
#[tokio::main]
async fn main() -> anyhow::Result<()> {