功能更新

main
阳光少年 1 year ago
parent 75a2805718
commit 21d0300c49

@ -9,7 +9,7 @@ use std::sync::OnceLock;
use nix::sched::{clone, CloneCb, CloneFlags, setns}; use nix::sched::{clone, CloneCb, CloneFlags, setns};
use nix::sys::{signal::{kill, Signal}, wait::{waitpid, WaitPidFlag}}; use nix::sys::{signal::{kill, Signal}, wait::{waitpid, WaitPidFlag}};
use nix::unistd::{dup2, pivot_root, setgid, setgroups, sethostname, setuid, Gid, Pid, Uid, User}; use nix::unistd::{dup2, getpgid, pivot_root, setgid, setgroups, sethostname, setuid, Gid, Pid, Uid, User};
use nix::mount::{mount, MntFlags, MsFlags, umount2}; use nix::mount::{mount, MntFlags, MsFlags, umount2};
use uuid; use uuid;
use toml; use toml;
@ -164,19 +164,20 @@ fn init_container_overlay<P: AsRef<Path>>(volume_path: P, upper_path: P, merged_
} }
fn init_container_dev<P: AsRef<Path>>(container_merged_path: P) -> Result<()> { fn init_container_dev<P: AsRef<Path>>(container_merged_path: P) -> Result<()> {
let dev_vec = ["urandom", "random", "null"]; let dev_vec = [("urandom", 0), ("random", 0), ("null", 0), ("zero", 0), ("shm", 1)];
for dev in dev_vec { for (dev, tp) in dev_vec {
let host_dev_path = format!("/dev/{dev}"); let host_dev_path = format!("/dev/{dev}");
let container_dev_path = container_merged_path.as_ref().join(format!("dev/{dev}")); let container_dev_path = container_merged_path.as_ref().join(format!("dev/{dev}"));
OpenOptions::new() match tp {
.create(true) 0 => {fs::File::create(&container_dev_path)?;},
.write(true) 1 => {create_dir(&container_dev_path, false)?;},
.read(true) _ => unreachable!()
.open(&container_dev_path)?; }
// 执行绑定挂载 // 执行绑定挂载
mount(Some(host_dev_path.as_str()), container_dev_path.to_str().unwrap(), None::<&str>, MsFlags::MS_BIND, None::<&str>)?; mount(Some(host_dev_path.as_str()), container_dev_path.to_str().unwrap(), Some("tmpfs"), MsFlags::MS_BIND, None::<&str>)?;
} }
Ok(()) Ok(())
} }
@ -200,21 +201,7 @@ fn init_container_custom_volume<P: AsRef<Path>>(container_merged_path: P, custom
// 创建宿主机和容器内的目录 // 创建宿主机和容器内的目录
create_dir(Path::new(host_path), true)?; create_dir(Path::new(host_path), true)?;
create_dir(&container_path, true)?; create_dir(&container_path, true)?;
mount(Some(host_path), container_path.as_str(), None::<&str>, MsFlags::MS_BIND, None::<&str>)?
// 绑定
let out = process::Command::new("mount")
.arg("-o")
.arg("bind")
.arg(host_path)
.arg(container_path)
.output()?;
if out.status.success() {
println!("创建自定义 volume: {custom_volume:?}");
} else {
let std_err = String::from_utf8_lossy(&out.stderr);
return Err(RockerError::OtherError(format!("创建volume失败: {std_err}")))
}
} }
Ok(()) Ok(())
} }
@ -258,8 +245,8 @@ fn init_container_pivot<P: AsRef<Path>>(merged_path: P) -> Result<()> {
let pwd_path = std::env::current_dir()?; let pwd_path = std::env::current_dir()?;
let pwd_str = pwd_path.to_string_lossy().to_string(); let pwd_str = pwd_path.to_string_lossy().to_string();
// 挂载bind // 挂载bind todo
mount(Some(pwd_str.as_str()), pwd_str.as_str(), Some("bind"), MsFlags::MS_BIND | MsFlags::MS_REC, Some(""))?; mount(Some(pwd_str.as_str()), pwd_str.as_str(), Some("bind"), MsFlags::MS_BIND | MsFlags::MS_REC, None::<&str>)?;
// 创建 rootfs/.pivot_root 目录用于存储 old_root // 创建 rootfs/.pivot_root 目录用于存储 old_root
let pivot_root_dir = format!("{pwd_str}/.pivot_root"); let pivot_root_dir = format!("{pwd_str}/.pivot_root");
@ -281,7 +268,7 @@ fn init_container_pivot<P: AsRef<Path>>(merged_path: P) -> Result<()> {
fn init_container_mount() -> Result<()> { fn init_container_mount() -> Result<()> {
// 挂载proc // 挂载proc
let mount_flags = MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID; let mount_flags = MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID;
mount(Some("proc"), "/proc", Some("proc"), mount_flags, Some(""))?; mount(Some("proc"), "/proc", Some("proc"), mount_flags, None::<&str>)?;
// 挂载dev // 挂载dev
// mount(Some("tmpfs"), "/dev", Some("tmpfs"), mount_flags, Some("mode=755"))?; // mount(Some("tmpfs"), "/dev", Some("tmpfs"), mount_flags, Some("mode=755"))?;
@ -292,7 +279,7 @@ fn init_container_mount() -> Result<()> {
fn init_container_proc() -> Result<()> { fn init_container_proc() -> Result<()> {
// 挂载proc // 挂载proc
let mount_flags = MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID; let mount_flags = MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID;
mount(Some("proc"), "/proc", Some("proc"), mount_flags, Some(""))?; mount(Some("proc"), "/proc", Some("proc"), mount_flags, None::<&str>)?;
Ok(()) Ok(())
} }
@ -483,7 +470,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
init_container_env(env_vec).unwrap(); init_container_env(env_vec).unwrap();
// //
init_container_pts().unwrap(); // init_container_pts().unwrap();
if container_info.log { if container_info.log {
init_container_log().unwrap(); init_container_log().unwrap();
@ -559,7 +546,8 @@ impl Display for ContainerInfo {
let volume: String = self.volume.chars().take(20).collect(); let volume: String = self.volume.chars().take(20).collect();
let env: String = self.env.chars().take(20).collect(); let env: String = self.env.chars().take(20).collect();
let run: String = self.run.chars().take(20).collect(); let run: String = self.run.chars().take(20).collect();
write!(f, "\x1b[4m{:<10} {:<8} {:<10} {:<20} {:<20} {:<20} {:<10}\x1b[24m", self.id, self.pid, self.image, run, volume, env, &self.status) let image: String = self.image.chars().take(10).collect();
write!(f, "\x1b[4m{:<10} {:<8} {:<10} {:<20} {:<20} {:<20} {:<10}\x1b[24m", self.id, self.pid, image, run, volume, env, &self.status)
} }
} }
@ -641,7 +629,7 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> {
if let Ok(container_info) = get_container_info(container_id) { if let Ok(container_info) = get_container_info(container_id) {
// 正在运行中的需要 kill // 正在运行中的需要 kill
if container_info.status == ContainerStatus::RUNNING { if container_info.status == ContainerStatus::RUNNING {
let _ = kill(Pid::from_raw(container_info.pid), Signal::SIGKILL); let _ = kill(Pid::from_raw(-container_info.pid), Signal::SIGKILL);
let pid_path = Path::new("/proc").join(container_info.pid.to_string()); let pid_path = Path::new("/proc").join(container_info.pid.to_string());
while pid_path.exists() { while pid_path.exists() {
std::thread::sleep(std::time::Duration::from_millis(10)); std::thread::sleep(std::time::Duration::from_millis(10));
@ -666,7 +654,7 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> {
} }
}); });
} }
// 卸载dev文件夹中的设备 todo // 卸载dev文件夹中的设备
let container_dev_path = container_merged_path.join("dev"); let container_dev_path = container_merged_path.join("dev");
container_dev_path.read_dir()?.filter_map(|d|d.ok()) container_dev_path.read_dir()?.filter_map(|d|d.ok())
.for_each(|p|{let _ = umount2(p.path().to_str().unwrap(), MntFlags::MNT_DETACH);}); .for_each(|p|{let _ = umount2(p.path().to_str().unwrap(), MntFlags::MNT_DETACH);});
@ -687,7 +675,7 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> {
} }
} else { } else {
println!("容器不存在: {container_id}, 强制删除"); println!("容器不存在: {container_id}, 强制删除");
// todo 需要强制删除一下目录 // 需要强制删除一下目录
match fs::remove_dir_all(&container_work_path) { match fs::remove_dir_all(&container_work_path) {
Ok(_) => println!("强制删除 {container_work_path:?} 成功"), Ok(_) => println!("强制删除 {container_work_path:?} 成功"),
Err(e) => println!("强制删除失败: {e:?}"), Err(e) => println!("强制删除失败: {e:?}"),
@ -707,7 +695,7 @@ fn main() -> Result<()>{
time::Instant::now() time::Instant::now()
}); });
let mut args = RockerArgs::parse(); let args = RockerArgs::parse();
if args.image.is_some() || args.restart.is_some() { if args.image.is_some() || args.restart.is_some() {
let container_info = match (&args.run, &args.image, &args.restart) { let container_info = match (&args.run, &args.image, &args.restart) {
(Some(cmd), Some(image), None) => { (Some(cmd), Some(image), None) => {

@ -3,55 +3,26 @@ use rand::Rng;
static NETWORK_FILE: &str = "/home/rocker/network"; static NETWORK_FILE: &str = "/home/rocker/network";
fn get_gateway_addr(addr: &str) -> String {
let prefix = &addr[..addr.len() - 1];
format!("{}0", prefix)
}
fn create_bridge_dev(bridge_name: &str) -> bool {
// brctl addbr br0
let args = ["addbr", bridge_name];
let out = std::process::Command::new("brctl")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("create_bridge_dev: {args:?}");
println!("{:?}", out);
return false
}
true
}
fn set_bridge_ip(bridge_name: &str, addr: &str) -> bool { #[derive(Debug, Clone)]
// 设置容器内从ip: ip addr add 192.168.124.1/24 dev bridge_name struct NetWrok {
let args = ["addr", "add", &format!("{addr}/24"), "dev", bridge_name]; gateway_addr: String, // 192.168.124.0
let out = std::process::Command::new("ip") bridge_addr: String, // 192.168.124.1
.args(args) slave_addr: String,
.output()
.unwrap(); bridge_name: String, // ro_uuid[:8]_1 // ip 就是 192.168.124.1
if !out.status.success() { master_veth_name: String, // ro_uuid[:8]_2 // 不分配ip 直接插到桥
println!("set_bridge_ip: {args:?}"); slave_veth_name: String, // ro_uuid[:8]_3 // ip 就是 192.168.124.3, 插在容器中
println!("{:?}", out);
return false;
}
true
} }
fn set_slave_ip(slave_veth_name: &str, addr: &str, pid: &str) -> bool {
// nsenter -t 10050 -n -- ip addr add <ip_address>/<subnet_mask> dev veth1 impl Display for NetWrok {
let args = ["-t", pid, "-n", "--", "ip", "addr", "add", &format!("{addr}/24"), "dev", slave_veth_name]; fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let out = std::process::Command::new("nsenter") write!(f, "{},{},{},{},{},{}", self.gateway_addr, self.bridge_addr, self.slave_addr, self.bridge_name, self.master_veth_name, self.slave_veth_name)
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_slave_ip: {args:?}");
println!("{:?}", out);
return false;
} }
true
} }
fn set_snat(gateway_addr: &str, bridge_name: &str, action: &str) -> bool { fn set_snat(gateway_addr: &str, bridge_name: &str, action: &str) -> bool {
// 检查是否存在 iptables -t nat -L POSTROUTING -n // 检查是否存在 iptables -t nat -L POSTROUTING -n
let args = ["-t", "nat", "-L", "POSTROUTING", "-n"]; let args = ["-t", "nat", "-L", "POSTROUTING", "-n"];
@ -83,219 +54,6 @@ fn set_snat(gateway_addr: &str, bridge_name: &str, action: &str) -> bool {
true true
} }
fn set_iptables_forward() -> bool {
// sudo sysctl net.ipv4.conf.all.forwarding=1
let args = ["net.ipv4.conf.all.forwarding=1"];
let out = std::process::Command::new("sysctl")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_iptables_forward: {args:?}");
println!("{:?}", out);
return false;
}
// sudo iptables -t filter -P FORWARD ACCEPT
let args = ["-t", "filter", "-P", "FORWARD", "ACCEPT"];
let out = std::process::Command::new("iptables")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_iptables_forward: {args:?}");
println!("{:?}", out);
return false;
}
true
}
fn set_slave_route(slave_veth_name: &str, bridge_addr: &str, pid: &str) -> bool {
// sudo nsenter -t 1851 -n -- ip route add default via 172.18.0.1 dev veth3
let args = ["-t", pid, "-n", "--", "ip", "route", "add", "default", "via", bridge_addr, "dev", slave_veth_name];
let out = std::process::Command::new("nsenter")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_slave_route: {args:?}");
println!("{:?}", out);
return false;
}
true
}
fn set_net_up(bridge_name: &str, master_veth_name: &str, pid: &str, slave_veth_name: &str) -> bool {
// sudo ip link set bridge_name up
let args = ["link", "set", bridge_name, "up"];
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_up: {args:?}");
println!("{:?}", out);
return false;
}
// sudo ip link set master_veth_name up
let args = ["link", "set", master_veth_name, "up"];
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_up: {args:?}");
println!("{:?}", out);
return false;
}
// nsenter -t 1970 -n -- ip link set dev slave_veth_name up
let args = ["-t", pid, "-n", "--", "ip", "link", "set", "dev", slave_veth_name, "up"];
let out = std::process::Command::new("nsenter")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_up: {args:?}");
println!("{:?}", out);
return false;
}
// ip link set lo up
let args = ["-t", pid, "-n", "--", "ip", "link", "set", "lo", "up"];
let out = std::process::Command::new("nsenter")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("set_up: {args:?}");
println!("{:?}", out);
return false;
}
true
}
fn set_up(dev_name: &str) {
// sudo ip link set bridge_name up
let args = ["link", "set", dev_name, "up"];
println!("set_up: {args:?}");
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", out);
}
}
fn set_route(bridge_name: &str, addr: &str) {
// ip route add 192.168.100.0/24 via 192.168.100.1 dev bridge_name
// sudo ip netns exec ns1 ip route add default via 172.18.0.1 dev veth0
// 把addr最后的1位替换为0
let gateway_addr = get_gateway_addr(addr);
// 删掉系统自动添加的 ip route del 172.18.0.0/24 dev br0
let args = ["route", "del", &format!("{gateway_addr}/24"), "dev", bridge_name];
println!("set_route: {args:?}");
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", out);
}
let args = ["route", "add", &format!("{gateway_addr}/24"), "via", addr, "dev", bridge_name];
println!("set_route: {args:?}");
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", out);
}
}
fn set_net(bridge_name: &str, addr: &str){
// sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/24 ! -o bridge_name -j MASQUERADE
let gateway_addr = get_gateway_addr(addr);
let args = ["-t", "nat", "-A", "POSTROUTING", "-s", &format!("{gateway_addr}/24"), "!", "-o", bridge_name, "-j", "MASQUERADE"];
println!("set_net: {args:?}");
let out = std::process::Command::new("iptables")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", out);
}
}
fn del_bridge(bridge_name: &str) -> bool {
// 是否还存在设备
let args = ["link", "show", bridge_name];
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if out.status.success() {
// 下线
let args = ["link", "set", bridge_name, "down"];
let _ = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
// brctl delbr br0
let args = ["delbr", bridge_name];
let out = std::process::Command::new("brctl")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("del_bridge: {args:?}");
println!("{:?}", out);
return false;
}
}
true
}
fn create_veth_pair(master_veth_name: &str, slave_veth_name: &str) -> bool {
// sudo ip link add master_veth_name type veth peer name slave_veth_name
let args = ["link", "add", master_veth_name, "type", "veth", "peer", "name", slave_veth_name];
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("create_veth_pair: {args:?}");
println!("{:?}", out);
return false;
}
return true;
}
#[derive(Debug, Clone)]
struct NetWrok {
gateway_addr: String, // 192.168.124.0
bridge_addr: String, // 192.168.124.1
slave_addr: String,
bridge_name: String, // ro_uuid[:8]_1 // ip 就是 192.168.124.1
master_veth_name: String, // ro_uuid[:8]_2 // 不分配ip 直接插到桥
slave_veth_name: String, // ro_uuid[:8]_3 // ip 就是 192.168.124.3, 插在容器中
}
impl Display for NetWrok {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{},{},{},{},{},{}", self.gateway_addr, self.bridge_addr, self.slave_addr, self.bridge_name, self.master_veth_name, self.slave_veth_name)
}
}
fn get_all_network() -> Vec<NetWrok> { fn get_all_network() -> Vec<NetWrok> {
// 打开 NETWORK_FILE 所有已经配置的信息, 如果没有则创建 // 打开 NETWORK_FILE 所有已经配置的信息, 如果没有则创建
let mut f = OpenOptions::new() let mut f = OpenOptions::new()
@ -323,21 +81,6 @@ fn get_all_network() -> Vec<NetWrok> {
all_network all_network
} }
fn master_join_bridge(bridge_name: &str, master_veth_name: &str) -> bool {
// 将主端链接到桥
//sudo brctl addif bridge_name master_veth_name
let args = ["addif", bridge_name, master_veth_name];
let out = std::process::Command::new("brctl")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("master_join_bridge: {args:?}");
println!("{:?}", out);
return false;
}
true
}
fn write_network_info(all_network: Vec<NetWrok>) { fn write_network_info(all_network: Vec<NetWrok>) {
let mut f = OpenOptions::new() let mut f = OpenOptions::new()
@ -351,85 +94,6 @@ fn write_network_info(all_network: Vec<NetWrok>) {
} }
} }
fn slave_join_bridge(slave_veth_name: &str, pid: &str) -> bool {
// 将从端 链接到容器
// sudo ip link set slave_veth_name netns 1234
let args = ["link", "set", slave_veth_name, "netns", pid];
let out = std::process::Command::new("ip")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("slave_join_bridge: {args:?}");
println!("{:?}", out);
return false;
}
true
}
pub fn create_network(uuid_name: &str, pid: i32) -> bool {
// 创建一个随机地址段的 没分配过的ip
let mut all_network = get_all_network();
let mut rg = rand::thread_rng();
let network = loop {
// 生成一个随机桥ip
let base_addr = format!("10.{}.{}", rg.gen_range(0..255), rg.gen_range(0..255));
let gateway_addr = format!("{base_addr}.0");
let bridge_addr = format!("{base_addr}.1");
let slave_addr = format!("{base_addr}.3");
if all_network.iter().any(|n|n.bridge_addr == bridge_addr) == false {
let bridge_name = format!("ro_{uuid_name}_1");
let master_veth_name = format!("ro_{uuid_name}_2");
let slave_veth_name = format!("ro_{uuid_name}_3");
let net_work = NetWrok {
gateway_addr,
bridge_addr,
slave_addr,
bridge_name,
master_veth_name,
slave_veth_name,
};
break net_work;
}
};
all_network.push(network.clone());
// 写入到文件中
write_network_info(all_network);
// 系统中创建桥
if create_bridge_dev(&network.bridge_name) &&
// 给桥分配ip
set_bridge_ip(&network.bridge_name, &network.bridge_addr) &&
// 创建veth pair
create_veth_pair(&network.master_veth_name, &network.slave_veth_name) &&
// 宿主机 主pair 连接桥
master_join_bridge(&network.bridge_name, &network.master_veth_name) &&
// 把从 pair 添加到容器内
slave_join_bridge(&network.slave_veth_name, pid.to_string().as_str()) &&
// 给容器内 pair 分配ip
set_slave_ip(&network.slave_veth_name, &network.slave_addr, pid.to_string().as_str()) &&
// 激活 上线
set_net_up(&network.bridge_name, &network.master_veth_name, pid.to_string().as_str(), &&network.slave_veth_name) &&
// 访问公网设置
// 配置路由
set_slave_route(&network.slave_veth_name, &network.bridge_addr, pid.to_string().as_str()) &&
// 设置转发规则
set_iptables_forward() &&
// 设置snat
set_snat(&network.gateway_addr, &network.bridge_name, "-A") {
println!("网络设备创建完成");
true
} else {
println!("create_network failed");
remove_network(&uuid_name);
false
}
}
fn del_dev(dev_name: &str) -> bool { fn del_dev(dev_name: &str) -> bool {
// 先检查是否还有该设备 // 先检查是否还有该设备
let args = ["link", "show", dev_name]; let args = ["link", "show", dev_name];
@ -485,6 +149,81 @@ pub fn remove_network(uuid_name: &str) {
write_network_info(all_network); write_network_info(all_network);
} }
pub fn create_network(uuid_name: &str, pid: i32) -> bool {
let pid = pid.to_string();
// 创建一个随机地址段的 没分配过的ip
let mut all_network = get_all_network();
let mut rg = rand::thread_rng();
let network = loop {
// 生成一个随机桥ip
let base_addr = format!("10.{}.{}", rg.gen_range(0..255), rg.gen_range(0..255));
let gateway_addr = format!("{base_addr}.0");
let bridge_addr = format!("{base_addr}.1");
let slave_addr = format!("{base_addr}.3");
if all_network.iter().any(|n|n.bridge_addr == bridge_addr) == false {
let bridge_name = format!("ro_{uuid_name}_1");
let master_veth_name = format!("ro_{uuid_name}_2");
let slave_veth_name = format!("ro_{uuid_name}_3");
let net_work = NetWrok {
gateway_addr,
bridge_addr,
slave_addr,
bridge_name,
master_veth_name,
slave_veth_name,
};
break net_work;
}
};
all_network.push(network.clone());
// 写入到文件中
write_network_info(all_network);
let bridge_addr_24 = &format!("{}/24", &network.bridge_addr);
let slave_addr_24 = &format!("{}/24", &network.slave_addr);
let cmd_lis = vec![
vec!["brctl", "addbr", &network.bridge_name],
vec!["ip", "addr", "add", bridge_addr_24, "dev", &network.bridge_name],
vec!["ip", "link", "add", &network.master_veth_name, "type", "veth", "peer", "name", &network.slave_veth_name],
vec!["brctl", "addif", &network.bridge_name, &network.master_veth_name],
vec!["ip", "link", "set", &network.slave_veth_name, "netns", &pid],
vec!["nsenter", "-t", &pid, "-n", "--", "ip", "addr", "add", slave_addr_24, "dev", &network.slave_veth_name],
vec!["ip", "link", "set", &network.bridge_name, "up"],
vec!["ip", "link", "set", &network.master_veth_name, "up"],
vec!["nsenter", "-t", &pid, "-n", "--", "ip", "link", "set", "dev", &network.slave_veth_name, "up"],
vec!["nsenter", "-t", &pid, "-n", "--", "ip", "link", "set", "lo", "up"],
vec!["nsenter", "-t", &pid, "-n", "--", "ip", "route", "add", "default", "via", &network.bridge_addr, "dev", &network.slave_veth_name],
vec!["sysctl", "net.ipv4.conf.all.forwarding=1"],
vec!["iptables", "-t", "filter", "-P", "FORWARD", "ACCEPT"],
];
let mut f = true;
for cmd in cmd_lis {
let out = std::process::Command::new(cmd[0])
.args(&cmd[1..])
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", cmd);
println!("{:?}", out);
f = false;
break;
}
}
if f && set_snat(&network.gateway_addr, &network.bridge_name, "-A") {
println!("🟢 网络设备创建成功");
true
} else {
println!("🔴 网络设备创建失败");
remove_network(&uuid_name);
false
}
}
fn main(){ fn main(){
let container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string(); let container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string();
// create_network(&container_id, 2084); // create_network(&container_id, 2084);

Binary file not shown.

@ -1,12 +1,38 @@
import urllib.request # import urllib.request
from datetime import datetime # from datetime import datetime
import time # import time
# import mmap
# import os
# print(os.getpid())
# print(os.getpgid(os.getpid()))
while True:
time.sleep(1) # with open("./data", "r+b") as f:
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # mm = mmap.mmap(f.fileno(), 0)
print(now) # time.sleep(1000000)
# # lis = []
# # while True:
# # lis.clear()
# # for _ in range(1024 * 1024 * 400):
# # if len(lis) < 1024 * 1024 * 50:
# # lis.append(_)
# # print("Ok")
# import time
# from datetime import datetime
# import urllib.request
# while True:
# time.sleep(1)
# now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# print(now)
# try: # try:
# request = urllib.request.Request("http://www.baidu.com") # request = urllib.request.Request("http://www.baidu.com")
# with urllib.request.urlopen(request) as response: # with urllib.request.urlopen(request) as response:

Loading…
Cancel
Save