1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-06-10 00:36:16 +02:00

Merge pull request #536 from knight42/feat/add-update-cmd

implement the update subcommand(partially)
This commit is contained in:
utam0k 2021-12-16 17:47:47 +09:00 committed by GitHub
commit a01252ae4c
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 105 additions and 74 deletions

14
Cargo.lock generated
View File

@ -588,9 +588,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.20"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7a30908dbce072eca83216eab939d2290080e00ca71611b96a09e5cdce5f3fa"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
@ -730,7 +730,7 @@ dependencies = [
"libc",
"log",
"nix",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=54c5e386f01ab37c9305cc4a83404eb157e42440)",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=12dcd858543db0e7bfb1ef053d1b748f2fda74ee)",
"procfs",
"quickcheck",
"rbpf",
@ -755,7 +755,7 @@ dependencies = [
"log",
"mio",
"nix",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=54c5e386f01ab37c9305cc4a83404eb157e42440)",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=12dcd858543db0e7bfb1ef053d1b748f2fda74ee)",
"path-clean",
"prctl",
"procfs",
@ -938,7 +938,7 @@ dependencies = [
[[package]]
name = "oci-spec"
version = "0.5.2"
source = "git+https://github.com/containers/oci-spec-rs?rev=54c5e386f01ab37c9305cc4a83404eb157e42440#54c5e386f01ab37c9305cc4a83404eb157e42440"
source = "git+https://github.com/containers/oci-spec-rs?rev=12dcd858543db0e7bfb1ef053d1b748f2fda74ee#12dcd858543db0e7bfb1ef053d1b748f2fda74ee"
dependencies = [
"derive_builder",
"getset",
@ -951,7 +951,7 @@ dependencies = [
[[package]]
name = "oci-spec"
version = "0.5.2"
source = "git+https://github.com/containers/oci-spec-rs?rev=d6fb1e91742313cd0d0085937e2d6df5d4669720#d6fb1e91742313cd0d0085937e2d6df5d4669720"
source = "git+https://github.com/containers/oci-spec-rs?rev=54c5e386f01ab37c9305cc4a83404eb157e42440#54c5e386f01ab37c9305cc4a83404eb157e42440"
dependencies = [
"derive_builder",
"getset",
@ -1671,7 +1671,7 @@ dependencies = [
"liboci-cli",
"log",
"nix",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=d6fb1e91742313cd0d0085937e2d6df5d4669720)",
"oci-spec 0.5.2 (git+https://github.com/containers/oci-spec-rs?rev=12dcd858543db0e7bfb1ef053d1b748f2fda74ee)",
"once_cell",
"pentacle",
"procfs",

View File

@ -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"] }
@ -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"] }

View File

@ -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"
@ -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"

View File

@ -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
@ -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),
}

View File

@ -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>,
}

View File

@ -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"

View File

@ -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;
@ -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
@ -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())
}

View File

@ -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)?;
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);
}
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);
}
}
}

View File

@ -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(())
}

View File

@ -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),