Skip to content

Commit

Permalink
Merge pull request #536 from knight42/feat/add-update-cmd
Browse files Browse the repository at this point in the history
implement the update subcommand(partially)
  • Loading branch information
utam0k authored Dec 16, 2021
2 parents 0be33bf + 09ecfba commit a01252a
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 74 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/libcgroups/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ nix = "0.23.0"
procfs = "0.12.0"
log = "0.4"
anyhow = "1.0"
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "54c5e386f01ab37c9305cc4a83404eb157e42440" }
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "12dcd858543db0e7bfb1ef053d1b748f2fda74ee" }
dbus = { version = "0.9.5", optional = true }
fixedbitset = "0.4.0"
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -26,7 +26,7 @@ errno = { version = "0.2.8", optional = true }
libc = { version = "0.2.112", optional = true }

[dev-dependencies]
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "54c5e386f01ab37c9305cc4a83404eb157e42440", features = ["proptests"] }
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "12dcd858543db0e7bfb1ef053d1b748f2fda74ee", features = ["proptests"] }
quickcheck = "1"
clap = "3.0.0-beta.5"
serde = { version = "1.0", features = ["derive"] }
Expand Down
6 changes: 3 additions & 3 deletions crates/libcontainer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ libc = "0.2.112"
log = "0.4"
mio = { version = "0.8.0", features = ["os-ext", "os-poll"] }
nix = "0.23.0"
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "54c5e386f01ab37c9305cc4a83404eb157e42440" }
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "12dcd858543db0e7bfb1ef053d1b748f2fda74ee" }
path-clean = "0.1.0"
procfs = "0.12.0"
prctl = "1.0.0"
Expand All @@ -28,6 +28,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dev-dependencies]
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "54c5e386f01ab37c9305cc4a83404eb157e42440", features = ["proptests"] }
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "12dcd858543db0e7bfb1ef053d1b748f2fda74ee", features = ["proptests"] }
quickcheck = "1"
serial_test = "0.5.1"
serial_test = "0.5.1"
6 changes: 4 additions & 2 deletions crates/liboci-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ mod ps;
mod resume;
mod run;
mod spec;
mod update;

pub use {
events::Events, exec::Exec, list::List, pause::Pause, ps::Ps, resume::Resume, run::Run,
spec::Spec,
spec::Spec, update::Update,
};

// Subcommands parsed by liboci-cli, based on the [OCI
Expand All @@ -51,10 +52,11 @@ pub enum CommonCmd {
Exec(Exec),
List(List),
Pause(Pause),
#[clap(setting=clap::AppSettings::AllowLeadingHyphen)]
#[clap(setting = clap::AppSettings::AllowLeadingHyphen)]
Ps(Ps),
Resume(Resume),
Run(Run),
Update(Update),
Spec(Spec),
}

Expand Down
12 changes: 12 additions & 0 deletions crates/liboci-cli/src/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use clap::Parser;

/// Update running container resource constraints
#[derive(Parser, Debug)]
pub struct Update {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,

/// Set the maximum number of processes allowed in the container
#[clap(long)]
pub pids_limit: Option<i64>,
}
2 changes: 1 addition & 1 deletion crates/youki/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ libcontainer = { path = "../libcontainer" }
liboci-cli = { path = "../liboci-cli" }
log = {version = "0.4", features = ["std"]}
nix = "0.23.0"
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "d6fb1e91742313cd0d0085937e2d6df5d4669720" }
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "12dcd858543db0e7bfb1ef053d1b748f2fda74ee" }
once_cell = "1.9.0"
pentacle = "1.0.0"
procfs = "0.12.0"
Expand Down
15 changes: 15 additions & 0 deletions crates/youki/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::{bail, Context, Result};
use std::{fs, path::Path};

use libcgroups::common::CgroupManager;
use libcontainer::container::Container;

pub mod completion;
Expand All @@ -18,6 +19,7 @@ pub mod run;
pub mod spec_json;
pub mod start;
pub mod state;
pub mod update;

fn load_container<P: AsRef<Path>>(root_path: P, container_id: &str) -> Result<Container> {
// resolves relative paths, symbolic links etc. and get complete path
Expand All @@ -32,3 +34,16 @@ fn load_container<P: AsRef<Path>>(root_path: P, container_id: &str) -> Result<Co
Container::load(container_root)
.with_context(|| format!("could not load state for container {}", container_id))
}

fn create_cgroup_manager<P: AsRef<Path>>(
root_path: P,
container_id: &str,
) -> Result<Box<dyn CgroupManager>> {
let container = load_container(root_path, container_id)?;
let cgroups_path = container.spec()?.cgroup_path;
let systemd_cgroup = container
.systemd()
.context("could not determine cgroup manager")?;

libcgroups::common::create_cgroup_manager(cgroups_path, systemd_cgroup, container.id())
}
93 changes: 34 additions & 59 deletions crates/youki/src/commands/ps.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,42 @@
use anyhow::{bail, Context, Result};
use libcgroups;
use libcontainer::{container::Container, utils};
use crate::commands::create_cgroup_manager;
use anyhow::{bail, Result};
use liboci_cli::Ps;
use std::{path::PathBuf, process::Command};

