From eeef85dd3390b3454c68506f71a685113698daf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=AB=E8=8A=B1?= Date: Tue, 8 Apr 2025 11:04:36 +0800 Subject: [PATCH] feat(cni): use environment variable to config cni tools path (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加dotenv来设定cni插件地址 * 改用lazy_static! * fmt * 增加命令执行结果的判断 --- .env | 5 ++++ Cargo.lock | 8 +++++ crates/app/Cargo.toml | 1 + crates/app/src/main.rs | 21 +++++++++++++ crates/cni/Cargo.toml | 3 +- crates/cni/src/cni_network.rs | 55 ++++++++++++++++++++++------------- 6 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..54e084f --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +# cni插件的路径 +CNI_BIN_DIR= "/opt/cni/bin" +CNI_CONF_DIR= "/etc/cni/net.d" +# 你的cnitool的路径 +CNI_TOOL = "/home/dragonos/MY/gopath/bin/cnitool" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 98cfffd..7972f74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -517,6 +517,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" name = "cni" version = "0.1.0" dependencies = [ + "lazy_static", "my-workspace-hack", "serde_json", ] @@ -758,6 +759,12 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "either" version = "1.13.0" @@ -807,6 +814,7 @@ name = "faas-rs" version = "0.1.0" dependencies = [ "actix-web", + "dotenv", "my-workspace-hack", "serde 1.0.217", "serde_json", diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index f5e8b9c..d58274b 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -10,3 +10,4 @@ service = { path = "../service" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" my-workspace-hack = { version = "0.1", path = "../my-workspace-hack" } +dotenv = "0.15" \ No newline at end of file diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index 84977b7..7dd33ab 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -10,6 +10,7 @@ use handlers::*; #[actix_web::main] async fn main() -> std::io::Result<()> { + dotenv::dotenv().ok(); let service = Arc::new( Service::new("/run/containerd/containerd.sock") .await @@ -30,3 +31,23 @@ async fn main() -> std::io::Result<()> { .run() .await } + +// 测试env能够正常获取 +#[cfg(test)] +mod tests { + #[test] + fn test_env() { + dotenv::dotenv().ok(); + let result: Vec<(String, String)> = dotenv::vars().collect(); + let bin = std::env::var("CNI_BIN_DIR").unwrap_or_else(|_| "Not set".to_string()); + let conf = std::env::var("CNI_CONF_DIR").unwrap_or_else(|_| "Not set".to_string()); + let tool = std::env::var("CNI_TOOL").unwrap_or_else(|_| "Not set".to_string()); + println!("CNI_BIN_DIR: {bin}"); + println!("CNI_CONF_DIR: {conf}"); + println!("CNI_TOOL: {tool}"); + // for (key, value) in &result { + // println!("{}={}", key, value); + // } + assert!(!result.is_empty()); + } +} diff --git a/crates/cni/Cargo.toml b/crates/cni/Cargo.toml index 982e4aa..8012e33 100644 --- a/crates/cni/Cargo.toml +++ b/crates/cni/Cargo.toml @@ -7,4 +7,5 @@ edition = "2024" [dependencies] serde_json = "1.0" -my-workspace-hack = { version = "0.1", path = "../my-workspace-hack" } \ No newline at end of file +my-workspace-hack = { version = "0.1", path = "../my-workspace-hack" } +lazy_static = "1.4.0" diff --git a/crates/cni/src/cni_network.rs b/crates/cni/src/cni_network.rs index 0a7d09d..7b81347 100644 --- a/crates/cni/src/cni_network.rs +++ b/crates/cni/src/cni_network.rs @@ -1,4 +1,5 @@ use crate::Err; +use lazy_static::lazy_static; use serde_json::Value; use std::{ fmt::Error, @@ -8,8 +9,15 @@ use std::{ path::Path, }; -const CNI_BIN_DIR: &str = "/opt/cni/bin"; -const CNI_CONF_DIR: &str = "/etc/cni/net.d"; +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"; const CNI_DATA_DIR: &str = "/var/run/cni"; const DEFAULT_CNI_CONF_FILENAME: &str = "10-faasrs.conflist"; @@ -50,10 +58,11 @@ fn default_cni_conf() -> String { } pub fn init_net_work() -> Result<(), Err> { - if !dir_exists(Path::new(CNI_CONF_DIR)) { - fs::create_dir_all(CNI_CONF_DIR)?; + 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 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())?; @@ -85,16 +94,20 @@ pub fn create_cni_network(cid: String, ns: String) -> Result<(String, String), E return Err(Box::new(Error)); } - let add_command = format!( - "export CNI_PATH={} && cnitool add faasrs-cni-bridge {}", - CNI_BIN_DIR, path - ); - let output = std::process::Command::new("sh") - .arg("-c") - .arg(&add_command) + 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(); + match output { Ok(output) => { + if !output.status.success() { + return Err(Box::new(Error)); + } let stdout = String::from_utf8_lossy(&output.stdout); let json: Value = match serde_json::from_str(&stdout) { Ok(json) => json, @@ -123,15 +136,15 @@ pub fn create_cni_network(cid: String, ns: String) -> Result<(String, String), E pub fn delete_cni_network(ns: &str, cid: &str) { let netns = get_netns(ns, cid); let path = get_path(&netns); - let del_command = format!( - "export CNI_PATH={} && cnitool del faasrs-cni-bridge {}", - CNI_BIN_DIR, path - ); - let _output_del = std::process::Command::new("sh") - .arg("-c") - .arg(&del_command) - .output() - .expect("Failed to execute del command"); + let bin = CNI_BIN_DIR.as_str(); + let cnitool = CNI_TOOL.as_str(); + + let _output_del = std::process::Command::new(cnitool) + .arg("del") + .arg("faasrs-cni-bridge") + .arg(&path) + .env("CNI_PATH", bin) + .output(); let _output = std::process::Command::new("ip") .arg("netns") .arg("delete")