Skip to content

Commit

Permalink
Add per command cgroup manager option
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Michaelis <code@mgjm.de>
  • Loading branch information
mgjm committed Jul 18, 2023
1 parent 97d6b46 commit 95f0b90
Show file tree
Hide file tree
Showing 7 changed files with 375 additions and 280 deletions.
7 changes: 7 additions & 0 deletions conmon-rs/common/proto/conmon.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ interface Conmon {
metadataOld @10 :Data; # deprecated
metadata @11 :Metadata; # Standard metadata to carry.
envVars @12 :TextTextMap;
cgroupManager @13 :CgroupManager;
}

struct LogDriver {
Expand All @@ -58,6 +59,11 @@ interface Conmon {
}
}

enum CgroupManager {
systemd @0;
cgroupfs @1;
}

struct CreateContainerResponse {
containerPid @0 :UInt32;
}
Expand All @@ -74,6 +80,7 @@ interface Conmon {
metadataOld @4 :Data; # deprecated
metadata @5 :Metadata; # Standard metadata to carry.
envVars @6 :TextTextMap;
cgroupManager @7 :CgroupManager;
}

struct ExecSyncContainerResponse {
Expand Down
47 changes: 4 additions & 43 deletions conmon-rs/server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,10 @@ pub struct Config {
/// Do not fork if true.
skip_fork: bool,

#[get_copy = "pub"]
#[arg(
default_value_t,
env(concat!(prefix!(), "CGROUP_MANAGER")),
long("cgroup-manager"),
short('c'),
value_enum,
value_name("MANAGER")
)]
/// Select the cgroup manager to be used.
cgroup_manager: CgroupManager,
// TODO: remove in next major release
#[arg(default_value(""), long("cgroup-manager"), short('c'), hide(true))]
/// (ignored for backwards compatibility)
cgroup_manager: String,

#[get_copy = "pub"]
#[arg(
Expand Down Expand Up @@ -301,38 +294,6 @@ impl Default for LogDriver {
}
}

#[derive(
AsRefStr,
Clone,
Copy,
Debug,
Deserialize,
Display,
EnumIter,
EnumString,
Eq,
Hash,
IntoStaticStr,
PartialEq,
Serialize,
ValueEnum,
)]
#[strum(serialize_all = "lowercase")]
/// Available cgroup managers.
pub enum CgroupManager {
/// Use systemd to create and manage cgroups
Systemd,

/// Use the cgroup filesystem to create and manage cgroups
Cgroupfs,
}

impl Default for CgroupManager {
fn default() -> Self {
Self::Systemd
}
}

