From 42b8867148d2287b2a40f23792a0ba23d97eea4f Mon Sep 17 00:00:00 2001 From: Tingzhou Yuan Date: Tue, 6 Dec 2022 06:54:34 +0000 Subject: [PATCH 1/2] runtime-rs: impl volume-stats trait for sandbox Implements get-volume-stats trait for sandbox, handler for shim-mgmt and add RPC calls to agent. Also added type conversions in trans.rs Fixes #5369 Signed-off-by: Tingzhou Yuan --- src/runtime-rs/Cargo.lock | 1 + src/runtime-rs/crates/agent/src/kata/agent.rs | 3 ++- src/runtime-rs/crates/agent/src/kata/trans.rs | 25 +++++++++++++++++-- src/runtime-rs/crates/agent/src/lib.rs | 5 ++-- src/runtime-rs/crates/agent/src/types.rs | 10 ++++++++ .../crates/runtimes/common/src/sandbox.rs | 1 + .../crates/runtimes/src/shim_mgmt/handlers.rs | 25 ++++++++++++++++++- .../runtimes/virt_container/src/sandbox.rs | 9 +++++++ 8 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index e38ae35105..e2525363b6 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -2470,6 +2470,7 @@ dependencies = [ "slog", "slog-scope", "tokio", + "url", "virt_container", "wasm_container", ] diff --git a/src/runtime-rs/crates/agent/src/kata/agent.rs b/src/runtime-rs/crates/agent/src/kata/agent.rs index b403f0f44c..6baab2dd1f 100644 --- a/src/runtime-rs/crates/agent/src/kata/agent.rs +++ b/src/runtime-rs/crates/agent/src/kata/agent.rs @@ -115,5 +115,6 @@ impl_agent!( copy_file | crate::CopyFileRequest | crate::Empty | None, get_oom_event | crate::Empty | crate::OomEventResponse | Some(0), get_ip_tables | crate::GetIPTablesRequest | crate::GetIPTablesResponse | None, - set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None + set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None, + get_volume_stats | crate::VolumeStatsRequest | crate::VolumeStatsResponse | None ); diff --git a/src/runtime-rs/crates/agent/src/kata/trans.rs b/src/runtime-rs/crates/agent/src/kata/trans.rs index 4ac0c45ec2..f2f7255354 100644 --- a/src/runtime-rs/crates/agent/src/kata/trans.rs +++ b/src/runtime-rs/crates/agent/src/kata/trans.rs @@ -8,7 +8,7 @@ use std::convert::Into; use protocols::{ agent::{self, OOMEvent}, - empty, health, types, + csi, empty, health, types, }; use crate::{ @@ -24,7 +24,7 @@ use crate::{ SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest, StatsContainerResponse, Storage, StringUser, ThrottlingData, TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse, - WaitProcessRequest, WriteStreamRequest, + VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest, WriteStreamRequest, }, OomEventResponse, WaitProcessResponse, WriteStreamResponse, }; @@ -846,3 +846,24 @@ impl From for OomEventResponse { } } } + +impl From for agent::VolumeStatsRequest { + fn from(from: VolumeStatsRequest) -> Self { + Self { + volume_guest_path: from.volume_guest_path, + unknown_fields: Default::default(), + cached_size: Default::default(), + } + } +} + +impl From for VolumeStatsResponse { + fn from(from: csi::VolumeStatsResponse) -> Self { + let result: String = format!( + "Usage: {:?}\nVolume Condition: {:?}", + from.get_usage(), + from.get_volume_condition() + ); + Self { data: result } + } +} diff --git a/src/runtime-rs/crates/agent/src/lib.rs b/src/runtime-rs/crates/agent/src/lib.rs index a3d1da72ac..fd4dde2557 100644 --- a/src/runtime-rs/crates/agent/src/lib.rs +++ b/src/runtime-rs/crates/agent/src/lib.rs @@ -23,8 +23,8 @@ pub use types::{ ReseedRandomDevRequest, ResizeVolumeRequest, Route, Routes, SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest, StatsContainerResponse, Storage, TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, - VersionCheckResponse, WaitProcessRequest, WaitProcessResponse, WriteStreamRequest, - WriteStreamResponse, + VersionCheckResponse, VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest, + WaitProcessResponse, WriteStreamRequest, WriteStreamResponse, }; use anyhow::Result; @@ -88,4 +88,5 @@ pub trait Agent: AgentManager + HealthService + Send + Sync { async fn get_oom_event(&self, req: Empty) -> Result; async fn get_ip_tables(&self, req: GetIPTablesRequest) -> Result; async fn set_ip_tables(&self, req: SetIPTablesRequest) -> Result; + async fn get_volume_stats(&self, req: VolumeStatsRequest) -> Result; } diff --git a/src/runtime-rs/crates/agent/src/types.rs b/src/runtime-rs/crates/agent/src/types.rs index 0cd509ff5e..7937166bd6 100644 --- a/src/runtime-rs/crates/agent/src/types.rs +++ b/src/runtime-rs/crates/agent/src/types.rs @@ -568,6 +568,16 @@ pub struct ResizeVolumeRequest { pub size: u64, } +#[derive(PartialEq, Clone, Default, Debug)] +pub struct VolumeStatsRequest { + pub volume_guest_path: String, +} + +#[derive(PartialEq, Clone, Default, Debug)] +pub struct VolumeStatsResponse { + pub data: String, +} + #[cfg(test)] mod test { use std::convert::TryFrom; diff --git a/src/runtime-rs/crates/runtimes/common/src/sandbox.rs b/src/runtime-rs/crates/runtimes/common/src/sandbox.rs index 3fee8165d4..7b1bcd8d54 100644 --- a/src/runtime-rs/crates/runtimes/common/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/common/src/sandbox.rs @@ -26,4 +26,5 @@ pub trait Sandbox: Send + Sync { // utils async fn set_iptables(&self, is_ipv6: bool, data: Vec) -> Result>; async fn get_iptables(&self, is_ipv6: bool) -> Result>; + async fn direct_volume_stats(&self, volume_path: &str) -> Result; } diff --git a/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs b/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs index dea9725a5e..b2ee0fd137 100644 --- a/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs +++ b/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs @@ -11,8 +11,9 @@ use anyhow::{anyhow, Result}; use common::Sandbox; use hyper::{Body, Method, Request, Response, StatusCode}; use std::sync::Arc; +use url::Url; -use shim_interface::shim_mgmt::{AGENT_URL, IP6_TABLE_URL, IP_TABLE_URL}; +use shim_interface::shim_mgmt::{AGENT_URL, IP6_TABLE_URL, IP_TABLE_URL, DIRECT_VOLUMN_PATH_KEY, DIRECT_VOLUMN_STATS_URL,}; // main router for response, this works as a multiplexer on // http arrival which invokes the corresponding handler function @@ -34,6 +35,7 @@ pub(crate) async fn handler_mux( (&Method::PUT, IP6_TABLE_URL) | (&Method::GET, IP6_TABLE_URL) => { ipv6_table_handler(sandbox, req).await } + (&Method::POST, DIRECT_VOLUMN_STATS_URL) => direct_volume_stats_handler(sandbox, req).await, _ => Ok(not_found(req).await), } } @@ -101,3 +103,24 @@ async fn generic_ip_table_handler( _ => Err(anyhow!("IP Tables only takes PUT and GET")), } } + +async fn direct_volume_stats_handler( + sandbox: Arc, + req: Request, +) -> Result> { + let params = Url::parse(&req.uri().to_string()) + .unwrap() + .query_pairs() + .into_owned() + .collect::>(); + let volume_path = params.get(DIRECT_VOLUMN_PATH_KEY).unwrap(); + let result = sandbox.direct_volume_stats(volume_path).await; + match result { + Ok(stats) => Ok(Response::new(Body::from(stats))), + Err(e) => { + let builder = Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR); + let resp = builder.body(Body::from(e.to_string())).unwrap(); + Ok(resp) + } + } +} diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs index 0d6e4765ec..41fdab15fe 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use agent::{ self, kata::KataAgent, types::KernelModule, Agent, GetIPTablesRequest, SetIPTablesRequest, + VolumeStatsRequest, }; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; @@ -329,6 +330,14 @@ impl Sandbox for VirtSandbox { self.agent.agent_sock().await } + async fn direct_volume_stats(&self, volume_guest_path: &str) -> Result { + let req: agent::VolumeStatsRequest = VolumeStatsRequest { + volume_guest_path: volume_guest_path.to_string(), + }; + let result = self.agent.get_volume_stats(req).await?.data; + Ok(result) + } + async fn set_iptables(&self, is_ipv6: bool, data: Vec) -> Result> { info!(sl!(), "sb: set_iptables invoked"); let req = SetIPTablesRequest { is_ipv6, data }; From 30e235f0a1ec420d796712e56c1669785316e24a Mon Sep 17 00:00:00 2001 From: Tingzhou Yuan Date: Tue, 6 Dec 2022 07:08:43 +0000 Subject: [PATCH 2/2] runtime-rs: impl volume-resize trait for sandbox Implements resize-volume handlers in shim-mgmt, trait for sandbox and add RPC calls to agent. Note the actual rpc handler for the resize request is currently not implemented, refer to issue #3694. Fixes #5369 Signed-off-by: Tingzhou Yuan --- .../shim-interface/src/shim_mgmt/client.rs | 6 +-- src/runtime-rs/Cargo.lock | 1 + src/runtime-rs/crates/agent/src/kata/agent.rs | 3 +- src/runtime-rs/crates/agent/src/kata/trans.rs | 24 ++++++++--- src/runtime-rs/crates/agent/src/lib.rs | 1 + src/runtime-rs/crates/runtimes/Cargo.toml | 2 + .../crates/runtimes/common/src/sandbox.rs | 1 + .../crates/runtimes/src/shim_mgmt/handlers.rs | 42 ++++++++++++++----- .../runtimes/virt_container/src/sandbox.rs | 16 ++++++- 9 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/libs/shim-interface/src/shim_mgmt/client.rs b/src/libs/shim-interface/src/shim_mgmt/client.rs index ace72c1d60..f112903c5c 100644 --- a/src/libs/shim-interface/src/shim_mgmt/client.rs +++ b/src/libs/shim-interface/src/shim_mgmt/client.rs @@ -53,7 +53,7 @@ impl MgmtClient { .method(Method::GET) .uri(url) .body(Body::empty())?; - return self.send_request(req).await; + self.send_request(req).await } /// The HTTP Post method for client @@ -72,7 +72,7 @@ impl MgmtClient { .uri(url) .header("content-type", content_type) .body(body)?; - return self.send_request(req).await; + self.send_request(req).await } /// The http PUT method for client @@ -82,7 +82,7 @@ impl MgmtClient { .method(Method::PUT) .uri(url) .body(Body::from(data))?; - return self.send_request(req).await; + self.send_request(req).await } async fn send_request(&self, req: Request) -> Result> { diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index e2525363b6..3e2d68fd1c 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -2452,6 +2452,7 @@ dependencies = [ name = "runtimes" version = "0.1.0" dependencies = [ + "agent", "anyhow", "common", "hyper", diff --git a/src/runtime-rs/crates/agent/src/kata/agent.rs b/src/runtime-rs/crates/agent/src/kata/agent.rs index 6baab2dd1f..aa0df08571 100644 --- a/src/runtime-rs/crates/agent/src/kata/agent.rs +++ b/src/runtime-rs/crates/agent/src/kata/agent.rs @@ -116,5 +116,6 @@ impl_agent!( get_oom_event | crate::Empty | crate::OomEventResponse | Some(0), get_ip_tables | crate::GetIPTablesRequest | crate::GetIPTablesResponse | None, set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None, - get_volume_stats | crate::VolumeStatsRequest | crate::VolumeStatsResponse | None + get_volume_stats | crate::VolumeStatsRequest | crate::VolumeStatsResponse | None, + resize_volume | crate::ResizeVolumeRequest | crate::Empty | None ); diff --git a/src/runtime-rs/crates/agent/src/kata/trans.rs b/src/runtime-rs/crates/agent/src/kata/trans.rs index f2f7255354..7d33a09923 100644 --- a/src/runtime-rs/crates/agent/src/kata/trans.rs +++ b/src/runtime-rs/crates/agent/src/kata/trans.rs @@ -20,11 +20,12 @@ use crate::{ GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, HugetlbStats, IPAddress, IPFamily, Interface, Interfaces, KernelModule, MemHotplugByProbeRequest, MemoryData, MemoryStats, NetworkStats, OnlineCPUMemRequest, PidsStats, ReadStreamRequest, - ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes, - SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest, - StatsContainerResponse, Storage, StringUser, ThrottlingData, TtyWinResizeRequest, - UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse, - VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest, WriteStreamRequest, + ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, ResizeVolumeRequest, + Route, Routes, SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, + SignalProcessRequest, StatsContainerResponse, Storage, StringUser, ThrottlingData, + TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, + VersionCheckResponse, VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest, + WriteStreamRequest, }, OomEventResponse, WaitProcessResponse, WriteStreamResponse, }; @@ -860,10 +861,21 @@ impl From for agent::VolumeStatsRequest { impl From for VolumeStatsResponse { fn from(from: csi::VolumeStatsResponse) -> Self { let result: String = format!( - "Usage: {:?}\nVolume Condition: {:?}", + "Usage: {:?} Volume Condition: {:?}", from.get_usage(), from.get_volume_condition() ); Self { data: result } } } + +impl From for agent::ResizeVolumeRequest { + fn from(from: ResizeVolumeRequest) -> Self { + Self { + volume_guest_path: from.volume_guest_path, + size: from.size, + unknown_fields: Default::default(), + cached_size: Default::default(), + } + } +} diff --git a/src/runtime-rs/crates/agent/src/lib.rs b/src/runtime-rs/crates/agent/src/lib.rs index fd4dde2557..ea3bab78f8 100644 --- a/src/runtime-rs/crates/agent/src/lib.rs +++ b/src/runtime-rs/crates/agent/src/lib.rs @@ -89,4 +89,5 @@ pub trait Agent: AgentManager + HealthService + Send + Sync { async fn get_ip_tables(&self, req: GetIPTablesRequest) -> Result; async fn set_ip_tables(&self, req: SetIPTablesRequest) -> Result; async fn get_volume_stats(&self, req: VolumeStatsRequest) -> Result; + async fn resize_volume(&self, req: ResizeVolumeRequest) -> Result; } diff --git a/src/runtime-rs/crates/runtimes/Cargo.toml b/src/runtime-rs/crates/runtimes/Cargo.toml index 142c44ed0c..3a6ab0a1b1 100644 --- a/src/runtime-rs/crates/runtimes/Cargo.toml +++ b/src/runtime-rs/crates/runtimes/Cargo.toml @@ -15,7 +15,9 @@ hyper = { version = "0.14.20", features = ["stream", "server", "http1"] } hyperlocal = "0.8" serde_json = "1.0.88" nix = "0.25.0" +url = "2.3.1" +agent = { path = "../agent" } common = { path = "./common" } kata-types = { path = "../../../libs/kata-types" } kata-sys-util = { path = "../../../libs/kata-sys-util" } diff --git a/src/runtime-rs/crates/runtimes/common/src/sandbox.rs b/src/runtime-rs/crates/runtimes/common/src/sandbox.rs index 7b1bcd8d54..0aee049225 100644 --- a/src/runtime-rs/crates/runtimes/common/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/common/src/sandbox.rs @@ -27,4 +27,5 @@ pub trait Sandbox: Send + Sync { async fn set_iptables(&self, is_ipv6: bool, data: Vec) -> Result>; async fn get_iptables(&self, is_ipv6: bool) -> Result>; async fn direct_volume_stats(&self, volume_path: &str) -> Result; + async fn direct_volume_resize(&self, resize_req: agent::ResizeVolumeRequest) -> Result<()>; } diff --git a/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs b/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs index b2ee0fd137..b0c79cd404 100644 --- a/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs +++ b/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs @@ -7,13 +7,17 @@ // This defines the handlers corresponding to the url when a request is sent to destined url, // the handler function should be invoked, and the corresponding data will be in the response -use anyhow::{anyhow, Result}; +use agent::ResizeVolumeRequest; +use anyhow::{anyhow, Context, Result}; use common::Sandbox; use hyper::{Body, Method, Request, Response, StatusCode}; use std::sync::Arc; use url::Url; -use shim_interface::shim_mgmt::{AGENT_URL, IP6_TABLE_URL, IP_TABLE_URL, DIRECT_VOLUMN_PATH_KEY, DIRECT_VOLUMN_STATS_URL,}; +use shim_interface::shim_mgmt::{ + AGENT_URL, DIRECT_VOLUME_PATH_KEY, DIRECT_VOLUME_RESIZE_URL, DIRECT_VOLUME_STATS_URL, + IP6_TABLE_URL, IP_TABLE_URL, +}; // main router for response, this works as a multiplexer on // http arrival which invokes the corresponding handler function @@ -35,7 +39,10 @@ pub(crate) async fn handler_mux( (&Method::PUT, IP6_TABLE_URL) | (&Method::GET, IP6_TABLE_URL) => { ipv6_table_handler(sandbox, req).await } - (&Method::POST, DIRECT_VOLUMN_STATS_URL) => direct_volume_stats_handler(sandbox, req).await, + (&Method::POST, DIRECT_VOLUME_STATS_URL) => direct_volume_stats_handler(sandbox, req).await, + (&Method::POST, DIRECT_VOLUME_RESIZE_URL) => { + direct_volume_resize_handler(sandbox, req).await + } _ => Ok(not_found(req).await), } } @@ -109,18 +116,33 @@ async fn direct_volume_stats_handler( req: Request, ) -> Result> { let params = Url::parse(&req.uri().to_string()) - .unwrap() + .map_err(|e| anyhow!(e))? .query_pairs() .into_owned() .collect::>(); - let volume_path = params.get(DIRECT_VOLUMN_PATH_KEY).unwrap(); + let volume_path = params + .get(DIRECT_VOLUME_PATH_KEY) + .context("shim-mgmt: volume path key not found in request params")?; let result = sandbox.direct_volume_stats(volume_path).await; match result { Ok(stats) => Ok(Response::new(Body::from(stats))), - Err(e) => { - let builder = Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR); - let resp = builder.body(Body::from(e.to_string())).unwrap(); - Ok(resp) - } + _ => Err(anyhow!("handler: Failed to get volume stats")), + } +} + +async fn direct_volume_resize_handler( + sandbox: Arc, + req: Request, +) -> Result> { + let body = hyper::body::to_bytes(req.into_body()).await?; + + // unserialize json body into resizeRequest struct + let resize_req: ResizeVolumeRequest = + serde_json::from_slice(&body).context("shim-mgmt: deserialize resizeRequest failed")?; + let result = sandbox.direct_volume_resize(resize_req).await; + + match result { + Ok(_) => Ok(Response::new(Body::from(""))), + _ => Err(anyhow!("handler: Failed to resize volume")), } } diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs index 41fdab15fe..1b170ce31f 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -334,8 +334,20 @@ impl Sandbox for VirtSandbox { let req: agent::VolumeStatsRequest = VolumeStatsRequest { volume_guest_path: volume_guest_path.to_string(), }; - let result = self.agent.get_volume_stats(req).await?.data; - Ok(result) + let result = self + .agent + .get_volume_stats(req) + .await + .context("sandbox: failed to process direct volume stats query")?; + Ok(result.data) + } + + async fn direct_volume_resize(&self, resize_req: agent::ResizeVolumeRequest) -> Result<()> { + self.agent + .resize_volume(resize_req) + .await + .context("sandbox: failed to resize direct-volume")?; + Ok(()) } async fn set_iptables(&self, is_ipv6: bool, data: Vec) -> Result> {