feat(cni): add unit test for commands (#70)

This commit is contained in:
Samuel Dai 2025-04-16 17:01:44 +08:00 committed by GitHub
parent 6ecde71c52
commit edf5d68d0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 427 additions and 178 deletions

218
Cargo.lock generated
View File

@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
dependencies = [
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -182,7 +182,7 @@ dependencies = [
"actix-router",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -252,6 +252,56 @@ dependencies = [
"alloc-no-stdlib",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.95"
@ -283,7 +333,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -294,7 +344,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -517,7 +567,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
name = "cni"
version = "0.1.0"
dependencies = [
"defer",
"dotenv",
"env_logger 0.11.8",
"lazy_static",
"log",
"my-workspace-hack",
@ -525,6 +577,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "config"
version = "0.11.0"
@ -672,7 +730,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -694,9 +752,15 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core 0.20.10",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
name = "defer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930c7171c8df9fb1782bdf9b918ed9ed2d33d1d22300abb754f9085bc48bf8e8"
[[package]]
name = "deranged"
version = "0.3.11"
@ -724,7 +788,7 @@ dependencies = [
"darling 0.20.10",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -734,7 +798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -747,7 +811,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -768,7 +832,7 @@ dependencies = [
"convert_case 0.7.1",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
"unicode-xid",
]
@ -790,7 +854,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -814,6 +878,16 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.10.2"
@ -827,6 +901,19 @@ dependencies = [
"termcolor",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -849,7 +936,7 @@ version = "0.1.0"
dependencies = [
"actix-web",
"dotenv",
"env_logger",
"env_logger 0.10.2",
"log",
"my-workspace-hack",
"provider",
@ -967,7 +1054,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1042,7 +1129,7 @@ dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1425,7 +1512,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1498,6 +1585,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.13.0"
@ -1513,6 +1606,30 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "jiff"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ad87c89110f55e4cd4dc2893a9790820206729eaf221555f742d540b0724a0"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde 1.0.217",
]
[[package]]
name = "jiff-static"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d076d5b64a7e2fe6f0743f02c43ca4a6725c0f904203bfe276a5b3e793103605"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "jobserver"
version = "0.1.32"
@ -1688,7 +1805,7 @@ dependencies = [
"regex-syntax",
"serde 1.0.217",
"smallvec",
"syn 2.0.96",
"syn 2.0.100",
"tokio",
"tokio-util",
"tower 0.4.13",
@ -1824,7 +1941,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1911,7 +2028,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1952,7 +2069,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -1973,6 +2090,21 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -1995,7 +2127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
dependencies = [
"proc-macro2",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2017,7 +2149,7 @@ dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2070,7 +2202,7 @@ dependencies = [
"prost",
"prost-types",
"regex",
"syn 2.0.96",
"syn 2.0.100",
"tempfile",
]
@ -2084,7 +2216,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2393,7 +2525,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2448,7 +2580,7 @@ version = "0.1.0"
dependencies = [
"cni",
"containerd-client",
"env_logger",
"env_logger 0.10.2",
"handlebars",
"hex",
"lazy_static",
@ -2565,7 +2697,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2581,9 +2713,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.96"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@ -2610,7 +2742,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2683,7 +2815,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2694,7 +2826,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2764,7 +2896,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2851,7 +2983,7 @@ dependencies = [
"prost-build",
"prost-types",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2920,7 +3052,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -2991,6 +3123,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.15.1"
@ -3058,7 +3196,7 @@ dependencies = [
"log",
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
"wasm-bindgen-shared",
]
@ -3093,7 +3231,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -3356,7 +3494,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
"synstructure",
]
@ -3378,7 +3516,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]
@ -3398,7 +3536,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
"synstructure",
]
@ -3421,7 +3559,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
"syn 2.0.100",
]
[[package]]

View File

@ -12,3 +12,5 @@ log = "0.4.27"
dotenv = "0.15.0"
netns-rs = "0.1.0"
lazy_static = "1.4.0"
env_logger = "0.11.8"
defer = "0.2.1"

92
crates/cni/src/command.rs Normal file
View File

@ -0,0 +1,92 @@
use std::{
io::Error,
process::{Command, Output},
};
lazy_static::lazy_static! {
static ref CNI_BIN_DIR: String =
std::env::var("CNI_BIN_DIR").expect("Environment variable CNI_BIN_DIR is not set");
static ref CNI_TOOL: String =
std::env::var("CNI_TOOL").expect("Environment variable CNI_TOOL is not set");
}
#[inline(always)]
fn netns_path(netns: &str) -> String {
"/var/run/netns/".to_string() + netns
}
pub(super) fn cni_add_bridge(netns: &str, bridge_network_name: &str) -> Result<Output, Error> {
Command::new(CNI_TOOL.as_str())
.arg("add")
.arg(bridge_network_name)
.arg(netns_path(netns))
.env("CNI_PATH", CNI_BIN_DIR.as_str())
.output()
}
pub(super) fn cni_del_bridge(netns: &str, bridge_network_name: &str) -> Result<Output, Error> {
Command::new(CNI_TOOL.as_str())
.arg("del")
.arg(bridge_network_name)
.arg(netns_path(netns))
.env("CNI_PATH", CNI_BIN_DIR.as_str())
.output()
}
/// THESE TESTS SHOULD BE RUN WITH ROOT PRIVILEGES
#[cfg(test)]
mod test {
use crate::{netns, util};
use std::path::Path;
use super::*;
const CNI_DATA_DIR: &str = "/var/run/cni";
const TEST_CNI_CONF_FILENAME: &str = "11-faasrstest.conflist";
const TEST_NETWORK_NAME: &str = "faasrstest-cni-bridge";
const TEST_BRIDGE_NAME: &str = "faasrstest0";
const TEST_SUBNET: &str = "10.99.0.0/16";
const CNI_CONF_DIR: &str = "/etc/cni/net.d";
fn init_test_net_fs() {
crate::util::init_net_fs(
Path::new(CNI_CONF_DIR),
TEST_CNI_CONF_FILENAME,
TEST_NETWORK_NAME,
TEST_BRIDGE_NAME,
TEST_SUBNET,
CNI_DATA_DIR,
)
.unwrap()
}
#[test]
#[ignore]
fn test_cni_resource() {
dotenv::dotenv().unwrap();
env_logger::init_from_env(env_logger::Env::new().default_filter_or("trace"));
init_test_net_fs();
let netns = util::netns_from_cid_and_cns("123456", "cns");
netns::create(&netns).unwrap();
defer::defer!({
let _ = netns::remove(&netns);
});
let result = cni_add_bridge(&netns, TEST_NETWORK_NAME);
log::debug!("add CNI result: {:?}", result);
assert!(
result.is_ok_and(|output| output.status.success()),
"Failed to add CNI"
);
defer::defer!({
let result = cni_del_bridge(&netns, TEST_NETWORK_NAME);
log::debug!("del CNI result: {:?}", result);
assert!(
result.is_ok_and(|output| output.status.success()),
"Failed to delete CNI"
);
});
}
}

View File

@ -1,23 +1,17 @@
type Err = Box<dyn std::error::Error>;
use lazy_static::lazy_static;
use netns_rs::NetNs;
use serde_json::Value;
use std::{
fmt::Error,
fs::{self, File},
io::Write,
net::IpAddr,
path::Path,
};
use std::{fmt::Error, net::IpAddr, path::Path};
mod command;
mod netns;
mod util;
use command as cmd;
lazy_static! {
static ref CNI_BIN_DIR: String =
std::env::var("CNI_BIN_DIR").expect("Environment variable CNI_BIN_DIR is not set");
static ref CNI_CONF_DIR: String =
std::env::var("CNI_CONF_DIR").expect("Environment variable CNI_CONF_DIR is not set");
static ref CNI_TOOL: String =
std::env::var("CNI_TOOL").expect("Environment variable CNI_TOOL is not set");
}
// const NET_NS_PATH_FMT: &str = "/proc/{}/ns/net";
@ -28,74 +22,25 @@ const DEFAULT_BRIDGE_NAME: &str = "faasrs0";
const DEFAULT_SUBNET: &str = "10.66.0.0/16";
// const DEFAULT_IF_PREFIX: &str = "eth";
fn default_cni_conf() -> String {
format!(
r#"
{{
"cniVersion": "0.4.0",
"name": "{}",
"plugins": [
{{
"type": "bridge",
"bridge": "{}",
"isGateway": true,
"ipMasq": true,
"ipam": {{
"type": "host-local",
"subnet": "{}",
"dataDir": "{}",
"routes": [
{{ "dst": "0.0.0.0/0" }}
]
}}
}},
{{
"type": "firewall"
}}
]
}}
"#,
DEFAULT_NETWORK_NAME, DEFAULT_BRIDGE_NAME, DEFAULT_SUBNET, CNI_DATA_DIR
pub fn init_net_work() -> Result<(), Err> {
util::init_net_fs(
Path::new(CNI_CONF_DIR.as_str()),
DEFAULT_CNI_CONF_FILENAME,
DEFAULT_NETWORK_NAME,
DEFAULT_BRIDGE_NAME,
DEFAULT_SUBNET,
CNI_DATA_DIR,
)
}
pub fn init_net_work() -> Result<(), Err> {
let cni_conf_dir = CNI_CONF_DIR.as_str();
if !dir_exists(Path::new(cni_conf_dir)) {
fs::create_dir_all(cni_conf_dir)?;
}
let net_config = Path::new(cni_conf_dir).join(DEFAULT_CNI_CONF_FILENAME);
let mut file = File::create(&net_config)?;
file.write_all(default_cni_conf().as_bytes())?;
Ok(())
}
fn get_netns(ns: &str, cid: &str) -> String {
format!("{}-{}", ns, cid)
}
fn get_path(netns: &str) -> String {
format!("/var/run/netns/{}", netns)
}
//TODO: 创建网络和删除网络的错误处理
pub fn create_cni_network(cid: String, ns: String) -> Result<(String, String), Err> {
// let netid = format!("{}-{}", cid, pid);
let netns = get_netns(ns.as_str(), cid.as_str());
let path = get_path(netns.as_str());
pub fn create_cni_network(cid: String, ns: String) -> Result<String, Err> {
let netns = util::netns_from_cid_and_cns(&cid, &ns);
let mut ip = String::new();
create_netns(&netns);
netns::create(&netns)?;
let bin = CNI_BIN_DIR.as_str();
let cnitool = CNI_TOOL.as_str();
let output = std::process::Command::new(cnitool)
.arg("add")
.arg("faasrs-cni-bridge")
.arg(&path)
.env("CNI_PATH", bin)
.output();
let output = cmd::cni_add_bridge(netns.as_str(), DEFAULT_NETWORK_NAME);
match output {
Ok(output) => {
@ -124,55 +69,14 @@ pub fn create_cni_network(cid: String, ns: String) -> Result<(String, String), E
}
}
Ok((ip, path))
Ok(ip)
}
pub fn delete_cni_network(ns: &str, cid: &str) {
let netns = get_netns(ns, cid);
let path = get_path(&netns);
let bin = CNI_BIN_DIR.as_str();
let cnitool = CNI_TOOL.as_str();
let netns = util::netns_from_cid_and_cns(cid, ns);
let _output_del = std::process::Command::new(cnitool)
.arg("del")
.arg("faasrs-cni-bridge")
.arg(&path)
.env("CNI_PATH", bin)
.output();
delete_netns(&netns);
}
fn create_netns(namespace_name: &str) {
match NetNs::new(namespace_name) {
Ok(ns) => {
log::info!("Created netns: {}", ns);
}
Err(e) => {
log::error!("Error creating netns: {}", e);
}
}
}
fn delete_netns(namespace_name: &str) {
match NetNs::get(namespace_name) {
Ok(ns) => {
ns.remove()
.map_err(|e| log::error!("Error deleting netns: {}", e))
.unwrap();
log::info!("Deleted netns: {}", namespace_name);
}
Err(e) => {
log::error!("Error getting netns: {}, NotFound", e);
}
}
}
fn dir_exists(dirname: &Path) -> bool {
path_exists(dirname).is_some_and(|info| info.is_dir())
}
fn path_exists(path: &Path) -> Option<fs::Metadata> {
fs::metadata(path).ok()
let _ = cmd::cni_del_bridge(&netns, DEFAULT_NETWORK_NAME);
let _ = netns::remove(&netns);
}
#[allow(unused)]
@ -185,14 +89,3 @@ fn cni_gateway() -> Result<String, Err> {
}
Err(Box::new(Error))
}
#[allow(unused)]
fn dir_empty(dirname: &Path) -> bool {
if !dir_exists(dirname) {
return false;
}
match fs::read_dir(dirname) {
Ok(mut entries) => entries.next().is_none(),
Err(_) => false,
}
}

32
crates/cni/src/netns.rs Normal file
View File

@ -0,0 +1,32 @@
use netns_rs::{Error, NetNs};
pub(super) fn create(netns: &str) -> Result<NetNs, Error> {
NetNs::new(netns)
}
pub(super) fn remove(netns: &str) -> Result<(), Error> {
match NetNs::get(netns) {
Ok(ns) => {
ns.remove()?;
Ok(())
}
Err(e) => {
log::error!("Failed to get netns {}: {}", netns, e);
Err(e)
}
}
}
/// THESE TESTS SHOULD BE RUN WITH ROOT PRIVILEGES
#[cfg(test)]
mod test {
use super::*;
#[test]
#[ignore]
fn test_create_and_remove() {
let netns_name = "test_netns";
create(netns_name).unwrap();
assert!(remove(netns_name).is_ok());
}
}

97
crates/cni/src/util.rs Normal file
View File

@ -0,0 +1,97 @@
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
static mut CNI_CONFIG_FILE: Option<CniConfFile> = None;
/// Generate "cns-cid"
#[inline(always)]
pub fn netns_from_cid_and_cns(cid: &str, cns: &str) -> String {
format!("{}-{}", cns, cid)
}
pub fn init_net_fs(
conf_dir: &Path,
conf_filename: &str,
net_name: &str,
bridge: &str,
subnet: &str,
data_dir: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let conf_file = CniConfFile::new(conf_dir, conf_filename, net_name, bridge, subnet, data_dir)?;
unsafe {
CNI_CONFIG_FILE = Some(conf_file);
}
Ok(())
}
fn cni_conf(name: &str, bridge: &str, subnet: &str, data_dir: &str) -> String {
format!(
r#"
{{
"cniVersion": "0.4.0",
"name": "{}",
"plugins": [
{{
"type": "bridge",
"bridge": "{}",
"isGateway": true,
"ipMasq": true,
"ipam": {{
"type": "host-local",
"subnet": "{}",
"dataDir": "{}",
"routes": [
{{ "dst": "0.0.0.0/0" }}
]
}}
}},
{{
"type": "firewall"
}}
]
}}
"#,
name, bridge, subnet, data_dir
)
}
struct CniConfFile {
conf_dir: PathBuf,
conf_filename: String,
}
impl CniConfFile {
fn new(
conf_dir: &Path,
conf_filename: &str,
net_name: &str,
bridge: &str,
subnet: &str,
data_dir: &str,
) -> Result<Self, Box<dyn std::error::Error>> {
if !conf_dir.exists() {
std::fs::create_dir_all(conf_dir)?;
}
if !conf_dir.is_dir() {
log::error!("CNI_CONF_DIR is not a directory");
panic!("CNI_CONF_DIR is not a directory");
}
let net_config = conf_dir.join(conf_filename);
File::create(&net_config)?
.write_all(cni_conf(net_name, bridge, subnet, data_dir).as_bytes())?;
Ok(Self {
conf_dir: conf_dir.to_path_buf(),
conf_filename: conf_filename.to_string(),
})
}
}
impl Drop for CniConfFile {
fn drop(&mut self) {
let net_config = self.conf_dir.join(&self.conf_filename);
if net_config.exists() {
std::fs::remove_file(&net_config).unwrap();
}
}
}

View File

@ -232,9 +232,9 @@ impl Service {
log::info!("drop sc ok");
let _ = cni::init_net_work();
log::info!("init_net_work ok");
let (ip, path) = cni::create_cni_network(cid.to_string(), ns.to_string())?;
let ip = cni::create_cni_network(cid.to_string(), ns.to_string())?;
let ports = ImageManager::get_runtime_config(img_name).unwrap().ports;
let network_config = NetworkConfig::new(path, ip, ports);
let network_config = NetworkConfig::new(ip, ports);
log::info!("create_cni_network ok");
self.save_network_config(cid, network_config.clone()).await;
log::info!("save_netns_ip ok, netconfig: {:?}", network_config);
@ -474,18 +474,13 @@ impl Service {
#[derive(Debug, Clone)]
pub struct NetworkConfig {
netns: String,
ip: String,
ports: Vec<String>,
}
impl NetworkConfig {
pub fn new(netns: String, ip: String, ports: Vec<String>) -> Self {
NetworkConfig { netns, ip, ports }
}
pub fn get_netns(&self) -> String {
self.netns.clone()
pub fn new(ip: String, ports: Vec<String>) -> Self {
NetworkConfig { ip, ports }
}
pub fn get_ip(&self) -> String {