功能更新

main
阳光少年 1 year ago
parent 5bbf984a3a
commit fc78c57942

@ -23,6 +23,7 @@ install:
mkdir -p $(WORKSPACE)/images mkdir -p $(WORKSPACE)/images
mkdir -p $(WORKSPACE)/volumes mkdir -p $(WORKSPACE)/volumes
mkdir -p $(WORKSPACE)/containers mkdir -p $(WORKSPACE)/containers
touch $(WORKSPACE)/network
chmod -R 777 $(WORKSPACE) chmod -R 777 $(WORKSPACE)
cp images/* $(WORKSPACE)/images/ cp images/* $(WORKSPACE)/images/
chown -R rocker:rocker $(WORKSPACE) chown -R rocker:rocker $(WORKSPACE)

@ -1,9 +1,9 @@
use std::{io, fs, fmt, os, path, process, time}; use std::{io, fs, fmt, os, path, process, time, sync, thread, env};
use fmt::Display; use fmt::Display;
use os::fd::{AsFd, AsRawFd}; use os::fd::{AsFd, AsRawFd};
use os::unix::{fs::PermissionsExt, process::CommandExt}; use os::unix::{fs::PermissionsExt, process::CommandExt};
use path::{Path, PathBuf}; use path::{Path, PathBuf};
use std::sync::OnceLock; use sync::OnceLock;
use nix::sched::{clone, CloneCb, CloneFlags, setns}; use nix::sched::{clone, CloneCb, CloneFlags, setns};
use nix::sys::wait::{waitpid, WaitPidFlag}; use nix::sys::wait::{waitpid, WaitPidFlag};
@ -116,6 +116,7 @@ fn extend_image(image_name: &String) -> Result<PathBuf> {
let volume_path_str = volume_path.to_str().unwrap(); // 安全的unwrap let volume_path_str = volume_path.to_str().unwrap(); // 安全的unwrap
// 解压缩 // 解压缩
println!("解压镜像: {image_name:?}");
let out = process::Command::new("tar") let out = process::Command::new("tar")
.arg("-xvf") .arg("-xvf")
.arg(image_path_str) .arg(image_path_str)
@ -134,7 +135,7 @@ fn extend_image(image_name: &String) -> Result<PathBuf> {
Ok(volume_path) Ok(volume_path)
} else { } else {
// 删除 volume_path // 删除 volume_path
std::fs::remove_dir_all(volume_path)?; fs::remove_dir_all(volume_path)?;
let std_err = String::from_utf8_lossy(&out.stderr); let std_err = String::from_utf8_lossy(&out.stderr);
Err(RockerError::from(io::Error::new(io::ErrorKind::Other, format!("解压缩镜像失败: {std_err}")))) Err(RockerError::from(io::Error::new(io::ErrorKind::Other, format!("解压缩镜像失败: {std_err}"))))
} }
@ -218,8 +219,8 @@ fn init_container_custom_volume<P: AsRef<Path>>(container_merged_path: P, custom
} }
fn clear_env() { fn clear_env() {
for (k, _) in std::env::vars(){ for (k, _) in env::vars(){
std::env::remove_var(k); env::remove_var(k);
} }
} }
@ -238,7 +239,7 @@ fn init_container_env(env_vec: &Vec<String>) -> Result<()>{
for item_env in env_vec.iter() { for item_env in env_vec.iter() {
let item_env_v = item_env.split("=").collect::<Vec<&str>>(); let item_env_v = item_env.split("=").collect::<Vec<&str>>();
if item_env_v.len() == 2 { if item_env_v.len() == 2 {
std::env::set_var(item_env_v[0], item_env_v[1]) env::set_var(item_env_v[0], item_env_v[1])
} else { } else {
if item_env.len() > 0 { if item_env.len() > 0 {
println!("env 格式不正确: {item_env}") println!("env 格式不正确: {item_env}")
@ -254,8 +255,8 @@ fn init_container_pivot<P: AsRef<Path>>(merged_path: P) -> Result<()> {
mount(None::<&str>, "/", None::<&str>, MsFlags::MS_PRIVATE | MsFlags::MS_REC, None::<&str>)?; mount(None::<&str>, "/", None::<&str>, MsFlags::MS_PRIVATE | MsFlags::MS_REC, None::<&str>)?;
// 修改overlayfs 为rootfs // 修改overlayfs 为rootfs
std::env::set_current_dir(merged_path)?; env::set_current_dir(merged_path)?;
let pwd_path = std::env::current_dir()?; let pwd_path = env::current_dir()?;
let pwd_str = pwd_path.to_string_lossy().to_string(); let pwd_str = pwd_path.to_string_lossy().to_string();
// 挂载bind todo // 挂载bind todo
@ -269,11 +270,11 @@ fn init_container_pivot<P: AsRef<Path>>(merged_path: P) -> Result<()> {
pivot_root(pwd_str.as_str(), pivot_root_dir.as_str())?; pivot_root(pwd_str.as_str(), pivot_root_dir.as_str())?;
// 修改当前进程工作目录(注意我们之前已经到rootfs内, 并且把根目录设置完毕了) // 修改当前进程工作目录(注意我们之前已经到rootfs内, 并且把根目录设置完毕了)
std::env::set_current_dir("/")?; env::set_current_dir("/")?;
// 卸载 old_root, 并删除临时文件 // 卸载 old_root, 并删除临时文件
umount2(".pivot_root", MntFlags::MNT_DETACH).unwrap(); umount2(".pivot_root", MntFlags::MNT_DETACH).unwrap();
std::fs::remove_dir(".pivot_root").unwrap(); fs::remove_dir(".pivot_root").unwrap();
Ok(()) Ok(())
} }
@ -372,14 +373,14 @@ fn start(container_info: &ContainerInfo, cb: CloneCb, clong_flags: CloneFlags, c
// 删除 pause标志文件, 解开阻塞, 使其执行exec // 删除 pause标志文件, 解开阻塞, 使其执行exec
(0..100).any(|i| { (0..100).any(|i| {
std::thread::sleep(std::time::Duration::from_millis(i)); thread::sleep(time::Duration::from_millis(i));
std::fs::remove_file(container_merged_pause_path).is_ok() fs::remove_file(container_merged_pause_path).is_ok()
}); });
// 检查是否执行exec了 // 检查是否执行exec了
let main_exe = std::env::current_exe()?; let main_exe = env::current_exe()?;
for i in 0..100 { for i in 0..100 {
std::thread::sleep(std::time::Duration::from_millis(i)); thread::sleep(time::Duration::from_millis(i));
if let Ok(true) = check_container_is_running(&child_pid, &main_exe) { if let Ok(true) = check_container_is_running(&child_pid, &main_exe) {
break; break;
} }
@ -447,7 +448,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
init_container_env(&env_vec).unwrap(); init_container_env(&env_vec).unwrap();
create_pause(container_root_pause_path).unwrap(); create_pause(container_root_pause_path).unwrap();
while container_merged_pause_path.exists() { while container_merged_pause_path.exists() {
std::thread::sleep(std::time::Duration::from_millis(10)); thread::sleep(time::Duration::from_millis(10));
} }
let cmd_vec = exec_cmd.split(" ").collect::<Vec<&str>>(); let cmd_vec = exec_cmd.split(" ").collect::<Vec<&str>>();
@ -499,7 +500,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
// 暂停等待外部主进程设置网络设备 // 暂停等待外部主进程设置网络设备
create_pause(&container_root_pause_path).unwrap(); create_pause(&container_root_pause_path).unwrap();
while container_root_pause_path.exists() { while container_root_pause_path.exists() {
std::thread::sleep(std::time::Duration::from_millis(10)); thread::sleep(time::Duration::from_millis(10));
} }
let cmd_vec = container_info.run.split(" ").collect::<Vec<&str>>(); let cmd_vec = container_info.run.split(" ").collect::<Vec<&str>>();
@ -524,7 +525,7 @@ enum ContainerStatus {
} }
impl Display for ContainerStatus { impl Display for ContainerStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::READY => write!(f, "😀"), Self::READY => write!(f, "😀"),
Self::RUNNING => write!(f, "{Y}"), Self::RUNNING => write!(f, "{Y}"),
@ -561,7 +562,7 @@ impl ContainerInfo {
} }
impl Display for ContainerInfo { impl Display for ContainerInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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();

@ -1,4 +1,7 @@
use std::{fmt::{Display, Formatter}, fs::OpenOptions, io::{stdout, Read, Write}}; use std::{io, fs, fmt, path};
use fmt::{Display, Formatter};
use io::{Read, Write};
use path::Path;
use rand::Rng; use rand::Rng;
static NETWORK_FILE: &str = "/home/rocker/network"; static NETWORK_FILE: &str = "/home/rocker/network";
@ -6,8 +9,8 @@ static NETWORK_FILE: &str = "/home/rocker/network";
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct NetWrok { struct NetWrok {
gateway_addr: String, // 192.168.124.0 gateway_addr: String, // 192.168.124.0
bridge_addr: String, // 192.168.124.1 bridge_addr: String, // 192.168.124.1
slave_addr: String, slave_addr: String,
bridge_name: String, // ro_uuid[:8]_1 // ip 就是 192.168.124.1 bridge_name: String, // ro_uuid[:8]_1 // ip 就是 192.168.124.1
@ -54,17 +57,27 @@ fn set_snat(gateway_addr: &str, bridge_name: &str, action: &str) -> bool {
true true
} }
fn get_all_network() -> Vec<NetWrok> { fn take_all_network() -> Vec<NetWrok> {
// 打开 NETWORK_FILE 所有已经配置的信息, 如果没有则创建 // 打开 NETWORK_FILE 所有已经配置的信息, 如果没有则创建
let mut f = OpenOptions::new() let network_file_paht = Path::new(NETWORK_FILE);
if (0..100).any(|i| {
std::thread::sleep(std::time::Duration::from_millis(i));
network_file_paht.exists()
}) == false {
println!("🔴 网络设备逻辑锁获取失败");
};
let mut f = fs::OpenOptions::new()
.write(true) .write(true)
.create(true)
.read(true) .read(true)
.open(NETWORK_FILE) .open(NETWORK_FILE)
.unwrap(); .unwrap();
let mut text = String::new(); let mut text = String::new();
f.read_to_string(&mut text).unwrap(); f.read_to_string(&mut text).unwrap();
// 逻辑锁, 删除 NETWORK_FILE文件, 由外部修改后更新算了, 暂时这么设计
let _ = fs::remove_file(NETWORK_FILE);
let mut all_network = vec![]; let mut all_network = vec![];
for line in text.lines() { for line in text.lines() {
let network_info_vec = line.split(",").collect::<Vec<&str>>(); let network_info_vec = line.split(",").collect::<Vec<&str>>();
@ -76,14 +89,14 @@ fn get_all_network() -> Vec<NetWrok> {
master_veth_name: network_info_vec[4].to_string(), master_veth_name: network_info_vec[4].to_string(),
slave_veth_name: network_info_vec[5].to_string(), slave_veth_name: network_info_vec[5].to_string(),
}) })
} }
all_network all_network
} }
fn write_network_info(all_network: Vec<NetWrok>) { fn write_network_info(all_network: Vec<NetWrok>) {
let mut f = OpenOptions::new() let mut f = fs::OpenOptions::new()
.write(true) .write(true)
.create(true) .create(true)
.truncate(true) .truncate(true)
@ -127,7 +140,7 @@ fn del_dev(dev_name: &str) -> bool {
pub fn remove_network(uuid_name: &str) { pub fn remove_network(uuid_name: &str) {
let mut all_network = get_all_network(); let mut all_network = take_all_network();
let mut network = None; let mut network = None;
all_network = all_network.into_iter() all_network = all_network.into_iter()
.filter_map(|n| { .filter_map(|n| {
@ -144,7 +157,7 @@ pub fn remove_network(uuid_name: &str) {
del_dev(&network.master_veth_name); del_dev(&network.master_veth_name);
set_snat(&network.gateway_addr, &network.bridge_name, "-D"); set_snat(&network.gateway_addr, &network.bridge_name, "-D");
} }
// 回写到文件中 // 回写到文件中
write_network_info(all_network); write_network_info(all_network);
println!("删除网络设备: {uuid_name}"); println!("删除网络设备: {uuid_name}");
} }
@ -153,7 +166,7 @@ pub fn remove_network(uuid_name: &str) {
pub fn create_network(uuid_name: &str, pid: i32) -> bool { pub fn create_network(uuid_name: &str, pid: i32) -> bool {
let pid = pid.to_string(); let pid = pid.to_string();
// 创建一个随机地址段的 没分配过的ip // 创建一个随机地址段的 没分配过的ip
let mut all_network = get_all_network(); let mut all_network = take_all_network();
let mut rg = rand::thread_rng(); let mut rg = rand::thread_rng();
let network = loop { let network = loop {

Loading…
Cancel
Save