|
|
|
|
@ -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<P: AsRef<Path>>(volume_path: P, upper_path: P, merged_
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_container_dev<P: AsRef<Path>>(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<P: AsRef<Path>>(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::<Vec<&str>>();
|
|
|
|
|
@ -213,8 +232,6 @@ fn init_container_env(env: &String) -> Result<()>{
|
|
|
|
|
env.split(",").map(String::from).collect::<Vec<String>>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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::<Vec<&str>>();
|
|
|
|
|
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:?}"),
|
|
|
|
|
|