mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 20:24:31 +00:00
runk: Support list
sub-command
Support list sub-command. It will traverse the root directory, parse status file and print basic information of containers. Behavior and print format consistent with runc. To handle race with runk delete or system user modify, the loop will continue to traverse when errors are encountered. Fixes: #4362 Signed-off-by: Chen Yiyang <cyyzero@qq.com>
This commit is contained in:
parent
b8e98b175c
commit
38a3188206
27
src/tools/runk/Cargo.lock
generated
27
src/tools/runk/Cargo.lock
generated
@ -985,7 +985,9 @@ dependencies = [
|
||||
"serde_json",
|
||||
"slog",
|
||||
"slog-async",
|
||||
"tabwriter",
|
||||
"tokio",
|
||||
"users",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1166,6 +1168,15 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabwriter"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36205cfc997faadcc4b0b87aaef3fbedafe20d38d4959a7ca6ff803564051111"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take_mut"
|
||||
version = "0.2.2"
|
||||
@ -1348,12 +1359,28 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -22,6 +22,8 @@ slog-async = "2.7.0"
|
||||
tokio = { version = "1.15.0", features = ["full"] }
|
||||
serde = { version = "1.0.133", features = ["derive"] }
|
||||
serde_json = "1.0.74"
|
||||
users = "0.11.0"
|
||||
tabwriter = "1.2.1"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
|
69
src/tools/runk/src/commands/list.rs
Normal file
69
src/tools/runk/src/commands/list.rs
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2021-2022 Kata Contributors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use super::state::get_container_state_name;
|
||||
use anyhow::Result;
|
||||
use libcontainer::status::{get_current_container_state, Status};
|
||||
use liboci_cli::List;
|
||||
use oci::ContainerState;
|
||||
use slog::{info, Logger};
|
||||
use std::{fs, os::unix::prelude::MetadataExt, path::Path};
|
||||
use std::{io, io::Write};
|
||||
use tabwriter::TabWriter;
|
||||
use users::get_user_by_uid;
|
||||
|
||||
pub fn run(_: List, root: &Path, logger: &Logger) -> Result<()> {
|
||||
let mut content = String::new();
|
||||
for entry in fs::read_dir(root)? {
|
||||
let entry = entry?;
|
||||
// Possibly race with runk delete, so continue loop when any error occurs below
|
||||
let metadata = match entry.metadata() {
|
||||
Ok(metadata) => metadata,
|
||||
Err(_) => continue,
|
||||
};
|
||||
if !metadata.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let container_id = match entry.file_name().into_string() {
|
||||
Ok(id) => id,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let status = match Status::load(root, &container_id) {
|
||||
Ok(status) => status,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let state = match get_current_container_state(&status) {
|
||||
Ok(state) => state,
|
||||
Err(_) => continue,
|
||||
};
|
||||
// Just like runc, pid of stopped container is 0
|
||||
let pid = match state {
|
||||
ContainerState::Stopped => 0,
|
||||
_ => status.pid,
|
||||
};
|
||||
// May replace get_user_by_uid with getpwuid(3)
|
||||
let owner = match get_user_by_uid(metadata.uid()) {
|
||||
Some(user) => String::from(user.name().to_string_lossy()),
|
||||
None => format!("#{}", metadata.uid()),
|
||||
};
|
||||
content.push_str(&format!(
|
||||
"{}\t{}\t{}\t{}\t{}\t{}\n",
|
||||
container_id,
|
||||
pid,
|
||||
get_container_state_name(state),
|
||||
status.bundle.display(),
|
||||
status.created,
|
||||
owner
|
||||
));
|
||||
}
|
||||
|
||||
let mut tab_writer = TabWriter::new(io::stdout());
|
||||
writeln!(&mut tab_writer, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER")?;
|
||||
write!(&mut tab_writer, "{}", content)?;
|
||||
tab_writer.flush()?;
|
||||
|
||||
info!(&logger, "list command finished successfully");
|
||||
Ok(())
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
pub mod create;
|
||||
pub mod delete;
|
||||
pub mod kill;
|
||||
pub mod list;
|
||||
pub mod run;
|
||||
pub mod spec;
|
||||
pub mod start;
|
||||
|
@ -78,6 +78,7 @@ async fn cmd_run(subcmd: SubCommand, root_path: &Path, logger: &Logger) -> Resul
|
||||
SubCommand::Common(cmd) => match cmd {
|
||||
CommonCmd::Run(run) => commands::run::run(run, root_path, logger).await,
|
||||
CommonCmd::Spec(spec) => commands::spec::run(spec, logger),
|
||||
CommonCmd::List(list) => commands::list::run(list, root_path, logger),
|
||||
_ => {
|
||||
return Err(anyhow!("command is not implemented yet"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user