use super::{Container, ContainerStatus};
use crate::config::YoukiConfig;
use crate::hooks;
use anyhow::{bail, Context, Result};
use libcgroups;
use nix::sys::signal;
use std::fs;
impl Container {
pub fn delete(&mut self, force: bool) -> Result<()> {
self.refresh_status()
.context("failed to refresh container status")?;
if self.can_kill() && force {
self.do_kill(signal::Signal::SIGKILL, true)?;
self.set_status(ContainerStatus::Stopped).save()?;
}
log::debug!("container status: {:?}", self.status());
if self.can_delete() {
if self.root.exists() {
let config = YoukiConfig::load(&self.root).with_context(|| {
format!("failed to load runtime spec for container {}", self.id())
})?;
log::debug!("config: {:?}", config);
log::debug!("remove dir {:?}", self.root);
fs::remove_dir_all(&self.root).with_context(|| {
format!("failed to remove container dir {}", self.root.display())
})?;
let use_systemd = self
.systemd()
.context("container state does not contain cgroup manager")?;
let cmanager = libcgroups::common::create_cgroup_manager(
&config.cgroup_path,
use_systemd,
self.id(),
)
.context("failed to create cgroup manager")?;
cmanager.remove().with_context(|| {
format!("failed to remove cgroup {}", config.cgroup_path.display())
})?;
if let Some(hooks) = config.hooks.as_ref() {
hooks::run_hooks(hooks.poststop().as_ref(), Some(self))
.with_context(|| "failed to run post stop hooks")?;
}
}
Ok(())
} else {
bail!(
"{} could not be deleted because it was {:?}",
self.id(),
self.status()
)
}
}
}