mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 17:37:20 +00:00 
			
		
		
		
	agent: support guest hooks
Scan guest hooks upon creating new sandbox and append them to guest OCI spec before running containers. Fixes: #485 Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
		| @@ -129,6 +129,9 @@ impl agentService { | ||||
|         // Add the root partition to the device cgroup to prevent access | ||||
|         update_device_cgroup(&mut oci)?; | ||||
|  | ||||
|         // Append guest hooks | ||||
|         append_guest_hooks(&s, &mut oci); | ||||
|  | ||||
|         // write spec to bundle path, hooks might | ||||
|         // read ocispec | ||||
|         let olddir = setup_bundle(&cid, &mut oci)?; | ||||
| @@ -1084,6 +1087,15 @@ impl protocols::agent_ttrpc::AgentService for agentService { | ||||
|             s.hostname = req.hostname.clone(); | ||||
|             s.running = true; | ||||
|  | ||||
|             if !req.guest_hook_path.is_empty() { | ||||
|                 if let Err(e) = s.add_hooks(&req.guest_hook_path) { | ||||
|                     error!( | ||||
|                         sl!(), | ||||
|                         "add guest hook {} failed: {:?}", req.guest_hook_path, e | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if req.sandbox_id.len() > 0 { | ||||
|                 s.id = req.sandbox_id.clone(); | ||||
|             } | ||||
| @@ -1523,6 +1535,18 @@ fn update_container_namespaces( | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| fn append_guest_hooks(s: &Sandbox, oci: &mut Spec) { | ||||
|     if s.hooks.is_none() { | ||||
|         return; | ||||
|     } | ||||
|     let guest_hooks = s.hooks.as_ref().unwrap(); | ||||
|     let mut hooks = oci.hooks.take().unwrap_or_default(); | ||||
|     hooks.prestart.append(&mut guest_hooks.prestart.clone()); | ||||
|     hooks.poststart.append(&mut guest_hooks.poststart.clone()); | ||||
|     hooks.poststop.append(&mut guest_hooks.poststop.clone()); | ||||
|     oci.hooks = Some(hooks); | ||||
| } | ||||
|  | ||||
| // Check is the container process installed the | ||||
| // handler for specific signal. | ||||
| fn is_signal_handled(pid: pid_t, signum: u32) -> bool { | ||||
|   | ||||
| @@ -11,7 +11,7 @@ use crate::namespace::NSTYPEPID; | ||||
| use crate::network::Network; | ||||
| use libc::pid_t; | ||||
| use netlink::{RtnlHandle, NETLINK_ROUTE}; | ||||
| use oci::LinuxNamespace; | ||||
| use oci::{Hook, Hooks}; | ||||
| use protocols::agent::OnlineCPUMemRequest; | ||||
| use regex::Regex; | ||||
| use rustjail::cgroups; | ||||
| @@ -22,6 +22,8 @@ use rustjail::process::Process; | ||||
| use slog::Logger; | ||||
| use std::collections::HashMap; | ||||
| use std::fs; | ||||
| use std::os::unix::fs::PermissionsExt; | ||||
| use std::path::Path; | ||||
| use std::sync::mpsc::Sender; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| @@ -42,6 +44,7 @@ pub struct Sandbox { | ||||
|     pub no_pivot_root: bool, | ||||
|     pub sender: Option<Sender<i32>>, | ||||
|     pub rtnl: Option<RtnlHandle>, | ||||
|     pub hooks: Option<Hooks>, | ||||
| } | ||||
|  | ||||
| impl Sandbox { | ||||
| @@ -66,6 +69,7 @@ impl Sandbox { | ||||
|             no_pivot_root: fs_type.eq(TYPEROOTFS), | ||||
|             sender: None, | ||||
|             rtnl: Some(RtnlHandle::new(NETLINK_ROUTE, 0).unwrap()), | ||||
|             hooks: None, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
| @@ -261,6 +265,57 @@ impl Sandbox { | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn add_hooks(&mut self, dir: &str) -> Result<()> { | ||||
|         let mut hooks = Hooks::default(); | ||||
|         if let Ok(hook) = self.find_hooks(dir, "prestart") { | ||||
|             hooks.prestart = hook; | ||||
|         } | ||||
|         if let Ok(hook) = self.find_hooks(dir, "poststart") { | ||||
|             hooks.poststart = hook; | ||||
|         } | ||||
|         if let Ok(hook) = self.find_hooks(dir, "poststop") { | ||||
|             hooks.poststop = hook; | ||||
|         } | ||||
|         self.hooks = Some(hooks); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     fn find_hooks(&self, hook_path: &str, hook_type: &str) -> Result<Vec<Hook>> { | ||||
|         let mut hooks = Vec::new(); | ||||
|         for entry in fs::read_dir(Path::new(hook_path).join(hook_type))? { | ||||
|             let entry = entry?; | ||||
|             // Reject non-file, symlinks and non-executable files | ||||
|             if !entry.file_type()?.is_file() | ||||
|                 || entry.file_type()?.is_symlink() | ||||
|                 || entry.metadata()?.permissions().mode() & 0o777 & 0o111 == 0 | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             let name = entry.file_name(); | ||||
|             let hook = Hook { | ||||
|                 path: Path::new(hook_path) | ||||
|                     .join(hook_type) | ||||
|                     .join(&name) | ||||
|                     .to_str() | ||||
|                     .unwrap() | ||||
|                     .to_owned(), | ||||
|                 args: vec![name.to_str().unwrap().to_owned(), hook_type.to_owned()], | ||||
|                 ..Default::default() | ||||
|             }; | ||||
|             info!( | ||||
|                 self.logger, | ||||
|                 "found {} hook {:?} mode {:o}", | ||||
|                 hook_type, | ||||
|                 hook, | ||||
|                 entry.metadata()?.permissions().mode() | ||||
|             ); | ||||
|             hooks.push(hook); | ||||
|         } | ||||
|  | ||||
|         Ok(hooks) | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn online_resources(logger: &Logger, path: &str, pattern: &str, num: i32) -> Result<i32> { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user