From 0efe035cda92eddd018b939fdc0af3ae3c57c3cd Mon Sep 17 00:00:00 2001 From: Kaizen Date: Sat, 19 Oct 2024 15:01:03 +0200 Subject: [PATCH 1/4] refactor/nanocld: better init container handling (#1086) * refactor/nanocld: better init container handling * fix/ndns: network binding * fix: clippy warning * fix/nanocld: cargo start instances --- Cargo.lock | 124 ++++++----- bin/nanocl/src/config.rs | 5 +- bin/nanocld/src/objects/cargo.rs | 12 +- bin/nanocld/src/objects/job.rs | 3 +- bin/nanocld/src/objects/vm.rs | 3 +- bin/nanocld/src/repositories/cargo.rs | 21 +- bin/nanocld/src/repositories/job.rs | 3 +- bin/nanocld/src/repositories/process.rs | 4 +- bin/nanocld/src/repositories/vm.rs | 2 +- bin/nanocld/src/services/process.rs | 6 +- bin/nanocld/src/system/event.rs | 2 +- bin/nanocld/src/utils/container/cargo.rs | 240 ++++++++++++--------- bin/nanocld/src/utils/container/job.rs | 5 +- bin/nanocld/src/utils/container/process.rs | 23 +- bin/nanocld/src/utils/container/vm.rs | 6 +- bin/ncdns/src/dnsmasq.rs | 1 + bin/ndns/dnsmasq.conf | 1 + 17 files changed, 272 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8837295ae..6e14f6111 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "anymap2" @@ -490,9 +490,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cc" -version = "1.1.28" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "shlex", ] @@ -1064,9 +1064,9 @@ dependencies = [ [[package]] name = "fluent-uri" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7bd399b64ddd63a83cf40512c96007dafe9ac26cfc8c89c820a247c6f7d2376" +checksum = "1918b65d96df47d3591bed19c5cca17e3fa5d0707318e4b5ef2eae01764df7e5" dependencies = [ "borrow-or-share", "ref-cast", @@ -1439,9 +1439,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -1797,9 +1797,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1879,9 +1879,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libredox" @@ -2349,9 +2349,9 @@ dependencies = [ [[package]] name = "ntex" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93daf570cdedb9a01a3020ccd367b2ff37402b30c979aff2da23e3e84d2b6cfc" +checksum = "223834e688405dcc46b5c28bc9225648c603e64d7b61e8903da33064b6f1464e" dependencies = [ "base64", "bitflags 2.6.0", @@ -2449,9 +2449,9 @@ dependencies = [ [[package]] name = "ntex-h2" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98763f0ee78f247c02fe1bcdf6380f306a08d95169f9c2d83619d5e1cb26c738" +checksum = "8e01b86bf30768ed7dca26bf279d0e0798ba5acf0baef4b0ea8e17a91ba71ad4" dependencies = [ "bitflags 2.6.0", "fxhash", @@ -2484,14 +2484,15 @@ dependencies = [ [[package]] name = "ntex-io" -version = "2.6.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8e90ceb0a9a1bcb57459b8e14c6257519afc8dc3460d68b507fb12e909d02c" +checksum = "80c49628e35ff52f36137a8e732261f392de621406a163571888f6163e3f6b10" dependencies = [ "bitflags 2.6.0", "log", "ntex-bytes", "ntex-codec", + "ntex-rt", "ntex-service", "ntex-util", "pin-project-lite", @@ -2542,9 +2543,9 @@ dependencies = [ [[package]] name = "ntex-rt" -version = "0.4.18" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d24cfad65aab77e56ee1f1a218ca248c141a22f6f65aba8ed56037ec3c6f3a4" +checksum = "76f86c83f89053c29dcf5f1e9663c53726eea337a3221fa243e61e0410a40ad7" dependencies = [ "async-channel 2.3.1", "async-std", @@ -2579,9 +2580,9 @@ dependencies = [ [[package]] name = "ntex-service" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2cc8f131d5fed702d758485fdc45a41dfab69d8ed71b84e2b910b4ea39f795" +checksum = "02daa9c4fc8b5382b24dd69d504599a72774d6828e4fc21e9013cb62096db7aa" dependencies = [ "slab", ] @@ -2777,9 +2778,9 @@ checksum = "e296cf87e61c9cfc1a61c3c63a0f7f286ed4554e0e22be84e8a38e1d264a2a29" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -2812,9 +2813,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -2883,9 +2884,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -2894,9 +2895,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -2904,9 +2905,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", @@ -2917,9 +2918,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3055,9 +3056,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -3374,9 +3375,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "once_cell", "ring", @@ -3397,9 +3398,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -3513,9 +3514,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "67d42a0bd4ac281beff598909bb56a86acaf979b84483e1c79c10dcaf98f8cf3" dependencies = [ "itoa", "memchr", @@ -4006,12 +4007,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -4133,9 +4131,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "serde", @@ -4220,9 +4218,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -4231,9 +4229,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -4246,9 +4244,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65471f79c1022ffa5291d33520cbbb53b7687b01c2f8e83b57d102eed7ed479d" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -4258,9 +4256,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4268,9 +4266,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -4281,15 +4279,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44188d185b5bdcae1052d08bcbcf9091a5524038d4572cc4f4f2bb9d5554ddd9" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/bin/nanocl/src/config.rs b/bin/nanocl/src/config.rs index 654420371..985a78bae 100644 --- a/bin/nanocl/src/config.rs +++ b/bin/nanocl/src/config.rs @@ -46,10 +46,7 @@ impl UserConfig { Ok(s) => s, Err(_) => return UserConfig::default(), }; - match serde_yaml::from_str::(&s) { - Ok(config) => config, - Err(_) => UserConfig::default(), - } + serde_yaml::from_str::(&s).unwrap_or_default() } } diff --git a/bin/nanocld/src/objects/cargo.rs b/bin/nanocld/src/objects/cargo.rs index a8c12dab0..12a9807e5 100644 --- a/bin/nanocld/src/objects/cargo.rs +++ b/bin/nanocld/src/objects/cargo.rs @@ -89,9 +89,12 @@ impl ObjDelByPk for CargoDb { state: &SystemState, ) -> HttpResult { let cargo = CargoDb::transform_read_by_pk(pk, &state.inner.pool).await?; - let processes = - ProcessDb::read_by_kind_key(&cargo.spec.cargo_key, &state.inner.pool) - .await?; + let processes = ProcessDb::read_by_kind_key( + &cargo.spec.cargo_key, + None, + &state.inner.pool, + ) + .await?; let (_, _, _, running) = utils::container::generic::count_status(&processes); if running > 0 && !opts.force.unwrap_or(false) { @@ -272,7 +275,8 @@ impl ObjInspectByPk for CargoDb { state: &SystemState, ) -> HttpResult { let cargo = CargoDb::transform_read_by_pk(pk, &state.inner.pool).await?; - let processes = ProcessDb::read_by_kind_key(pk, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(pk, None, &state.inner.pool).await?; let (_, _, _, running_instances) = utils::container::generic::count_status(&processes); let status = ObjPsStatusDb::read_by_pk(pk, &state.inner.pool).await?; diff --git a/bin/nanocld/src/objects/job.rs b/bin/nanocld/src/objects/job.rs index 1dab59cd4..6152952d7 100644 --- a/bin/nanocld/src/objects/job.rs +++ b/bin/nanocld/src/objects/job.rs @@ -73,7 +73,8 @@ impl ObjInspectByPk for JobDb { state: &crate::models::SystemState, ) -> HttpResult { let job = JobDb::transform_read_by_pk(pk, &state.inner.pool).await?; - let instances = ProcessDb::read_by_kind_key(pk, &state.inner.pool).await?; + let instances = + ProcessDb::read_by_kind_key(pk, None, &state.inner.pool).await?; let (instance_total, instance_failed, instance_success, instance_running) = utils::container::generic::count_status(&instances); let job_inspect = JobInspect { diff --git a/bin/nanocld/src/objects/vm.rs b/bin/nanocld/src/objects/vm.rs index c864b88cb..eb351bf20 100644 --- a/bin/nanocld/src/objects/vm.rs +++ b/bin/nanocld/src/objects/vm.rs @@ -211,7 +211,8 @@ impl ObjInspectByPk for VmDb { ) -> HttpResult { let vm = VmDb::transform_read_by_pk(pk, &state.inner.pool).await?; let processes = - ProcessDb::read_by_kind_key(&vm.spec.vm_key, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&vm.spec.vm_key, None, &state.inner.pool) + .await?; let (total, _, _, running_instances) = utils::container::generic::count_status(&processes); Ok(VmInspect { diff --git a/bin/nanocld/src/repositories/cargo.rs b/bin/nanocld/src/repositories/cargo.rs index 209f7f6f3..ea5aa061b 100644 --- a/bin/nanocld/src/repositories/cargo.rs +++ b/bin/nanocld/src/repositories/cargo.rs @@ -238,17 +238,30 @@ impl CargoDb { let spec = SpecDb::read_by_pk(&cargo.spec.key, &state.inner.pool) .await? .try_to_cargo_spec()?; - let processes = - ProcessDb::read_by_kind_key(&cargo.spec.cargo_key, &state.inner.pool) - .await?; + let filter = GenericFilter::new().r#where( + "data", + GenericClause::Contains(serde_json::json!({ + "Config": { + "Labels": { + "io.nanocl.not-init-c": "true" + } + } + })), + ); + let processes = ProcessDb::read_by_kind_key( + &cargo.spec.cargo_key, + Some(filter), + &state.inner.pool, + ) + .await?; let (_, _, _, running) = utils::container::generic::count_status(&processes); cargo_summaries.push(CargoSummary { created_at: cargo.created_at, status: cargo.status, namespace_name: cargo.namespace_name, - instance_total: processes.len(), instance_running: running, + instance_total: processes.len(), spec: spec.clone(), }); } diff --git a/bin/nanocld/src/repositories/job.rs b/bin/nanocld/src/repositories/job.rs index 9ac70666f..a7087f1cc 100644 --- a/bin/nanocld/src/repositories/job.rs +++ b/bin/nanocld/src/repositories/job.rs @@ -155,7 +155,8 @@ impl JobDb { .iter() .map(|job| async { let instances = - ProcessDb::read_by_kind_key(&job.name, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&job.name, None, &state.inner.pool) + .await?; let ( instance_total, instance_failed, diff --git a/bin/nanocld/src/repositories/process.rs b/bin/nanocld/src/repositories/process.rs index 99cc8a622..1bd1f77b0 100644 --- a/bin/nanocld/src/repositories/process.rs +++ b/bin/nanocld/src/repositories/process.rs @@ -112,9 +112,11 @@ impl RepositoryReadByTransform for ProcessDb { impl ProcessDb { pub async fn read_by_kind_key( kind_key: &str, + filter: Option, pool: &Pool, ) -> IoResult> { - let filter = GenericFilter::new() + let filter = filter + .unwrap_or_default() .r#where("kind_key", GenericClause::Eq(kind_key.to_owned())); ProcessDb::transform_read_by(&filter, pool).await } diff --git a/bin/nanocld/src/repositories/vm.rs b/bin/nanocld/src/repositories/vm.rs index 85c1cede0..f689b283f 100644 --- a/bin/nanocld/src/repositories/vm.rs +++ b/bin/nanocld/src/repositories/vm.rs @@ -173,7 +173,7 @@ impl VmDb { .await? .try_to_vm_spec()?; let processes = - ProcessDb::read_by_kind_key(&vm.spec.vm_key, pool).await?; + ProcessDb::read_by_kind_key(&vm.spec.vm_key, None, pool).await?; let (_, _, _, running_instances) = utils::container::generic::count_status(&processes); vm_summaries.push(VmSummary { diff --git a/bin/nanocld/src/services/process.rs b/bin/nanocld/src/services/process.rs index c34989cfd..6bfb118e9 100644 --- a/bin/nanocld/src/services/process.rs +++ b/bin/nanocld/src/services/process.rs @@ -76,7 +76,7 @@ async fn logs_processes( let kind = kind.parse().map_err(HttpError::bad_request)?; let kind_key = utils::key::gen_kind_key(&kind, &name, &qs.namespace); let processes = - ProcessDb::read_by_kind_key(&kind_key, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&kind_key, None, &state.inner.pool).await?; log::debug!("process::logs_process: {kind_key}"); let options: LogsOptions = qs.into_inner().into(); let futures = processes @@ -337,7 +337,7 @@ pub async fn wait_processes( condition: qs.condition.clone().unwrap_or_default(), }; let processes = - ProcessDb::read_by_kind_key(&kind_pk, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&kind_pk, None, &state.inner.pool).await?; let mut streams = Vec::new(); for process in processes { let options = Some(opts.clone()); @@ -410,7 +410,7 @@ pub async fn stats_processes( let kind_key = utils::key::gen_kind_key(&kind, &name, &qs.namespace); let opts: StatsOptions = qs.clone().into(); let processes = - ProcessDb::read_by_kind_key(&kind_key, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&kind_key, None, &state.inner.pool).await?; let streams = processes .into_iter() diff --git a/bin/nanocld/src/system/event.rs b/bin/nanocld/src/system/event.rs index da41861a9..2c1e7f0cf 100644 --- a/bin/nanocld/src/system/event.rs +++ b/bin/nanocld/src/system/event.rs @@ -36,7 +36,7 @@ async fn job_ttl(actor: &EventActor, state: &SystemState) -> IoResult<()> { _ => {} } let instances = - ProcessDb::read_by_kind_key(&job.name, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&job.name, None, &state.inner.pool).await?; let (_, instance_failed, _, running) = utils::container::generic::count_status(&instances); log::debug!( diff --git a/bin/nanocld/src/utils/container/cargo.rs b/bin/nanocld/src/utils/container/cargo.rs index 809a010c5..831bd2943 100644 --- a/bin/nanocld/src/utils/container/cargo.rs +++ b/bin/nanocld/src/utils/container/cargo.rs @@ -1,7 +1,7 @@ use bollard_next::{ container::{ - RemoveContainerOptions, RenameContainerOptions, StartContainerOptions, - StopContainerOptions, WaitContainerOptions, + Config, RemoveContainerOptions, RenameContainerOptions, + StartContainerOptions, StopContainerOptions, WaitContainerOptions, }, secret::{HostConfig, RestartPolicy, RestartPolicyNameEnum}, }; @@ -25,105 +25,105 @@ use crate::{ /// Function that execute the init container before the main cargo container /// -async fn init_container( - cargo: &Cargo, +async fn start_init_container( + process: &Process, state: &SystemState, -) -> IoResult> { - match cargo.spec.init_container.clone() { - Some(mut before) => { - let image = before - .image - .clone() - .unwrap_or(cargo.spec.container.image.clone().unwrap()); - let host_config = before.host_config.unwrap_or_default(); - before.image = Some(image.clone()); - before.host_config = Some(HostConfig { - network_mode: Some( - host_config.network_mode.unwrap_or("nanoclbr0".to_owned()), - ), - ..host_config - }); - super::image::download( - &image, - cargo.spec.image_pull_secret.clone(), - cargo.spec.image_pull_policy.clone().unwrap_or_default(), - cargo, - state, - ) - .await?; - let mut labels = before.labels.to_owned().unwrap_or_default(); - labels.insert("io.nanocl.c".to_owned(), cargo.spec.cargo_key.to_owned()); - labels.insert("io.nanocl.n".to_owned(), cargo.namespace_name.to_owned()); - labels.insert("io.nanocl.init-c".to_owned(), "true".to_owned()); - labels.insert( - "com.docker.compose.project".into(), - format!("nanocl_{}", cargo.namespace_name), - ); - before.labels = Some(labels); - let short_id = utils::key::generate_short_id(6); - let name = format!( - "init-{}-{}.{}.c", - cargo.spec.name, short_id, cargo.namespace_name - ); - let process = super::process::create( - &ProcessKind::Cargo, - &name, - &cargo.spec.cargo_key, - &before, - state, - ) - .await?; - state - .inner - .docker_api - .start_container(&name, None::>) - .await - .map_err(|err| err.map_err_context(|| "InitContainer"))?; - let options = Some(WaitContainerOptions { - condition: "not-running", - }); - let mut stream = state.inner.docker_api.wait_container(&name, options); - while let Some(wait_status) = stream.next().await { - log::trace!("init_container: wait {wait_status:?}"); - match wait_status { - Ok(wait_status) => { - log::debug!("Wait status: {wait_status:?}"); - if wait_status.status_code != 0 { - let error = match wait_status.error { - Some(error) => { - error.message.unwrap_or("Unknown error".to_owned()) - } - None => "Unknown error".to_owned(), - }; - return Err(IoError::interrupted( - "InitContainer", - &format!("{error} {}", wait_status.status_code), - )); - } - } - Err(err) => { - return Err(IoError::interrupted( - "InitContainer", - &format!("{err}"), - )); - } +) -> IoResult<()> { + state + .inner + .docker_api + .start_container(&process.name, None::>) + .await + .map_err(|err| err.map_err_context(|| "InitContainer"))?; + let options = Some(WaitContainerOptions { + condition: "not-running", + }); + let mut stream = state + .inner + .docker_api + .wait_container(&process.name, options); + while let Some(wait_status) = stream.next().await { + log::trace!("init_container: wait {wait_status:?}"); + match wait_status { + Ok(wait_status) => { + log::debug!("Wait status: {wait_status:?}"); + if wait_status.status_code != 0 { + let error = match wait_status.error { + Some(error) => error.message.unwrap_or("Unknown error".to_owned()), + None => "Unknown error".to_owned(), + }; + return Err(IoError::interrupted( + "InitContainer", + &format!("{error} {}", wait_status.status_code), + )); } } - Ok(Some(process)) + Err(err) => { + return Err(IoError::interrupted("InitContainer", &format!("{err}"))); + } } - None => Ok(None), } + Ok(()) +} + +async fn create_init_container( + cargo: &Cargo, + init_container: &Config, + state: &SystemState, +) -> IoResult { + let mut init_container = init_container.clone(); + let image = init_container + .image + .clone() + .unwrap_or(cargo.spec.container.image.clone().unwrap()); + let host_config = init_container.host_config.unwrap_or_default(); + init_container.image = Some(image.clone()); + init_container.host_config = Some(HostConfig { + network_mode: Some( + host_config.network_mode.unwrap_or("nanoclbr0".to_owned()), + ), + ..host_config + }); + super::image::download( + &image, + cargo.spec.image_pull_secret.clone(), + cargo.spec.image_pull_policy.clone().unwrap_or_default(), + cargo, + state, + ) + .await?; + let mut labels = init_container.labels.to_owned().unwrap_or_default(); + labels.insert("io.nanocl.c".to_owned(), cargo.spec.cargo_key.to_owned()); + labels.insert("io.nanocl.n".to_owned(), cargo.namespace_name.to_owned()); + labels.insert("io.nanocl.init-c".to_owned(), "true".to_owned()); + labels.insert( + "com.docker.compose.project".into(), + format!("nanocl_{}", cargo.namespace_name), + ); + init_container.labels = Some(labels); + let short_id = utils::key::generate_short_id(6); + let name = format!( + "init-{}-{}.{}.c", + cargo.spec.name, short_id, cargo.namespace_name + ); + let process = super::process::create( + &ProcessKind::Cargo, + &name, + &cargo.spec.cargo_key, + &init_container, + state, + ) + .await?; + Ok(process) } /// Execute the cargo spec to create the cargo container -/// If the cargo has a init container, it will be executed before the main cargo container /// pub async fn create( cargo: &Cargo, number: usize, state: &SystemState, ) -> IoResult> { - let init_instance = init_container(cargo, state).await?; super::image::download( &cargo.spec.container.image.clone().unwrap_or_default(), cargo.spec.image_pull_secret.clone(), @@ -148,7 +148,7 @@ pub async fn create( // Flatten the secrets to have envs in a single vector secret_envs = secrets.into_iter().flatten().collect(); } - let mut instances = (0..number) + let instances = (0..number) .collect::>() .into_iter() .map(move |current| { @@ -173,8 +173,9 @@ pub async fn create( .insert("io.nanocl.c".to_owned(), cargo.spec.cargo_key.to_owned()); labels .insert("io.nanocl.n".to_owned(), cargo.namespace_name.to_owned()); + labels.insert("io.nanocl.not-init-c".to_owned(), "true".to_owned()); labels.insert( - "com.docker.compose.project".into(), + "com.docker.compose.project".to_owned(), format!("nanocl_{}", cargo.namespace_name), ); let auto_remove = host_config.auto_remove.unwrap_or(false); @@ -235,9 +236,6 @@ pub async fn create( .await .into_iter() .collect::>>()?; - if let Some(init_instance) = init_instance { - instances.insert(0, init_instance); - } Ok(instances) } @@ -245,9 +243,51 @@ pub async fn create( /// pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { let cargo = CargoDb::transform_read_by_pk(&key, &state.inner.pool).await?; - let processes = - ProcessDb::read_by_kind_key(&cargo.spec.cargo_key, &state.inner.pool) - .await?; + let filter = GenericFilter::new().r#where( + "data", + GenericClause::Contains(serde_json::json!({ + "Config": { + "Labels": { + "io.nanocl.not-init-c": "true" + } + } + })), + ); + let processes = ProcessDb::read_by_kind_key( + &cargo.spec.cargo_key, + Some(filter), + &state.inner.pool, + ) + .await?; + log::debug!( + "processes {:?}", + processes.iter().map(|p| p.name.clone()).collect::>() + ); + let filter = GenericFilter::new().r#where( + "data", + GenericClause::Contains(serde_json::json!({ + "Config": { + "Labels": { + "io.nanocl.init-c": "true" + } + } + })), + ); + let init_process = ProcessDb::read_by_kind_key( + &cargo.spec.cargo_key, + Some(filter), + &state.inner.pool, + ) + .await?; + if let Some(init_container) = &cargo.spec.init_container { + if init_process.is_empty() { + let process = + create_init_container(&cargo, init_container, state).await?; + start_init_container(&process, state).await?; + } else { + start_init_container(&init_process[0], state).await?; + } + } // TODO: FIND BEST NODES TO RUN WORKLOAD // let nodes = // MetricDb::find_best_nodes(90.0, 90.0, 100, &state.inner.pool).await?; @@ -273,7 +313,8 @@ pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { /// pub async fn update(key: &str, state: &SystemState) -> IoResult<()> { let cargo = CargoDb::transform_read_by_pk(&key, &state.inner.pool).await?; - let processes = ProcessDb::read_by_kind_key(key, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(key, None, &state.inner.pool).await?; // rename old instances to flag them for deletion processes .iter() @@ -314,6 +355,10 @@ pub async fn update(key: &str, state: &SystemState) -> IoResult<()> { _ => 1, }; // Create instance with the new spec + if let Some(init_container) = &cargo.spec.init_container { + let process = create_init_container(&cargo, init_container, state).await?; + start_init_container(&process, state).await?; + } let new_instances = match create(&cargo, number, state).await { Err(err) => { log::error!( @@ -396,7 +441,8 @@ pub async fn update(key: &str, state: &SystemState) -> IoResult<()> { /// Delete cargo instances and the cargo itself in the database /// pub async fn delete(key: &str, state: &SystemState) -> IoResult<()> { - let processes = ProcessDb::read_by_kind_key(key, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(key, None, &state.inner.pool).await?; for process in processes { let _ = state .inner diff --git a/bin/nanocld/src/utils/container/job.rs b/bin/nanocld/src/utils/container/job.rs index 935294ba8..4c01b248f 100644 --- a/bin/nanocld/src/utils/container/job.rs +++ b/bin/nanocld/src/utils/container/job.rs @@ -74,7 +74,7 @@ pub async fn create_instances( pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { let job = JobDb::transform_read_by_pk(&key, &state.inner.pool).await?; let mut processes = - ProcessDb::read_by_kind_key(&job.name, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&job.name, None, &state.inner.pool).await?; if processes.is_empty() { processes = create_instances(&job, state).await?; } @@ -115,7 +115,8 @@ pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { /// pub async fn delete(key: &str, state: &SystemState) -> IoResult<()> { let job = JobDb::transform_read_by_pk(&key, &state.inner.pool).await?; - let processes = ProcessDb::read_by_kind_key(key, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(key, None, &state.inner.pool).await?; super::process::delete_instances( &processes .iter() diff --git a/bin/nanocld/src/utils/container/process.rs b/bin/nanocld/src/utils/container/process.rs index 911451534..e420c604d 100644 --- a/bin/nanocld/src/utils/container/process.rs +++ b/bin/nanocld/src/utils/container/process.rs @@ -7,6 +7,7 @@ use futures_util::stream::FuturesUnordered; use nanocl_error::io::{FromIo, IoError, IoResult}; use nanocl_stubs::{ cargo::CargoKillOptions, + generic::{GenericClause, GenericFilter}, process::{Process, ProcessKind, ProcessPartial}, system::{NativeEventAction, ObjPsStatusKind}, }; @@ -141,7 +142,8 @@ pub async fn kill_by_kind_key( opts: &CargoKillOptions, state: &SystemState, ) -> IoResult<()> { - let processes = ProcessDb::read_by_kind_key(pk, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(pk, None, &state.inner.pool).await?; for process in processes { state .inner @@ -161,7 +163,8 @@ pub async fn restart_instances( kind: &ProcessKind, state: &SystemState, ) -> IoResult<()> { - let processes = ProcessDb::read_by_kind_key(pk, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(pk, None, &state.inner.pool).await?; for process in processes { state .inner @@ -183,7 +186,7 @@ pub async fn stop_instances( state: &SystemState, ) -> IoResult<()> { let processes = - ProcessDb::read_by_kind_key(kind_pk, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(kind_pk, None, &state.inner.pool).await?; log::debug!("stop_process_by_kind_pk: {kind_pk}"); for process in processes { state @@ -214,9 +217,21 @@ pub async fn start_instances( kind: &ProcessKind, state: &SystemState, ) -> IoResult<()> { + let filter = GenericFilter::new().r#where( + "data", + GenericClause::Contains(serde_json::json!({ + "Config": { + "Labels": { + "io.nanocl.not-init-c": "true" + } + } + })), + ); let processes = - ProcessDb::read_by_kind_key(kind_key, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(kind_key, Some(filter), &state.inner.pool) + .await?; for process in processes { + log::debug!("starting process {}", process.name); state .inner .docker_api diff --git a/bin/nanocld/src/utils/container/vm.rs b/bin/nanocld/src/utils/container/vm.rs index 9b535385f..d15f28d17 100644 --- a/bin/nanocld/src/utils/container/vm.rs +++ b/bin/nanocld/src/utils/container/vm.rs @@ -142,7 +142,8 @@ pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { let image = VmImageDb::read_by_pk(&vm.spec.disk.image, &state.inner.pool).await?; let processes = - ProcessDb::read_by_kind_key(&vm.spec.vm_key, &state.inner.pool).await?; + ProcessDb::read_by_kind_key(&vm.spec.vm_key, None, &state.inner.pool) + .await?; if processes.is_empty() { create_instance(&vm, &image, true, state).await?; } @@ -155,7 +156,8 @@ pub async fn start(key: &str, state: &SystemState) -> IoResult<()> { /// pub async fn delete(key: &str, state: &SystemState) -> IoResult<()> { let vm = VmDb::transform_read_by_pk(&key, &state.inner.pool).await?; - let processes = ProcessDb::read_by_kind_key(key, &state.inner.pool).await?; + let processes = + ProcessDb::read_by_kind_key(key, None, &state.inner.pool).await?; super::process::delete_instances( &processes .into_iter() diff --git a/bin/ncdns/src/dnsmasq.rs b/bin/ncdns/src/dnsmasq.rs index 24c166bc3..d77e9a7bf 100644 --- a/bin/ncdns/src/dnsmasq.rs +++ b/bin/ncdns/src/dnsmasq.rs @@ -63,6 +63,7 @@ no-poll no-hosts proxy-dnssec except-interface=lo +interface=nanoclbr0 conf-dir={}/dnsmasq.d,*.conf ", &self.config_dir diff --git a/bin/ndns/dnsmasq.conf b/bin/ndns/dnsmasq.conf index 6ad2278eb..35621d942 100644 --- a/bin/ndns/dnsmasq.conf +++ b/bin/ndns/dnsmasq.conf @@ -4,3 +4,4 @@ no-hosts proxy-dnssec except-interface=lo interface=nanoclbr0 +bind-dynamic From f6991c178e7fb58ddd6d290b4f4cf759161d9a6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 19 Oct 2024 15:18:33 +0200 Subject: [PATCH 2/4] build(deps): bump jsonschema from 0.22.3 to 0.23.0 (#1084) Bumps [jsonschema](https://github.com/Stranger6667/jsonschema-rs) from 0.22.3 to 0.23.0. - [Release notes](https://github.com/Stranger6667/jsonschema-rs/releases) - [Changelog](https://github.com/Stranger6667/jsonschema-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stranger6667/jsonschema-rs/compare/rust-v0.22.3...rust-v0.23.0) --- updated-dependencies: - dependency-name: jsonschema dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 ++++------ bin/nanocld/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e14f6111..638b91641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1806,9 +1806,9 @@ dependencies = [ [[package]] name = "jsonschema" -version = "0.22.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0762f81b67c46ac403497420b7f4ae457f6cdbef499d24f101bf4a63c35ddea1" +checksum = "bea85509e7320309cc8be62d8badb46f9525157bdc748bf2ec089cd4083a3f7e" dependencies = [ "ahash 0.8.11", "anyhow", @@ -1817,14 +1817,12 @@ dependencies = [ "email_address", "fancy-regex", "fraction", - "getrandom", "idna 1.0.2", "itoa", "num-cmp", "once_cell", "percent-encoding", "referencing", - "regex", "regex-syntax", "serde", "serde_json", @@ -3192,9 +3190,9 @@ dependencies = [ [[package]] name = "referencing" -version = "0.22.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43fda277062a68f002ee482f8319d2fcc84be5ff11669cacd74db7ca01f7f36a" +checksum = "35bdf02a06a0820fcb9ce064715b424f1cdd79e24f991990a92425afe11eaf4a" dependencies = [ "ahash 0.8.11", "fluent-uri", diff --git a/bin/nanocld/Cargo.toml b/bin/nanocld/Cargo.toml index f1fb3889d..3a62f7dfb 100644 --- a/bin/nanocld/Cargo.toml +++ b/bin/nanocld/Cargo.toml @@ -78,7 +78,7 @@ chrono = { version = "0.4", default-features = false, features = [ "clock", "serde", ] } -jsonschema = { version = "0.22", default-features = false } +jsonschema = { version = "0.23", default-features = false } nanocld_client = { version = "0.16", features = ["tokio"] } metrsd_client = "0.5" nanocl_stubs = { version = "0.16", features = ["serde", "clap"] } From fff136d553ceb37a001740965af752daa24eca81 Mon Sep 17 00:00:00 2001 From: Kaizen Date: Mon, 21 Oct 2024 06:39:42 +0200 Subject: [PATCH 3/4] refactor: generic network binding (#1091) --- bin/nanocld/specs/swagger.yaml | 8 +++---- bin/nanocld/src/main.rs | 1 - bin/ncdns/specs/swagger.yaml | 4 ++-- bin/ncdns/src/utils.rs | 36 ++++++++++++++++++------------ bin/ncdns/tests/resource_dns.yml | 2 +- bin/ncproxy/specs/swagger.yaml | 4 ++-- bin/ncproxy/src/utils/rule.rs | 16 ++++++------- bin/ncvpnkit/src/main.rs | 12 +++++----- crates/nanocl_stubs/src/dns.rs | 6 +++-- crates/nanocl_stubs/src/generic.rs | 28 ++++++++++++++++++++++- crates/nanocl_stubs/src/proxy.rs | 21 ++++------------- 11 files changed, 80 insertions(+), 58 deletions(-) diff --git a/bin/nanocld/specs/swagger.yaml b/bin/nanocld/specs/swagger.yaml index ca19fd224..d2fdf9719 100644 --- a/bin/nanocld/specs/swagger.yaml +++ b/bin/nanocld/specs/swagger.yaml @@ -3259,7 +3259,7 @@ components: Name: type: string IpAddress: - type: string + $ref: '#/components/schemas/NetworkKind' additionalProperties: false Driver: type: object @@ -5774,7 +5774,7 @@ components: nullable: true minimum: 0 Network: - $ref: '#/components/schemas/ProxyNetwork' + $ref: '#/components/schemas/NetworkKind' LimitReqZone: allOf: - $ref: '#/components/schemas/LimitReqZone' @@ -5805,7 +5805,7 @@ components: - Target properties: Network: - $ref: '#/components/schemas/ProxyNetwork' + $ref: '#/components/schemas/NetworkKind' Protocol: $ref: '#/components/schemas/ProxyStreamProtocol' Port: @@ -6039,7 +6039,7 @@ components: - Entries properties: Network: - type: string + $ref: '#/components/schemas/NetworkKind' Entries: type: array items: diff --git a/bin/nanocld/src/main.rs b/bin/nanocld/src/main.rs index aa48f3539..45a22580e 100644 --- a/bin/nanocld/src/main.rs +++ b/bin/nanocld/src/main.rs @@ -38,7 +38,6 @@ async fn main() -> std::io::Result<()> { err.print_and_exit(); } Ok(config) => config, - // gfg }; // Boot internal dependencies (database, event bus, etc...) let daemon_state = match system::init(&config).await { diff --git a/bin/ncdns/specs/swagger.yaml b/bin/ncdns/specs/swagger.yaml index 737425a32..ff42c983a 100644 --- a/bin/ncdns/specs/swagger.yaml +++ b/bin/ncdns/specs/swagger.yaml @@ -79,7 +79,7 @@ components: Name: type: string IpAddress: - type: string + $ref: '#/components/schemas/NetworkKind' additionalProperties: false ResourceDnsRule: type: object @@ -88,7 +88,7 @@ components: - Entries properties: Network: - type: string + $ref: '#/components/schemas/NetworkKind' Entries: type: array items: diff --git a/bin/ncdns/src/utils.rs b/bin/ncdns/src/utils.rs index 89f5dcd16..9254e4670 100644 --- a/bin/ncdns/src/utils.rs +++ b/bin/ncdns/src/utils.rs @@ -1,7 +1,9 @@ use nanocl_error::io::{FromIo, IoError, IoResult}; use nanocld_client::stubs::dns::ResourceDnsRule; -use nanocld_client::stubs::generic::{GenericClause, GenericFilter}; +use nanocld_client::stubs::generic::{ + GenericClause, GenericFilter, NetworkKind, +}; use nanocld_client::NanocldClient; use crate::dnsmasq::Dnsmasq; @@ -34,13 +36,13 @@ async fn get_bridge_addr(client: &NanocldClient) -> IoResult { /// Get network address of given network async fn get_network_addr( - network: &str, + network: &NetworkKind, client: &NanocldClient, ) -> IoResult { let addr = match network { - "Local" => "127.0.0.1".to_owned(), - "Public" => get_host_addr(client).await?, - "Internal" => get_bridge_addr(client).await?, + NetworkKind::Local => "127.0.0.1".to_owned(), + NetworkKind::Public => get_host_addr(client).await?, + NetworkKind::Internal => get_bridge_addr(client).await?, _ => { return Err(IoError::invalid_input( "Network", @@ -91,18 +93,24 @@ pub(crate) async fn update_entries( let mut file_content = format!("bind-dynamic\nlisten-address={listen_address}\n"); for entry in &entries { - let ip_address = match entry.ip_address.as_str() { - "Public" => get_host_addr(client).await?, - "Private" => "127.0.0.1".into(), - "Internal" => get_bridge_addr(client).await?, - _ => entry.ip_address.clone(), + let ip_address = match &entry.ip_address { + NetworkKind::Local => "127.0.0.1".to_owned(), + NetworkKind::Public => get_host_addr(client).await?, + NetworkKind::Internal => get_bridge_addr(client).await?, + NetworkKind::Other(ip) => ip.to_string(), + NetworkKind::All => { + return Err(IoError::invalid_input( + "Network", + "All network is not supported", + )) + } }; let entry = &format!("address=/{}/{}", entry.name, ip_address); file_content += &format!("{entry}\n"); log::debug!("utils::update_entries: {entry}"); } dnsmasq - .write_config(&dns_rule.network, &file_content) + .write_config(&dns_rule.network.to_string(), &file_content) .await?; Ok(()) } @@ -112,7 +120,7 @@ pub(crate) async fn remove_entries( dnsmasq: &Dnsmasq, client: &NanocldClient, ) -> IoResult<()> { - let content = dnsmasq.read_config(&dns_rule.network).await?; + let content = dnsmasq.read_config(&dns_rule.network.to_string()).await?; log::debug!("{}", content); let mut file_content = String::new(); let lines = content.lines(); @@ -133,11 +141,11 @@ pub(crate) async fn remove_entries( } log::debug!("{}", file_content); if file_content == empty_entries { - dnsmasq.remove_config(&dns_rule.network).await?; + dnsmasq.remove_config(&dns_rule.network.to_string()).await?; return Ok(()); } dnsmasq - .write_config(&dns_rule.network, &file_content) + .write_config(&dns_rule.network.to_string(), &file_content) .await?; Ok(()) } diff --git a/bin/ncdns/tests/resource_dns.yml b/bin/ncdns/tests/resource_dns.yml index 19c435c9f..52e1db534 100644 --- a/bin/ncdns/tests/resource_dns.yml +++ b/bin/ncdns/tests/resource_dns.yml @@ -1,6 +1,6 @@ Network: Internal Entries: - Name: test.com - IpAddress: 127.0.0.1 + IpAddress: Local - Name: test1.com IpAddress: Internal diff --git a/bin/ncproxy/specs/swagger.yaml b/bin/ncproxy/specs/swagger.yaml index aa4c15195..69bee09d5 100644 --- a/bin/ncproxy/specs/swagger.yaml +++ b/bin/ncproxy/specs/swagger.yaml @@ -148,7 +148,7 @@ components: nullable: true minimum: 0 Network: - $ref: '#/components/schemas/ProxyNetwork' + $ref: '#/components/schemas/NetworkKind' LimitReqZone: allOf: - $ref: '#/components/schemas/LimitReqZone' @@ -179,7 +179,7 @@ components: - Target properties: Network: - $ref: '#/components/schemas/ProxyNetwork' + $ref: '#/components/schemas/NetworkKind' Protocol: $ref: '#/components/schemas/ProxyStreamProtocol' Port: diff --git a/bin/ncproxy/src/utils/rule.rs b/bin/ncproxy/src/utils/rule.rs index 23540b9fc..f69c4af72 100644 --- a/bin/ncproxy/src/utils/rule.rs +++ b/bin/ncproxy/src/utils/rule.rs @@ -2,10 +2,10 @@ use nanocl_error::io::{FromIo, IoError, IoResult}; use nanocld_client::{ stubs::{ + generic::NetworkKind, process::Process, proxy::{ - ProxyNetwork, ProxySsl, ProxySslConfig, StreamTarget, UnixTarget, - UpstreamTarget, + ProxySsl, ProxySslConfig, StreamTarget, UnixTarget, UpstreamTarget, }, }, NanocldClient, @@ -94,22 +94,22 @@ pub async fn get_addresses( } pub async fn get_network_addr( - network: &ProxyNetwork, + network: &NetworkKind, port: u16, client: &NanocldClient, ) -> IoResult { match network { - ProxyNetwork::All => Ok(format!("{port}")), - ProxyNetwork::Public => { + NetworkKind::All => Ok(format!("{port}")), + NetworkKind::Public => { let ip = get_host_addr(client).await?; Ok(format!("{ip}:{port}")) } - ProxyNetwork::Local => Ok(format!("127.0.0.1:{port}")), - ProxyNetwork::Internal => { + NetworkKind::Local => Ok(format!("127.0.0.1:{port}")), + NetworkKind::Internal => { let ip = get_bridge_addr(client).await?; Ok(format!("{ip}:{port}")) } - ProxyNetwork::Other(ip) => Ok(format!("{ip}:{port}")), + NetworkKind::Other(ip) => Ok(format!("{ip}:{port}")), } } diff --git a/bin/ncvpnkit/src/main.rs b/bin/ncvpnkit/src/main.rs index 2dee2554b..7773b3553 100644 --- a/bin/ncvpnkit/src/main.rs +++ b/bin/ncvpnkit/src/main.rs @@ -7,12 +7,12 @@ use nanocl_error::io::{FromIo, IoError, IoResult}; use vpnkitrc::stubs::*; use nanocl_utils::logger; -use nanocld_client::stubs::proxy::{ - ProxyNetwork, ProxyRule, ProxyRuleStream, ProxyStreamProtocol, - ResourceProxyRule, -}; use nanocld_client::stubs::resource::Resource; use nanocld_client::stubs::system::{Event, EventActorKind, NativeEventAction}; +use nanocld_client::stubs::{ + generic::NetworkKind, + proxy::{ProxyRule, ProxyRuleStream, ProxyStreamProtocol, ResourceProxyRule}, +}; use nanocld_client::NanocldClient; mod vars; @@ -122,7 +122,7 @@ async fn on_event( for rule in r_proxy_rule.rules.into_iter() { if let ProxyRule::Stream(stream) = rule { match stream.network { - ProxyNetwork::All | ProxyNetwork::Public => {} + NetworkKind::All | NetworkKind::Public => {} _ => continue, } let port = rule_stream_to_vpnkit_port(&stream); @@ -140,7 +140,7 @@ async fn on_event( for rule in resource.rules.into_iter() { if let ProxyRule::Stream(stream) = rule { match stream.network { - ProxyNetwork::All | ProxyNetwork::Public => {} + NetworkKind::All | NetworkKind::Public => {} _ => continue, } let port = rule_stream_to_vpnkit_port(&stream); diff --git a/crates/nanocl_stubs/src/dns.rs b/crates/nanocl_stubs/src/dns.rs index af8ff56bb..0cbe127bd 100644 --- a/crates/nanocl_stubs/src/dns.rs +++ b/crates/nanocl_stubs/src/dns.rs @@ -1,6 +1,8 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::generic::NetworkKind; + #[derive(Clone, Debug)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -11,7 +13,7 @@ use serde::{Deserialize, Serialize}; )] pub struct DnsEntry { pub name: String, - pub ip_address: String, + pub ip_address: NetworkKind, } #[derive(Clone, Debug)] @@ -23,6 +25,6 @@ pub struct DnsEntry { serde(deny_unknown_fields, rename_all = "PascalCase") )] pub struct ResourceDnsRule { - pub network: String, + pub network: NetworkKind, pub entries: Vec, } diff --git a/crates/nanocl_stubs/src/generic.rs b/crates/nanocl_stubs/src/generic.rs index 801ed9e33..ab723810d 100644 --- a/crates/nanocl_stubs/src/generic.rs +++ b/crates/nanocl_stubs/src/generic.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, net::IpAddr}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -285,3 +285,29 @@ pub enum ImagePullPolicy { #[default] IfNotPresent, } + +/// Network binding kinds +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))] +pub enum NetworkKind { + All, + Local, + Public, + Internal, + Other(IpAddr), +} + +impl std::fmt::Display for NetworkKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + NetworkKind::All => write!(f, "All"), + NetworkKind::Local => write!(f, "Local"), + NetworkKind::Public => write!(f, "Public"), + NetworkKind::Internal => write!(f, "Internal"), + NetworkKind::Other(ip) => write!(f, "Ip({})", ip), + } + } +} diff --git a/crates/nanocl_stubs/src/proxy.rs b/crates/nanocl_stubs/src/proxy.rs index e93834c18..0f6a7813b 100644 --- a/crates/nanocl_stubs/src/proxy.rs +++ b/crates/nanocl_stubs/src/proxy.rs @@ -1,8 +1,8 @@ -use std::net::IpAddr; - #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::generic::NetworkKind; + /// Proxy rules modes #[derive(Debug, Clone)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] @@ -16,19 +16,6 @@ pub enum ProxyRule { Stream(ProxyRuleStream), } -#[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))] -pub enum ProxyNetwork { - All, - Local, - Public, - Internal, - Other(IpAddr), -} - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -243,7 +230,7 @@ impl std::fmt::Display for ProxyStreamProtocol { )] pub struct ProxyRuleStream { /// Type of the network binding - pub network: ProxyNetwork, + pub network: NetworkKind, /// Protocol to use Tcp | Udp pub protocol: ProxyStreamProtocol, /// The port to open on nodes @@ -347,7 +334,7 @@ pub struct ProxyRuleHttp { /// Port to listen on (default 80 or 443) pub port: Option, /// Type of network binding - pub network: ProxyNetwork, + pub network: NetworkKind, /// Optional limit request zone #[cfg_attr( feature = "serde", From 196e3e2c9c98f491c6d6d8324e898467bb180583 Mon Sep 17 00:00:00 2001 From: Leo Vernisse Date: Mon, 21 Oct 2024 16:40:53 +0200 Subject: [PATCH 4/4] feature/nanocld: inject data to cargo (#1092) --- bin/nanocld/src/utils/container/cargo.rs | 10 ++++++-- bin/nanocld/src/utils/container/generic.rs | 30 +++++++++++++++++++++- bin/nanocld/src/utils/system.rs | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/bin/nanocld/src/utils/container/cargo.rs b/bin/nanocld/src/utils/container/cargo.rs index 831bd2943..a0b9f2e54 100644 --- a/bin/nanocld/src/utils/container/cargo.rs +++ b/bin/nanocld/src/utils/container/cargo.rs @@ -23,7 +23,7 @@ use crate::{ utils, }; -/// Function that execute the init container before the main cargo container +/// Function that start and wait the status of the init container before the main cargo container /// async fn start_init_container( process: &Process, @@ -66,6 +66,8 @@ async fn start_init_container( Ok(()) } +/// Function that create the init container of the cargo +/// async fn create_init_container( cargo: &Cargo, init_container: &Config, @@ -124,11 +126,14 @@ pub async fn create( number: usize, state: &SystemState, ) -> IoResult> { + let data = serde_json::to_string(&cargo)?; + let new_data = super::generic::inject_data(&data, state).await?; + let cargo = serde_json::from_str::(&new_data)?; super::image::download( &cargo.spec.container.image.clone().unwrap_or_default(), cargo.spec.image_pull_secret.clone(), cargo.spec.image_pull_policy.clone().unwrap_or_default(), - cargo, + &cargo, state, ) .await?; @@ -152,6 +157,7 @@ pub async fn create( .collect::>() .into_iter() .map(move |current| { + let cargo = cargo.clone(); let secret_envs = secret_envs.clone(); async move { let ordinal_index = if current > 0 { diff --git a/bin/nanocld/src/utils/container/generic.rs b/bin/nanocld/src/utils/container/generic.rs index a294652b5..3278606ed 100644 --- a/bin/nanocld/src/utils/container/generic.rs +++ b/bin/nanocld/src/utils/container/generic.rs @@ -1,4 +1,5 @@ -use nanocl_error::io::IoResult; +use bollard_next::network::InspectNetworkOptions; +use nanocl_error::io::{IoError, IoResult}; use nanocl_stubs::{ process::{Process, ProcessKind}, system::{NativeEventAction, ObjPsStatusKind}, @@ -142,3 +143,30 @@ pub async fn emit_stopping( emit(kind_key, kind, NativeEventAction::Stopping, state).await?; Ok(()) } + +/// Inject data into the payload +/// eg: $$INTERNAL_GATEWAY +pub async fn inject_data(data: &str, state: &SystemState) -> IoResult { + let network_gateway = state + .inner + .docker_api + .inspect_network("nanoclbr0", None::>) + .await + .map_err(|err| { + IoError::interrupted( + "Network", + &format!("Unable to inspect network nanoclbr0 {err}"), + ) + })?; + let ipam = network_gateway.ipam.unwrap_or_default(); + let ipam_config = ipam.config.unwrap_or_default(); + let Some(network) = ipam_config.first() else { + return Err(IoError::invalid_data( + "Network", + "No network found for nanoclbr0", + )); + }; + let gateway_addr = network.gateway.clone().unwrap_or_default(); + let new_data = data.replace("$$INTERNAL_GATEWAY", &gateway_addr); + Ok(new_data) +} diff --git a/bin/nanocld/src/utils/system.rs b/bin/nanocld/src/utils/system.rs index b976a4239..700926f94 100644 --- a/bin/nanocld/src/utils/system.rs +++ b/bin/nanocld/src/utils/system.rs @@ -110,6 +110,8 @@ pub async fn register_namespace( Ok(()) } +/// Sync the cargo status with the container status. +/// We use it at startup to be sure that the cargo status is up to date. async fn sync_cargo_status( cargo: &Cargo, container: &ContainerInspectResponse,