diff --git a/crates/runc-shim/src/container.rs b/crates/runc-shim/src/container.rs index c5218ef..5cb7ec6 100644 --- a/crates/runc-shim/src/container.rs +++ b/crates/runc-shim/src/container.rs @@ -84,6 +84,7 @@ pub trait Container { fn pid(&self) -> i32; fn stats(&self) -> Result; fn update(&mut self, resources: &LinuxResources) -> Result<()>; + fn pids(&self) -> Result; } pub struct CommonContainer { diff --git a/crates/runc-shim/src/runc.rs b/crates/runc-shim/src/runc.rs index 21780dc..33d28a4 100644 --- a/crates/runc-shim/src/runc.rs +++ b/crates/runc-shim/src/runc.rs @@ -35,8 +35,11 @@ use shim::api::*; use shim::error::{Error, Result}; use shim::io_error; use shim::mount::mount_rootfs; +use shim::protos::api::ProcessInfo; use shim::protos::cgroups::metrics::{CPUStat, CPUUsage, MemoryEntry, MemoryStat, Metrics}; -use shim::protos::protobuf::{well_known_types::Timestamp, CodedInputStream, Message}; +use shim::protos::protobuf::well_known_types::{Any, Timestamp}; +use shim::protos::protobuf::{CodedInputStream, Message, RepeatedField}; +use shim::protos::shim::oci::ProcessDetails; use shim::util::{read_spec_from_file, write_options, write_runtime, IntoOption}; use shim::{debug, error, other, other_error}; use time::OffsetDateTime; @@ -464,6 +467,53 @@ impl Container for RuncContainer { fn update(&mut self, resources: &LinuxResources) -> Result<()> { Err(Error::Unimplemented("update".to_string())) } + + #[cfg(feature = "async")] + fn pids(&self) -> Result { + Err(Error::Unimplemented("pids".to_string())) + } + + #[cfg(not(feature = "async"))] + fn pids(&self) -> Result { + let pids = self + .common + .init + .runtime + .ps(self.common.init.id()) + .map_err(other_error!(e, "failed to ps"))?; + let mut processes: Vec = Vec::new(); + for pid in pids { + let mut p_info = ProcessInfo { + pid: pid as u32, + ..Default::default() + }; + for process in self.common.processes.values() { + if process.common.pid as usize == pid { + let details = ProcessDetails { + exec_id: "".to_string(), + ..Default::default() + }; + // marshal ProcessDetails to Any + let mut any = Any::new(); + let mut data = Vec::new(); + details + .write_to_vec(&mut data) + .map_err(other_error!(e, "write ProcessDetails to vec"))?; + any.set_value(data); + any.set_type_url(details.descriptor().full_name().to_string()); + + p_info.set_info(any); + break; + } + } + processes.push(p_info); + } + let resp = PidsResponse { + processes: RepeatedField::from(processes), + ..Default::default() + }; + Ok(resp) + } } impl RuncContainer { diff --git a/crates/runc-shim/src/task.rs b/crates/runc-shim/src/task.rs index 4f9c7b7..841bae7 100644 --- a/crates/runc-shim/src/task.rs +++ b/crates/runc-shim/src/task.rs @@ -132,6 +132,17 @@ where Ok(resp) } + fn pids(&self, _ctx: &TtrpcContext, req: PidsRequest) -> TtrpcResult { + debug!("Pids request for {:?}", req); + let containers = self.containers.lock().unwrap(); + let container = containers.get(req.get_id()).ok_or_else(|| { + Error::Other(format!("can not find container by id {}", req.get_id())) + })?; + + let resp = container.pids()?; + Ok(resp) + } + fn kill(&self, _ctx: &TtrpcContext, req: KillRequest) -> TtrpcResult { info!("Kill request for {:?}", req); let mut containers = self.containers.lock().unwrap(); diff --git a/crates/runc/src/lib.rs b/crates/runc/src/lib.rs index 9f7dfa1..c9f07f9 100644 --- a/crates/runc/src/lib.rs +++ b/crates/runc/src/lib.rs @@ -233,7 +233,7 @@ impl Runc { /// List all containers associated with this runc instance pub fn list(&self) -> Result> { - let args = ["list".to_string(), "--format-json".to_string()]; + let args = ["list".to_string(), "--format=json".to_string()]; let res = self.launch(self.command(&args)?, true)?; let output = res.output.trim(); @@ -271,7 +271,7 @@ impl Runc { pub fn ps(&self, id: &str) -> Result> { let args = [ "ps".to_string(), - "--format-json".to_string(), + "--format=json".to_string(), id.to_string(), ]; let res = self.launch(self.command(&args)?, false)?; @@ -449,7 +449,7 @@ impl Runc { /// List all containers associated with this runc instance pub async fn list(&self) -> Result> { - let args = ["list".to_string(), "--format-json".to_string()]; + let args = ["list".to_string(), "--format=json".to_string()]; let res = self.launch(self.command(&args)?, true).await?; let output = res.output.trim(); @@ -487,7 +487,7 @@ impl Runc { pub async fn ps(&self, id: &str) -> Result> { let args = [ "ps".to_string(), - "--format-json".to_string(), + "--format=json".to_string(), id.to_string(), ]; let res = self.launch(self.command(&args)?, true).await?;