diff --git a/src/main.rs b/src/main.rs index 2eabf7c..9cdbc26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use std::fs::OpenOptions; use std::os::unix::fs::OpenOptionsExt; use std::{io, fs, fmt, os, path, process, time}; use fmt::Display; @@ -162,6 +163,24 @@ fn init_container_overlay>(volume_path: P, upper_path: P, merged_ Ok(()) } +fn init_container_dev>(container_merged_path: P) -> Result<()> { + let dev_vec = ["urandom", "random", "null"]; + + for dev in dev_vec { + let host_dev_path = format!("/dev/{dev}"); + let container_dev_path = container_merged_path.as_ref().join(format!("dev/{dev}")); + + OpenOptions::new() + .create(true) + .write(true) + .read(true) + .open(&container_dev_path)?; + // 执行绑定挂载 + mount(Some(host_dev_path.as_str()), container_dev_path.to_str().unwrap(), None::<&str>, MsFlags::MS_BIND, None::<&str>)?; + } + Ok(()) +} + fn init_container_custom_volume>(container_merged_path: P, custom_volume_s: &String) -> Result<()> { for custom_volume in custom_volume_s.split(",") { let custom_volume_v = custom_volume.split(":").collect::>(); @@ -213,8 +232,6 @@ fn init_container_env(env: &String) -> Result<()>{ env.split(",").map(String::from).collect::>() }; - env_vec.push(r#"PS1=\u\h:\W\$ "#.to_string()); - for item_env in env_vec.iter() { let item_env_v = item_env.split("=").collect::>(); if item_env_v.len() == 2 { @@ -264,7 +281,15 @@ fn init_container_mount() -> Result<()> { mount(Some("proc"), "/proc", Some("proc"), mount_flags, Some(""))?; // 挂载dev - mount(Some("tmpfs"), "/dev", Some("tmpfs"), mount_flags, Some("mode=755"))?; + // mount(Some("tmpfs"), "/dev", Some("tmpfs"), mount_flags, Some("mode=755"))?; + Ok(()) +} + + +fn init_container_proc() -> Result<()> { + // 挂载proc + let mount_flags = MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID; + mount(Some("proc"), "/proc", Some("proc"), mount_flags, Some(""))?; Ok(()) } @@ -420,20 +445,37 @@ fn run_container(container_info: &ContainerInfo, is_exec_cmd: Option<&String>) - Box::new(_cb) as CloneCb } else { let _cb = || { + sethostname(USER_NAME).unwrap(); + init_container_env(&container_info.env).unwrap(); + let volume_path = extend_image(&container_info.image).unwrap(); init_container_overlay(&volume_path, &container_upper_path, &container_merged_path).unwrap(); + + // 用户自定义的文件映射 if container_info.volume.len() > 3 { // .:. 最少也要有3个字符吧 init_container_custom_volume(&container_merged_path, &container_info.volume).unwrap(); } - sethostname(USER_NAME).unwrap(); - init_container_env(&container_info.env).unwrap(); + + // rocker需要特殊处理的一些文件映射 + { // 宿主机设备透传给虚拟机 + init_container_dev(&container_merged_path).unwrap(); + } + + + // 设置pivot init_container_pivot(&container_merged_path).unwrap(); - init_container_mount().unwrap(); + + // 挂载proc + init_container_proc().unwrap(); + if container_info.log { init_container_log().unwrap(); } + + // 设置用户 init_container_user(rocker_uid, rocker_gid).unwrap(); + // 暂停等待外部主进程设置网络设备 create_pause(&container_root_pause_path).unwrap(); while container_root_pause_path.exists() { std::thread::sleep(std::time::Duration::from_millis(10)); @@ -607,6 +649,11 @@ fn stop_container(containers_id: &str, is_remove: bool) -> Result<()> { } }); } + // 卸载dev文件夹中的设备 todo + let container_dev_path = container_merged_path.join("dev"); + container_dev_path.read_dir()?.filter_map(|d|d.ok()) + .for_each(|p|{let _ = umount2(p.path().to_str().unwrap(), MntFlags::MNT_DETACH);}); + // 卸载overlayfs match umount2(container_merged_path.to_str().unwrap(), MntFlags::MNT_DETACH) { Ok(_) => println!("卸载overlayfs卷: {container_merged_path:?}"), diff --git a/test.env b/test.env index 2f3f8dd..74ad18f 100644 --- a/test.env +++ b/test.env @@ -1,6 +1,7 @@ -SHLVL=1 -PS1=(python_env) \u\h:\W\$ -PATH=/python_env/bin:/sbin:/usr/sbin:/bin:/usr/bin -VIRTUAL_ENV_PROMPT=(python_env) -VIRTUAL_ENV=/python_env -PWD=/ +LANG=C.UTF-8 +TERM=xterm +PYPY_VERSION=7.3.16 +PYTHON_GET_PIP_SHA256=95c5ee602b2f3cc50ae053d716c3c89bea62c58568f64d7d25924d399b2d5218 +PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/3843bff3a0a61da5b63ea0b7d34794c5c51a2f11/get-pip.py +PATH=/opt/pypy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +_=/usr/bin/env \ No newline at end of file