功能更新

main
阳光少年 1 year ago
parent 5c6eed464c
commit e75ef3198a

@ -27,10 +27,6 @@ install:
cp images/* $(WORKSPACE)/images/ cp images/* $(WORKSPACE)/images/
chown -R rocker:rocker $(WORKSPACE) chown -R rocker:rocker $(WORKSPACE)
-mkdir /sys/fs/cgroup/rocker_1
-mkdir /sys/fs/cgroup/rocker_2
-mkdir /sys/fs/cgroup/rocker_3
clean: clean:
-./target/debug/rocker --rm all -./target/debug/rocker --rm all
-rocker --rm all -rocker --rm all

@ -9,17 +9,29 @@ use crate::error::Result;
static CGROUP_PATH: &str = "/sys/fs/cgroup/rocker"; static CGROUP_PATH: &str = "/sys/fs/cgroup/rocker";
pub enum CgroupLevel { pub enum CgroupLevel {
One, V1,
Two, V2,
Three, V3,
V4,
V5,
V6,
V7,
V8,
V9,
} }
impl From<&str> for CgroupLevel { impl From<&str> for CgroupLevel {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
match value { match value {
"1" => CgroupLevel::One, "v1" => CgroupLevel::V1,
"2" => CgroupLevel::Two, "v2" => CgroupLevel::V2,
"3" => CgroupLevel::Three, "v3" => CgroupLevel::V3,
"v4" => CgroupLevel::V4,
"v5" => CgroupLevel::V5,
"v6" => CgroupLevel::V6,
"v7" => CgroupLevel::V7,
"v8" => CgroupLevel::V8,
"v9" => CgroupLevel::V9,
_ => todo!("invalid cgroup level"), _ => todo!("invalid cgroup level"),
} }
} }
@ -28,16 +40,22 @@ impl From<&str> for CgroupLevel {
impl Display for CgroupLevel { impl Display for CgroupLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::One => write!(f, "1"), Self::V1 => write!(f, "v1"),
Self::Two => write!(f, "2"), Self::V2 => write!(f, "v2"),
Self::Three => write!(f, "3"), Self::V3 => write!(f, "v3"),
Self::V4 => write!(f, "v4"),
Self::V5 => write!(f, "v5"),
Self::V6 => write!(f, "v6"),
Self::V7 => write!(f, "v7"),
Self::V8 => write!(f, "v8"),
Self::V9 => write!(f, "v9"),
} }
} }
} }
impl Default for CgroupLevel { impl Default for CgroupLevel {
fn default() -> Self { fn default() -> Self {
CgroupLevel::One CgroupLevel::V1
} }
} }

@ -93,13 +93,6 @@ struct RockerArgs {
cgroup: Option<String>, cgroup: Option<String>,
} }
macro_rules! rocker_println {
($($arg:tt)*) => {
if cfg!(debug_assertions) {
println!($($arg)*);
}
};
}
/// 从images解压到volumes /// 从images解压到volumes
fn extend_image(image_name: &String) -> Result<PathBuf> { fn extend_image(image_name: &String) -> Result<PathBuf> {
@ -217,11 +210,13 @@ fn init_container_custom_volume<P: AsRef<Path>>(container_merged_path: P, custom
Ok(()) Ok(())
} }
fn clear_env() {
fn get_env_vec(env: &String) -> Result<Vec<String>> {
for (k, _) in std::env::vars(){ for (k, _) in std::env::vars(){
std::env::remove_var(k); std::env::remove_var(k);
} }
}
fn get_env_vec(env: &String) -> Result<Vec<String>> {
let env_vec = if env.starts_with("./") || env.starts_with("/") { let env_vec = if env.starts_with("./") || env.starts_with("/") {
// 读取出路径指定的文件作为env // 读取出路径指定的文件作为env
let env_text = fs::read_to_string(env)?; let env_text = fs::read_to_string(env)?;
@ -301,7 +296,7 @@ fn init_container_pts() -> Result<()> {
} }
fn init_container_log() -> Result<()> { fn init_container_log() -> Result<()> {
let log_path = Path::new("logs"); let log_path = Path::new("/logs");
let log_file = fs::OpenOptions::new() let log_file = fs::OpenOptions::new()
.append(true) .append(true)
.write(true) .write(true)
@ -362,15 +357,11 @@ fn create_pause(container_root_pause_path: &Path) -> Result<()> {
fn start(container_info: &ContainerInfo, cb: CloneCb, clong_flags: CloneFlags, container_merged_pause_path: &PathBuf) -> Result<()>{ fn start(container_info: &ContainerInfo, cb: CloneCb, clong_flags: CloneFlags, container_merged_pause_path: &PathBuf) -> Result<()>{
match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} { match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} {
Ok(child_pid) => { Ok(child_pid) => {
{ // 执行成功就保存吧~
let mut _container_info = container_info.clone();
_container_info.pid = child_pid.as_raw();
let _ = _container_info.flush();
}
// exec之前的步骤 // exec之前的步骤
create_network(&container_info.id, child_pid.as_raw()); create_network(&container_info.id, child_pid.as_raw());
Cgroup::create(&container_info.id, child_pid.as_raw(), CgroupLevel::from(container_info.cgroup_level.as_str()))?; if let Err(e) = Cgroup::create(&container_info.id, child_pid.as_raw(), CgroupLevel::from(container_info.cgroup_level.as_str())) {
println!("cgroup create error: {}", e)
}
// 删除 pause标志文件, 解开阻塞, 使其执行exec // 删除 pause标志文件, 解开阻塞, 使其执行exec
(0..100).any(|i| { (0..100).any(|i| {
@ -427,6 +418,8 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
} else { } else {
return Err(RockerError::OtherError("容器工作目录创建失败".to_string())); return Err(RockerError::OtherError("容器工作目录创建失败".to_string()));
} }
// 保存容器信息
let _ = container_info.flush();
let rocker_user_info = User::from_name(USER_NAME)?.ok_or(RockerError::OtherError(format!("没找到 用户: {USER_NAME}")))?; let rocker_user_info = User::from_name(USER_NAME)?.ok_or(RockerError::OtherError(format!("没找到 用户: {USER_NAME}")))?;
let rocker_uid = rocker_user_info.uid; let rocker_uid = rocker_user_info.uid;
@ -434,7 +427,8 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
let _cb = if let Some(exec_cmd) = is_exec_cmd { let _cb = if let Some(exec_cmd) = is_exec_cmd {
let _cb = || { let _cb = || {
init_exec_ns(container_info.pid).unwrap(); init_exec_ns(container_info.procs[0]).unwrap();
clear_env();
let env_vec = get_env_vec(&Default::default()).unwrap(); let env_vec = get_env_vec(&Default::default()).unwrap();
if container_info.root == false { if container_info.root == false {
init_container_user(rocker_uid, rocker_gid).unwrap(); init_container_user(rocker_uid, rocker_gid).unwrap();
@ -458,6 +452,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
} else { } else {
let _cb = || { let _cb = || {
sethostname(USER_NAME).unwrap(); sethostname(USER_NAME).unwrap();
clear_env();
let env_vec = get_env_vec(&container_info.env).unwrap(); let env_vec = get_env_vec(&container_info.env).unwrap();
let volume_path = extend_image(&container_info.image).unwrap(); let volume_path = extend_image(&container_info.image).unwrap();
@ -479,7 +474,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
// 挂载proc // 挂载proc
init_container_proc().unwrap(); init_container_proc().unwrap();
// // 设置自定义env
init_container_env(env_vec).unwrap(); init_container_env(env_vec).unwrap();
// //
@ -535,7 +530,6 @@ impl Display for ContainerStatus {
#[derive(Deserialize, Serialize, Debug, Clone)] #[derive(Deserialize, Serialize, Debug, Clone)]
struct ContainerInfo { struct ContainerInfo {
id: String, id: String,
pid: i32,
status: ContainerStatus, status: ContainerStatus,
run: String, // /bin/bash run: String, // /bin/bash
@ -545,8 +539,9 @@ struct ContainerInfo {
log: bool, log: bool,
wait: bool, wait: bool,
root: bool, root: bool,
cgroup_level: String, // one/two/three cgroup_level: String, // v1/v2/v3...
procs: Vec<i32> // 动态从控制组中获取的
} }
impl ContainerInfo { impl ContainerInfo {
@ -564,7 +559,7 @@ impl Display for ContainerInfo {
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();
let image: String = self.image.chars().take(10).collect(); 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) write!(f, "\x1b[4m{:<10} {:<10} {:<20} {:<20} {:<20} {:<10}\x1b[24m", self.id, image, run, volume, env, &self.status)
} }
} }
@ -575,18 +570,10 @@ fn get_container_info(container_id: &str) -> Result<ContainerInfo> {
let mut container_info: ContainerInfo = toml::from_str(&info_str)?; let mut container_info: ContainerInfo = toml::from_str(&info_str)?;
// todo 判断当前进程组 是否还有进程 // todo 判断当前进程组 是否还有进程
let cgroup = Cgroup::from(&container_info); for pid in Cgroup::from(&container_info).procs {
container_info.procs.push(pid)
// 判断是否正在运行, 进入proc/pid/判断当前进程网络中是否有下面的设备 }
// let dev_path = Path::new("/proc").join(container_info.pid.to_string()).join("net").join("dev"); if container_info.procs.len() > 0 {
// let is_running = if let Ok(dev_text) = fs::read_to_string(dev_path){
// let slave_veth_name = format!("ro_{container_id}_3");
// dev_text.lines().any(|l|l.starts_with(&slave_veth_name))
// } else {
// false
// };
if cgroup.procs.len() > 0 {
container_info.status = ContainerStatus::RUNNING; container_info.status = ContainerStatus::RUNNING;
} else { } else {
container_info.status = ContainerStatus::STOP; container_info.status = ContainerStatus::STOP;
@ -607,7 +594,7 @@ fn get_all_container_info() -> Result<Vec<ContainerInfo>> {
/// 读取所有容器的状态 /// 读取所有容器的状态
fn show_containers(is_show_all: bool) -> Result<()> { fn show_containers(is_show_all: bool) -> Result<()> {
println!("{:<10} {:<8} {:<10} {:<20} {:<20} {:<20} {:<10}", "id", "pid", "image", "run", "volume", "env", "status"); println!("{:<10} {:<10} {:<20} {:<20} {:<20} {:<10}", "id", "image", "run", "volume", "env", "status");
for container_info in get_all_container_info()? { for container_info in get_all_container_info()? {
if is_show_all{ if is_show_all{
println!("{container_info}"); println!("{container_info}");
@ -686,7 +673,6 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> {
} }
} }
} }
} }
Ok(()) Ok(())
} }
@ -704,7 +690,6 @@ fn main() -> Result<()>{
(Some(cmd), Some(image), None) => { (Some(cmd), Some(image), None) => {
ContainerInfo { ContainerInfo {
id: uuid::Uuid::new_v4().to_string()[0..8].to_string(), id: uuid::Uuid::new_v4().to_string()[0..8].to_string(),
pid: -1,
run: cmd.clone(), run: cmd.clone(),
image: image.clone(), image: image.clone(),
volume: args.volume.clone().unwrap_or_default(), volume: args.volume.clone().unwrap_or_default(),
@ -713,7 +698,8 @@ fn main() -> Result<()>{
log: args.log, log: args.log,
wait: args.wait, wait: args.wait,
cgroup_level: args.cgroup.clone().unwrap_or(CgroupLevel::default().to_string()), cgroup_level: args.cgroup.clone().unwrap_or(CgroupLevel::default().to_string()),
root: args.root root: args.root,
procs: vec![]
} }
} }
(None, None, Some(_container_id)) => { (None, None, Some(_container_id)) => {
@ -761,6 +747,5 @@ fn main() -> Result<()>{
println!("容器{container_id}未运行"); println!("容器{container_id}未运行");
} }
} }
Ok(()) Ok(())
} }

@ -122,7 +122,6 @@ fn del_dev(dev_name: &str) -> bool {
return false; return false;
} }
} }
true true
} }

@ -8,6 +8,10 @@ import os
import threading import threading
import ctypes import ctypes
print("hello", time.time())
exit()
def read_memory(address): def read_memory(address):
# 创建一个足够大的缓冲区来读取内存 # 创建一个足够大的缓冲区来读取内存
buffer_size = 8 # 假设我们读取的是一个64位整数 buffer_size = 8 # 假设我们读取的是一个64位整数

Loading…
Cancel
Save