diff --git a/src/libs/kata-types/src/annotations/mod.rs b/src/libs/kata-types/src/annotations/mod.rs index 80718dc50a..26925c349b 100644 --- a/src/libs/kata-types/src/annotations/mod.rs +++ b/src/libs/kata-types/src/annotations/mod.rs @@ -80,6 +80,9 @@ pub const KATA_ANNO_CFG_AGENT_CONTAINER_PIPE_SIZE: &str = /// An annotation key to specify the size of the pipes created for containers. pub const CONTAINER_PIPE_SIZE_KERNEL_PARAM: &str = "agent.container_pipe_size"; +/// Policy is an annotation containing the contents of an agent policy file, base64 encoded. +pub const KATA_ANNO_CFG_AGENT_POLICY: &str = "io.katacontainers.config.agent.policy"; + // Hypervisor related annotations /// Prefix for Hypervisor configurations. pub const KATA_ANNO_CFG_HYPERVISOR_PREFIX: &str = "io.katacontainers.config.hypervisor."; @@ -990,6 +993,25 @@ impl Annotation { return Err(u32_err); } }, + KATA_ANNO_CFG_AGENT_POLICY => { + // Base64 decode the annotation value + if let Ok(b64_decoded) = base64::decode_config(&value, base64::STANDARD) { + match String::from_utf8(b64_decoded) { + Ok(policy) => ag.policy = policy, + Err(_e) => { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + format!( + "agent policy {:?} specified in annotation", + &value + ), + )) + } + } + } else { + ag.policy = "".to_string() + } + } KATA_ANNO_CFG_RUNTIME_CREATE_CONTAINTER_TIMEOUT => { match self.get_value::(key) { Ok(v) => { diff --git a/src/libs/kata-types/src/config/agent.rs b/src/libs/kata-types/src/config/agent.rs index 73b472ed3c..34c74cc63d 100644 --- a/src/libs/kata-types/src/config/agent.rs +++ b/src/libs/kata-types/src/config/agent.rs @@ -146,6 +146,10 @@ pub struct Agent { /// Memory agent configuration #[serde(default)] pub mem_agent: MemAgent, + + /// Agent policy + #[serde(default)] + pub policy: String, } impl std::default::Default for Agent { @@ -165,6 +169,7 @@ impl std::default::Default for Agent { kernel_modules: Default::default(), container_pipe_size: 0, mem_agent: MemAgent::default(), + policy: Default::default(), } } } diff --git a/src/runtime-rs/crates/agent/src/kata/agent.rs b/src/runtime-rs/crates/agent/src/kata/agent.rs index 38075ebc5f..5fe5d5273a 100644 --- a/src/runtime-rs/crates/agent/src/kata/agent.rs +++ b/src/runtime-rs/crates/agent/src/kata/agent.rs @@ -125,5 +125,6 @@ impl_agent!( get_metrics | crate::Empty | crate::MetricsResponse | None, get_guest_details | crate::GetGuestDetailsRequest | crate::GuestDetailsResponse | None, add_swap | crate::AddSwapRequest | crate::Empty | None, - add_swap_path | crate::AddSwapPathRequest | crate::Empty | None + add_swap_path | crate::AddSwapPathRequest | crate::Empty | None, + set_policy | crate::SetPolicyRequest | 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 d76417e547..138bbafbda 100644 --- a/src/runtime-rs/crates/agent/src/kata/trans.rs +++ b/src/runtime-rs/crates/agent/src/kata/trans.rs @@ -28,7 +28,8 @@ use crate::{ VersionCheckResponse, VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest, WriteStreamRequest, }, - GetGuestDetailsRequest, OomEventResponse, WaitProcessResponse, WriteStreamResponse, + GetGuestDetailsRequest, OomEventResponse, SetPolicyRequest, WaitProcessResponse, + WriteStreamResponse, }; fn trans_vec>(from: Vec) -> Vec { @@ -744,6 +745,15 @@ impl From for agent::GuestDetailsRequest { } } +impl From for agent::SetPolicyRequest { + fn from(from: SetPolicyRequest) -> Self { + Self { + policy: from.policy, + ..Default::default() + } + } +} + impl From for AgentDetails { fn from(src: agent::AgentDetails) -> Self { Self { diff --git a/src/runtime-rs/crates/agent/src/lib.rs b/src/runtime-rs/crates/agent/src/lib.rs index b574482d0c..398a5ab0bf 100644 --- a/src/runtime-rs/crates/agent/src/lib.rs +++ b/src/runtime-rs/crates/agent/src/lib.rs @@ -33,6 +33,8 @@ use async_trait::async_trait; use kata_types::config::Agent as AgentConfig; +use crate::types::SetPolicyRequest; + pub const AGENT_KATA: &str = "kata"; #[async_trait] @@ -96,4 +98,5 @@ pub trait Agent: AgentManager + HealthService + Send + Sync { async fn get_guest_details(&self, req: GetGuestDetailsRequest) -> Result; async fn add_swap(&self, req: AddSwapRequest) -> Result; async fn add_swap_path(&self, req: AddSwapPathRequest) -> Result; + async fn set_policy(&self, req: SetPolicyRequest) -> Result; } diff --git a/src/runtime-rs/crates/agent/src/types.rs b/src/runtime-rs/crates/agent/src/types.rs index e6bb71b119..ea211b90aa 100644 --- a/src/runtime-rs/crates/agent/src/types.rs +++ b/src/runtime-rs/crates/agent/src/types.rs @@ -615,6 +615,11 @@ pub struct AddSwapPathRequest { pub path: String, } +#[derive(PartialEq, Clone, Default, Debug)] +pub struct SetPolicyRequest { + pub policy: String, +} + #[cfg(test)] mod test { use std::convert::TryFrom; 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 613cca2878..defd1a3cf4 100644 --- a/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs +++ b/src/runtime-rs/crates/runtimes/src/shim_mgmt/handlers.rs @@ -45,6 +45,7 @@ pub(crate) async fn handler_mux( direct_volume_resize_handler(sandbox, req).await } (&Method::GET, METRICS_URL) => metrics_url_handler(sandbox, req).await, + // TODO: implement policy related method _ => Ok(not_found(req).await), } } 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 51ad550f65..7810525a3a 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -6,7 +6,7 @@ use crate::health_check::HealthCheck; use agent::kata::KataAgent; -use agent::types::KernelModule; +use agent::types::{KernelModule, SetPolicyRequest}; use agent::{ self, Agent, GetGuestDetailsRequest, GetIPTablesRequest, SetIPTablesRequest, VolumeStatsRequest, }; @@ -345,6 +345,24 @@ impl VirtSandbox { })) } + async fn set_agent_policy(&self) -> Result<()> { + // TODO: Exclude policy-related items from the annotations. + let toml_config = self.resource_manager.config().await; + if let Some(agent_config) = toml_config.agent.get(&toml_config.runtime.agent_name) { + // If a Policy has been specified, send it to the agent. + if !agent_config.policy.is_empty() { + self.agent + .set_policy(SetPolicyRequest { + policy: agent_config.policy.clone(), + }) + .await + .context("sandbox: set policy failed")?; + } + } + + Ok(()) + } + async fn prepare_vm_socket_config(&self) -> Result { // It will check the hypervisor's capabilities to see if it supports hybrid-vsock. // If it does not, it'll assume that it only supports legacy vsock. @@ -593,6 +611,7 @@ impl Sandbox for VirtSandbox { .start(&address) .await .context(format!("connect to address {:?}", &address))?; + self.set_agent_policy().await.context("set agent policy")?; self.resource_manager .setup_after_start_vm()