mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 12:44:39 +00:00
agent: Run OCI poststart hooks after a container is launched
Run the OCI `poststart` hooks must be called after the user-specified process is executed but before the `start` operation returns in accordance with OCI runtime spec. Fixes: #4575 Signed-off-by: Manabu Sugimoto <Manabu.Sugimoto@sony.com>
This commit is contained in:
parent
133528dd14
commit
acd3302bef
@ -222,7 +222,7 @@ pub trait BaseContainer {
|
|||||||
async fn start(&mut self, p: Process) -> Result<()>;
|
async fn start(&mut self, p: Process) -> Result<()>;
|
||||||
async fn run(&mut self, p: Process) -> Result<()>;
|
async fn run(&mut self, p: Process) -> Result<()>;
|
||||||
async fn destroy(&mut self) -> Result<()>;
|
async fn destroy(&mut self) -> Result<()>;
|
||||||
fn exec(&mut self) -> Result<()>;
|
async fn exec(&mut self) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinuxContainer protected by Mutex
|
// LinuxContainer protected by Mutex
|
||||||
@ -634,11 +634,6 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
|||||||
capabilities::drop_privileges(cfd_log, c)?;
|
capabilities::drop_privileges(cfd_log, c)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if init {
|
|
||||||
// notify parent to run poststart hooks
|
|
||||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let args = oci_process.args.to_vec();
|
let args = oci_process.args.to_vec();
|
||||||
let env = oci_process.env.to_vec();
|
let env = oci_process.env.to_vec();
|
||||||
|
|
||||||
@ -1054,7 +1049,7 @@ impl BaseContainer for LinuxContainer {
|
|||||||
self.start(p).await?;
|
self.start(p).await?;
|
||||||
|
|
||||||
if init {
|
if init {
|
||||||
self.exec()?;
|
self.exec().await?;
|
||||||
self.status.transition(ContainerState::Running);
|
self.status.transition(ContainerState::Running);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,7 +1097,7 @@ impl BaseContainer for LinuxContainer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(&mut self) -> Result<()> {
|
async fn exec(&mut self) -> Result<()> {
|
||||||
let fifo = format!("{}/{}", &self.root, EXEC_FIFO_FILENAME);
|
let fifo = format!("{}/{}", &self.root, EXEC_FIFO_FILENAME);
|
||||||
let fd = fcntl::open(fifo.as_str(), OFlag::O_WRONLY, Mode::from_bits_truncate(0))?;
|
let fd = fcntl::open(fifo.as_str(), OFlag::O_WRONLY, Mode::from_bits_truncate(0))?;
|
||||||
let data: &[u8] = &[0];
|
let data: &[u8] = &[0];
|
||||||
@ -1114,6 +1109,26 @@ impl BaseContainer for LinuxContainer {
|
|||||||
.as_secs();
|
.as_secs();
|
||||||
|
|
||||||
self.status.transition(ContainerState::Running);
|
self.status.transition(ContainerState::Running);
|
||||||
|
|
||||||
|
let spec = self
|
||||||
|
.config
|
||||||
|
.spec
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| anyhow!("OCI spec was not found"))?;
|
||||||
|
let st = self.oci_state()?;
|
||||||
|
|
||||||
|
// run poststart hook
|
||||||
|
if spec.hooks.is_some() {
|
||||||
|
info!(self.logger, "poststart hook");
|
||||||
|
let hooks = spec
|
||||||
|
.hooks
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| anyhow!("OCI hooks were not found"))?;
|
||||||
|
for h in hooks.poststart.iter() {
|
||||||
|
execute_hook(&self.logger, h, &st).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unistd::close(fd)?;
|
unistd::close(fd)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1335,20 +1350,6 @@ async fn join_namespaces(
|
|||||||
// notify child run prestart hooks completed
|
// notify child run prestart hooks completed
|
||||||
info!(logger, "notify child run prestart hook completed!");
|
info!(logger, "notify child run prestart hook completed!");
|
||||||
write_async(pipe_w, SYNC_SUCCESS, "").await?;
|
write_async(pipe_w, SYNC_SUCCESS, "").await?;
|
||||||
|
|
||||||
info!(logger, "notify child parent ready to run poststart hook!");
|
|
||||||
// wait to run poststart hook
|
|
||||||
read_async(pipe_r).await?;
|
|
||||||
info!(logger, "get ready to run poststart hook!");
|
|
||||||
|
|
||||||
// run poststart hook
|
|
||||||
if spec.hooks.is_some() {
|
|
||||||
info!(logger, "poststart hook");
|
|
||||||
let hooks = spec.hooks.as_ref().unwrap();
|
|
||||||
for h in hooks.poststart.iter() {
|
|
||||||
execute_hook(&logger, h, st).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(logger, "wait for child process ready to run exec");
|
info!(logger, "wait for child process ready to run exec");
|
||||||
@ -2090,9 +2091,10 @@ mod tests {
|
|||||||
assert!(ret.is_ok(), "Expecting Ok, Got {:?}", ret);
|
assert!(ret.is_ok(), "Expecting Ok, Got {:?}", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn test_linuxcontainer_exec() {
|
async fn test_linuxcontainer_exec() {
|
||||||
let ret = new_linux_container_and_then(|mut c: LinuxContainer| c.exec());
|
let (c, _dir) = new_linux_container();
|
||||||
|
let ret = c.unwrap().exec().await;
|
||||||
assert!(ret.is_err(), "Expecting Err, Got {:?}", ret);
|
assert!(ret.is_err(), "Expecting Err, Got {:?}", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ impl AgentService {
|
|||||||
.get_container(&cid)
|
.get_container(&cid)
|
||||||
.ok_or_else(|| anyhow!("Invalid container id"))?;
|
.ok_or_else(|| anyhow!("Invalid container id"))?;
|
||||||
|
|
||||||
ctr.exec()?;
|
ctr.exec().await?;
|
||||||
|
|
||||||
if sid == cid {
|
if sid == cid {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
Loading…
Reference in New Issue
Block a user