impl Default for Config {
fn default() -> Self {
Self::parse()
Expand Down
34 changes: 22 additions & 12 deletions conmon-rs/server/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
container_io::{ContainerIO, SharedContainerIO},
container_log::ContainerLog,
pause::Pause,
server::Server,
server::{GenerateRuntimeArgs, Server},
telemetry::Telemetry,
version::Version,
};
Expand Down Expand Up @@ -121,16 +121,17 @@ impl conmon::Server for Server {
debug!("PID file is {}", pidfile.display());

let child_reaper = self.reaper().clone();
let global_args = capnp_vec_str!(req.get_global_args());
let command_args = capnp_vec_str!(req.get_command_args());
let args = pry_err!(self.generate_create_args(
&id,
bundle_path,
&container_io,
&pidfile,
global_args,
command_args
));
let global_args = pry!(req.get_global_args());
let command_args = pry!(req.get_command_args());
let cgroup_manager = pry!(req.get_cgroup_manager());
let args = GenerateRuntimeArgs {
config: self.config(),
id: &id,
container_io: &container_io,
pidfile: &pidfile,
cgroup_manager,
};
let args = pry_err!(args.create_args(bundle_path, global_args, command_args));
let stdin = req.get_stdin();
let runtime = self.config().runtime().clone();
let exit_paths = capnp_vec_path!(req.get_exit_paths());
Expand Down Expand Up @@ -213,8 +214,17 @@ impl conmon::Server for Server {
let mut container_io = pry_err!(ContainerIO::new(req.get_terminal(), logger));

let command = pry!(req.get_command());
let args = pry_err!(self.generate_exec_sync_args(&id, &pidfile, &container_io, &command));
let env_vars = pry!(req.get_env_vars().and_then(capnp_util::into_map));
let cgroup_manager = pry!(req.get_cgroup_manager());

let args = GenerateRuntimeArgs {
config: self.config(),
id: &id,
container_io: &container_io,
pidfile: &pidfile,
cgroup_manager,
};
let args = pry_err!(args.exec_sync_args(command));

Promise::from_future(
async move {
Expand Down
67 changes: 37 additions & 30 deletions conmon-rs/server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
child_reaper::ChildReaper,
config::{CgroupManager, Commands, Config, LogDriver, Verbosity},
config::{Commands, Config, LogDriver, Verbosity},
container_io::{ContainerIO, ContainerIOType},
init::{DefaultInit, Init},
journal::Journal,
Expand All @@ -14,7 +14,7 @@ use crate::{
use anyhow::{format_err, Context, Result};
use capnp::text_list::Reader;
use capnp_rpc::{rpc_twoparty_capnp::Side, twoparty, RpcSystem};
use conmon_common::conmon_capnp::conmon;
use conmon_common::conmon_capnp::conmon::{self, CgroupManager};
use futures::{AsyncReadExt, FutureExt};
use getset::Getters;
use nix::{
Expand Down Expand Up @@ -279,80 +279,87 @@ impl Server {
task::spawn_local(Box::pin(rpc_system.map(|_| ())));
}
}
}

pub(crate) struct GenerateRuntimeArgs<'a> {
pub(crate) config: &'a Config,
pub(crate) id: &'a str,
pub(crate) container_io: &'a ContainerIO,
pub(crate) pidfile: &'a Path,
pub(crate) cgroup_manager: CgroupManager,
}

impl GenerateRuntimeArgs<'_> {
const SYSTEMD_CGROUP_ARG: &'static str = "--systemd-cgroup";

/// Generate the OCI runtime CLI arguments from the provided parameters.
pub(crate) fn generate_create_args(
&self,
id: &str,
pub fn create_args(
self,
bundle_path: &Path,
container_io: &ContainerIO,
pidfile: &Path,
global_args: Vec<String>,
command_args: Vec<String>,
global_args: Reader,
command_args: Reader,
) -> Result<Vec<String>> {
let mut args = vec![];

if let Some(rr) = self.config().runtime_root() {
if let Some(rr) = self.config.runtime_root() {
args.push(format!("--root={}", rr.display()));
}

if self.config().cgroup_manager() == CgroupManager::Systemd {
if self.cgroup_manager == CgroupManager::Systemd {
args.push(Self::SYSTEMD_CGROUP_ARG.into());
}

args.extend(global_args);
for arg in global_args {
args.push(arg?.to_string());
}

args.extend([
"create".to_string(),
"--bundle".to_string(),
bundle_path.display().to_string(),
"--pid-file".to_string(),
pidfile.display().to_string(),
self.pidfile.display().to_string(),
]);

args.extend(command_args);
for arg in command_args {
args.push(arg?.to_string());
}

if let ContainerIOType::Terminal(terminal) = container_io.typ() {
if let ContainerIOType::Terminal(terminal) = self.container_io.typ() {
args.push(format!("--console-socket={}", terminal.path().display()));
}
args.push(id.into());

args.push(self.id.into());

debug!("Runtime args {:?}", args.join(" "));
Ok(args)
}

/// Generate the OCI runtime CLI arguments from the provided parameters.
pub(crate) fn generate_exec_sync_args(
&self,
id: &str,
pidfile: &Path,
container_io: &ContainerIO,
command: &Reader,
) -> Result<Vec<String>> {
pub(crate) fn exec_sync_args(&self, command: Reader) -> Result<Vec<String>> {
let mut args = vec![];

if let Some(rr) = self.config().runtime_root() {
if let Some(rr) = self.config.runtime_root() {
args.push(format!("--root={}", rr.display()));
}

if self.config().cgroup_manager() == CgroupManager::Systemd {
if self.cgroup_manager == CgroupManager::Systemd {
args.push(Self::SYSTEMD_CGROUP_ARG.into());
}

args.push("exec".to_string());
args.push("-d".to_string());

if let ContainerIOType::Terminal(terminal) = container_io.typ() {
if let ContainerIOType::Terminal(terminal) = self.container_io.typ() {
args.push(format!("--console-socket={}", terminal.path().display()));
args.push("--tty".to_string());
}

args.push(format!("--pid-file={}", pidfile.display()));
args.push(id.into());
args.push(format!("--pid-file={}", self.pidfile.display()));
args.push(self.id.into());

for value in command.iter() {
args.push(value?.to_string());
for arg in command {
args.push(arg?.to_string());
}

debug!("Exec args {:?}", args.join(" "));
Expand Down
Loading

0 comments on commit 95f0b90

Please sign in to comment.