1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-05-24 16:36:07 +02:00
youki/crates/libcontainer/src/config.rs
Yashodhan 601df9ecd3
Fix cgroups determination in exec implementation (#2720)
* Set cgroups path for tenant containers from main container

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Ignore new_user_ns for creating cgroups path

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Remove user_ns param completely

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Add tests in podman rootless for exec

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Fix add_task implementation for cgroups v2 and systemd

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* minor refactor in tenant builder

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Add unit test for systemd add_task function

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Fix task addition to properly add tasks via dbus api

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

* Fix cross cotainers for tests running

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>

---------

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
2024-04-27 21:49:58 +09:00

130 lines
3.6 KiB
Rust

use crate::utils;
use oci_spec::runtime::{Hooks, Spec};
use serde::{Deserialize, Serialize};
use std::{
fs,
io::{BufReader, BufWriter, Write},
path::{Path, PathBuf},
};
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("failed to save config")]
SaveIO {
source: std::io::Error,
path: PathBuf,
},
#[error("failed to save config")]
SaveEncode {
source: serde_json::Error,
path: PathBuf,
},
#[error("failed to parse config")]
LoadIO {
source: std::io::Error,
path: PathBuf,
},
#[error("failed to parse config")]
LoadParse {
source: serde_json::Error,
path: PathBuf,
},
#[error("missing linux in spec")]
MissingLinux,
}
type Result<T> = std::result::Result<T, ConfigError>;
const YOUKI_CONFIG_NAME: &str = "youki_config.json";
/// A configuration for passing information obtained during container creation to other commands.
/// Keeping the information to a minimum improves performance.
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct YoukiConfig {
pub hooks: Option<Hooks>,
pub cgroup_path: PathBuf,
}
impl<'a> YoukiConfig {
pub fn from_spec(spec: &'a Spec, container_id: &str) -> Result<Self> {
Ok(YoukiConfig {
hooks: spec.hooks().clone(),
cgroup_path: utils::get_cgroup_path(
spec.linux()
.as_ref()
.ok_or(ConfigError::MissingLinux)?
.cgroups_path(),
container_id,
),
})
}
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let file = fs::File::create(path.as_ref().join(YOUKI_CONFIG_NAME)).map_err(|err| {
ConfigError::SaveIO {
source: err,
path: path.as_ref().to_owned(),
}
})?;
let mut writer = BufWriter::new(file);
serde_json::to_writer(&mut writer, self).map_err(|err| ConfigError::SaveEncode {
source: err,
path: path.as_ref().to_owned(),
})?;
writer.flush().map_err(|err| ConfigError::SaveIO {
source: err,
path: path.as_ref().to_owned(),
})?;
Ok(())
}
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self> {
let path = path.as_ref();
let file =
fs::File::open(path.join(YOUKI_CONFIG_NAME)).map_err(|err| ConfigError::LoadIO {
source: err,
path: path.to_owned(),
})?;
let reader = BufReader::new(file);
let config = serde_json::from_reader(reader).map_err(|err| ConfigError::LoadParse {
source: err,
path: path.to_owned(),
})?;
Ok(config)
}
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
#[test]
fn test_config_from_spec() -> Result<()> {
let container_id = "sample";
let spec = Spec::default();
let config = YoukiConfig::from_spec(&spec, container_id)?;
assert_eq!(&config.hooks, spec.hooks());
dbg!(&config.cgroup_path);
assert_eq!(
config.cgroup_path,
PathBuf::from(format!(":youki:{container_id}"))
);
Ok(())
}
#[test]
fn test_config_save_and_load() -> Result<()> {
let container_id = "sample";
let tmp = tempfile::tempdir().expect("create temp dir");
let spec = Spec::default();
let config = YoukiConfig::from_spec(&spec, container_id)?;
config.save(&tmp)?;
let act = YoukiConfig::load(&tmp)?;
assert_eq!(act, config);
Ok(())
}
}