|
|
@ -168,9 +168,9 @@ fn init_container_log(log: bool) -> Result<()> {
|
|
|
|
let log_path = Path::new("logs");
|
|
|
|
let log_path = Path::new("logs");
|
|
|
|
create_dir_and_set777(log_path)?;
|
|
|
|
create_dir_and_set777(log_path)?;
|
|
|
|
let log_fd = File::create(log_path.join("log"))?;
|
|
|
|
let log_fd = File::create(log_path.join("log"))?;
|
|
|
|
let log_fd_raw = log_fd.as_raw_fd();
|
|
|
|
|
|
|
|
if log {
|
|
|
|
if log {
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
let log_fd_raw = log_fd.as_raw_fd();
|
|
|
|
dup2(log_fd_raw, 1)?;
|
|
|
|
dup2(log_fd_raw, 1)?;
|
|
|
|
dup2(log_fd_raw, 2)?;
|
|
|
|
dup2(log_fd_raw, 2)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -313,7 +313,7 @@ impl Display for ContainerInfo {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::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();
|
|
|
|
write!(f, "{:<10}{:<8}{:<10}{:<20}{:<20}{:<20}{:<10}", self.id, self.pid, self.image, self.run, volume, env, &self.status)
|
|
|
|
write!(f, "\x1b[4m{:<10}{:<8}{:<10}{:<20}{:<20}{:<20}{:<10}\x1b[24m", self.id, self.pid, self.image, self.run, volume, env, &self.status)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -338,11 +338,36 @@ fn show_containers() -> Result<()> {
|
|
|
|
let containers_path = Path::new(WORKSPACE).join("containers");
|
|
|
|
let containers_path = Path::new(WORKSPACE).join("containers");
|
|
|
|
|
|
|
|
|
|
|
|
println!("{:<10}{:<8}{:<10}{:<20}{:<20}{:<20}{:<10}", "id", "pid", "image", "run", "volume", "env", "status");
|
|
|
|
println!("{:<10}{:<8}{:<10}{:<20}{:<20}{:<20}{:<10}", "id", "pid", "image", "run", "volume", "env", "status");
|
|
|
|
for entry in fs::read_dir(containers_path)? {
|
|
|
|
|
|
|
|
let path = entry?.path();
|
|
|
|
let all_container_work_path = fs::read_dir(containers_path)?
|
|
|
|
let info_path = path.join(INFO_FILE);
|
|
|
|
.map(|res| res.map(|e| e.path()))
|
|
|
|
let info_str = fs::read_to_string(info_path)?;
|
|
|
|
.filter_map(|p| p.ok())
|
|
|
|
let container_info: ContainerInfo = toml::from_str(&info_str)?;
|
|
|
|
.collect::<Vec<PathBuf>>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for container_work_path in all_container_work_path.iter() {
|
|
|
|
|
|
|
|
let info_path = container_work_path.join(INFO_FILE);
|
|
|
|
|
|
|
|
let mut container_info: ContainerInfo;
|
|
|
|
|
|
|
|
if let Ok(info_str) = fs::read_to_string(info_path) {
|
|
|
|
|
|
|
|
container_info = toml::from_str(&info_str)?;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 判断是否正在运行, 首先得到该容器所有的fd
|
|
|
|
|
|
|
|
let lock_path = container_work_path.join(LOCK_FILE);
|
|
|
|
|
|
|
|
let proc_fd_path = Path::new("/proc").join(container_info.pid.to_string()).join("fd");
|
|
|
|
|
|
|
|
let is_running = if let Ok(fd_dir) = fs::read_dir(proc_fd_path) {
|
|
|
|
|
|
|
|
fd_dir.filter_map(|p|p.ok())
|
|
|
|
|
|
|
|
.filter_map(|f| fs::read_link(f.path()).ok())
|
|
|
|
|
|
|
|
.any(|p|p == lock_path)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
false
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if is_running {
|
|
|
|
|
|
|
|
container_info.status = "✅".to_string();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
container_info.status = "❌".to_string();
|
|
|
|
|
|
|
|
}
|
|
|
|
println!("{}", container_info);
|
|
|
|
println!("{}", container_info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|