功能更新

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

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

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

@ -93,13 +93,6 @@ struct RockerArgs {
cgroup: Option<String>,
}
macro_rules! rocker_println {
($($arg:tt)*) => {
if cfg!(debug_assertions) {
println!($($arg)*);
}
};
}
/// 从images解压到volumes
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(())
}
fn get_env_vec(env: &String) -> Result<Vec<String>> {
fn clear_env() {
for (k, _) in std::env::vars(){
std::env::remove_var(k);
}
}
fn get_env_vec(env: &String) -> Result<Vec<String>> {
let env_vec = if env.starts_with("./") || env.starts_with("/") {
// 读取出路径指定的文件作为env
let env_text = fs::read_to_string(env)?;
@ -301,7 +296,7 @@ fn init_container_pts() -> Result<()> {
}
fn init_container_log() -> Result<()> {
let log_path = Path::new("logs");
let log_path = Path::new("/logs");
let log_file = fs::OpenOptions::new()
.append(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<()>{
match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} {
Ok(child_pid) => {
{ // 执行成功就保存吧~
let mut _container_info = container_info.clone();
_container_info.pid = child_pid.as_raw();
let _ = _container_info.flush();
}
// exec之前的步骤
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
(0..100).any(|i| {
@ -427,6 +418,8 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
} else {
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_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 = || {
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();
if container_info.root == false {
init_container_user(rocker_uid, rocker_gid).unwrap();
@ -458,6 +452,7 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) -
} else {
let _cb = || {
sethostname(USER_NAME).unwrap();
clear_env();
let env_vec = get_env_vec(&container_info.env).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
init_container_proc().unwrap();
//
// 设置自定义env
init_container_env(env_vec).unwrap();
//
@ -535,7 +530,6 @@ impl Display for ContainerStatus {
#[derive(Deserialize, Serialize, Debug, Clone)]
struct ContainerInfo {
id: String,
pid: i32,
status: ContainerStatus,
run: String, // /bin/bash
@ -546,7 +540,8 @@ struct ContainerInfo {
wait: bool,
root: bool,
cgroup_level: String, // one/two/three
cgroup_level: String, // v1/v2/v3...
procs: Vec<i32> // 动态从控制组中获取的
}
impl ContainerInfo {
@ -564,7 +559,7 @@ impl Display for ContainerInfo {
let env: String = self.env.chars().take(20).collect();
let run: String = self.run.chars().take(20).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)?;
// todo 判断当前进程组 是否还有进程
let cgroup = Cgroup::from(&container_info);
// 判断是否正在运行, 进入proc/pid/判断当前进程网络中是否有下面的设备
// let dev_path = Path::new("/proc").join(container_info.pid.to_string()).join("net").join("dev");
// 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 {
for pid in Cgroup::from(&container_info).procs {
container_info.procs.push(pid)
}
if container_info.procs.len() > 0 {
container_info.status = ContainerStatus::RUNNING;
} else {
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<()> {
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()? {
if is_show_all{
println!("{container_info}");
@ -686,7 +673,6 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> {
}
}
}
}
Ok(())
}
@ -704,7 +690,6 @@ fn main() -> Result<()>{
(Some(cmd), Some(image), None) => {
ContainerInfo {
id: uuid::Uuid::new_v4().to_string()[0..8].to_string(),
pid: -1,
run: cmd.clone(),
image: image.clone(),
volume: args.volume.clone().unwrap_or_default(),
@ -713,7 +698,8 @@ fn main() -> Result<()>{
log: args.log,
wait: args.wait,
cgroup_level: args.cgroup.clone().unwrap_or(CgroupLevel::default().to_string()),
root: args.root
root: args.root,
procs: vec![]
}
}
(None, None, Some(_container_id)) => {
@ -761,6 +747,5 @@ fn main() -> Result<()>{
println!("容器{container_id}未运行");
}
}
Ok(())
}

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

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

Loading…
Cancel
Save