pub fn ps(args: Ps, root_path: PathBuf) -> Result<()> {
let container_root = root_path.join(&args.container_id);
if !container_root.exists() {
bail!("{} doesn't exist.", args.container_id)
}
let container = Container::load(container_root)?;
if container.root.exists() {
let config_absolute_path = container.root.join("config.json");
log::debug!("load spec from {:?}", config_absolute_path);
let spec = oci_spec::runtime::Spec::load(config_absolute_path)?;
log::debug!("spec: {:?}", spec);
let cgroups_path = utils::get_cgroup_path(
spec.linux()
.as_ref()
.context("no linux in spec")?
.cgroups_path(),
container.id(),
);
let systemd_cgroup = container
.systemd()
.context("could not determine cgroup manager")?;
let cmanager = libcgroups::common::create_cgroup_manager(
cgroups_path,
systemd_cgroup,
container.id(),
)?;
let pids: Vec<i32> = cmanager
.get_all_pids()?
.iter()
.map(|pid| pid.as_raw())
.collect();
let cmanager = create_cgroup_manager(root_path, &args.container_id)?;

let pids: Vec<i32> = cmanager
.get_all_pids()?
.iter()
.map(|pid| pid.as_raw())
.collect();

if args.format == "json" {
println!("{}", serde_json::to_string(&pids)?);
} else if args.format == "table" {
let default_ps_options = vec![String::from("-ef")];
let ps_options = if args.ps_options.is_empty() {
&default_ps_options
} else {
&args.ps_options
};
let output = Command::new("ps").args(ps_options).output()?;
if !output.status.success() {
println!("{}", std::str::from_utf8(&output.stderr)?);
} else {
let lines = std::str::from_utf8(&output.stdout)?;
let lines: Vec<&str> = lines.split('\n').collect();
let pid_index = get_pid_index(lines[0])?;
println!("{}", &lines[0]);
for line in &lines[1..] {
if line.is_empty() {
continue;
}
let fields: Vec<&str> = line.split_whitespace().collect();
let pid: i32 = fields[pid_index].parse()?;
if pids.contains(&pid) {
println!("{}", line);
}
if args.format == "json" {
println!("{}", serde_json::to_string(&pids)?);
} else if args.format == "table" {
let default_ps_options = vec![String::from("-ef")];
let ps_options = if args.ps_options.is_empty() {
&default_ps_options
} else {
&args.ps_options
};
let output = Command::new("ps").args(ps_options).output()?;
if !output.status.success() {
println!("{}", std::str::from_utf8(&output.stderr)?);
} else {
let lines = std::str::from_utf8(&output.stdout)?;
let lines: Vec<&str> = lines.split('\n').collect();
let pid_index = get_pid_index(lines[0])?;
println!("{}", &lines[0]);
for line in &lines[1..] {
if line.is_empty() {
continue;
}
let fields: Vec<&str> = line.split_whitespace().collect();
let pid: i32 = fields[pid_index].parse()?;
if pids.contains(&pid) {
println!("{}", line);
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions crates/youki/src/commands/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::path::PathBuf;

use crate::commands::create_cgroup_manager;
use anyhow::Result;
use libcgroups::{self, common::ControllerOpt};
use liboci_cli::Update;
use oci_spec::runtime::{LinuxPids, LinuxResources};

pub fn update(args: Update, root_path: PathBuf) -> Result<()> {
let cmanager = create_cgroup_manager(root_path, &args.container_id)?;

let mut linux_res = LinuxResources::default();
if let Some(new_pids_limit) = args.pids_limit {
let mut pids = LinuxPids::default();
pids.set_limit(new_pids_limit);
linux_res.set_pids(Some(pids));
}

cmanager.apply(&ControllerOpt {
resources: &linux_res,
disable_oom_killer: false,
oom_score_adj: None,
freezer_state: None,
})?;
Ok(())
}
1 change: 1 addition & 0 deletions crates/youki/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ fn main() -> Result<()> {
CommonCmd::Resume(resume) => commands::resume::resume(resume, root_path),
CommonCmd::Run(run) => commands::run::run(run, root_path, systemd_cgroup),
CommonCmd::Spec(spec) => commands::spec_json::spec(spec),
CommonCmd::Update(update) => commands::update::update(update, root_path),
},

SubCommand::Info(info) => commands::info::info(info),
Expand Down

0 comments on commit a01252a

Please sign in to comment.