Skip to content

Commit

Permalink
Merge pull request #499 from Furisto/systemd-part3
Browse files Browse the repository at this point in the history
Support resource restrictions for rootless containers
  • Loading branch information
utam0k authored Nov 28, 2021
2 parents 54cbd15 + 1a14c43 commit 8310ac4
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 118 deletions.
9 changes: 8 additions & 1 deletion crates/libcgroups/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,18 @@ pub fn create_cgroup_manager<P: Into<PathBuf>>(
if !systemd::booted() {
bail!("systemd cgroup flag passed, but systemd support for managing cgroups is not available");
}
log::info!("systemd cgroup manager will be used");

let use_system = nix::unistd::geteuid().is_root();

log::info!(
"systemd cgroup manager with system bus {} will be used",
use_system
);
return Ok(Box::new(systemd::manager::Manager::new(
DEFAULT_CGROUP_ROOT.into(),
cgroup_path.into(),
container_name.into(),
use_system,
)?));
}
log::info!("cgroup manager V2 will be used");
Expand Down
66 changes: 60 additions & 6 deletions crates/libcgroups/src/systemd/dbus/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,54 @@ use anyhow::{Context, Result};
use dbus::arg::{RefArg, Variant};
use dbus::blocking::{Connection, Proxy};
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;

pub trait SystemdClient {
fn is_system(&self) -> bool;

fn start_transient_unit(
&self,
container_name: &str,
pid: u32,
parent: &str,
unit_name: &str,
) -> Result<()>;

fn stop_transient_unit(&self, unit_name: &str) -> Result<()>;

fn set_unit_properties(
&self,
unit_name: &str,
properties: &HashMap<&str, Box<dyn RefArg>>,
) -> Result<()>;

fn systemd_version(&self) -> Result<u32>;

fn control_cgroup_root(&self) -> Result<PathBuf>;
}

/// Client is a wrapper providing higher level API and abatraction around dbus.
/// For more information see https://www.freedesktop.org/wiki/Software/systemd/dbus/
pub struct Client {
conn: Connection,
system: bool,
}

impl Client {
pub fn new() -> Result<Self> {
/// Uses the system bus to communicate with systemd
pub fn new_system() -> Result<Self> {
let conn = Connection::new_system()?;
Ok(Client { conn })
Ok(Client { conn, system: true })
}

/// Uses the session bus to communicate with systemd
pub fn new_session() -> Result<Self> {
let conn = Connection::new_session()?;
Ok(Client {
conn,
system: false,
})
}

fn create_proxy(&self) -> Proxy<&Connection> {
Expand All @@ -24,11 +60,17 @@ impl Client {
Duration::from_millis(5000),
)
}
}

impl SystemdClient for Client {
fn is_system(&self) -> bool {
self.system
}

/// start_transient_unit is a higher level API for starting a unit
/// for a specific container under systemd.
/// See https://www.freedesktop.org/wiki/Software/systemd/dbus for more details.
pub fn start_transient_unit(
fn start_transient_unit(
&self,
container_name: &str,
pid: u32,
Expand Down Expand Up @@ -70,6 +112,8 @@ impl Client {
properties.push(("DefaultDependencies", Variant(Box::new(false))));
properties.push(("PIDs", Variant(Box::new(vec![pid]))));

log::debug!("START UNIT: {:?}", properties);

proxy
.start_transient_unit(unit_name, "replace", properties, vec![])
.with_context(|| {
Expand All @@ -81,7 +125,7 @@ impl Client {
Ok(())
}

pub fn stop_transient_unit(&self, unit_name: &str) -> Result<()> {
fn stop_transient_unit(&self, unit_name: &str) -> Result<()> {
let proxy = self.create_proxy();

proxy
Expand All @@ -90,7 +134,7 @@ impl Client {
Ok(())
}

pub fn set_unit_properties(
fn set_unit_properties(
&self,
unit_name: &str,
properties: &HashMap<&str, Box<dyn RefArg>>,
Expand All @@ -108,7 +152,7 @@ impl Client {
Ok(())
}

pub fn systemd_version(&self) -> Result<u32> {
fn systemd_version(&self) -> Result<u32> {
let proxy = self.create_proxy();

let version = proxy
Expand All @@ -123,4 +167,14 @@ impl Client {

Ok(version)
}

fn control_cgroup_root(&self) -> Result<PathBuf> {
let proxy = self.create_proxy();

let cgroup_root = proxy
.control_group()
.context("failed to get systemd control group")?;
PathBuf::try_from(&cgroup_root)
.with_context(|| format!("parse systemd control cgroup {} into path", cgroup_root))
}
}
Loading

0 comments on commit 8310ac4

Please sign in to comment.