Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split the subcommands into their own files. #110

Merged
merged 1 commit into from
Jun 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cgroups/v2/systemd_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl SystemDCGroupManager {
Ok(controllers)
}

fn write_controllers(path: &Path, controllers: &Vec<String>) -> Result<()> {
fn write_controllers(path: &Path, controllers: &[String]) -> Result<()> {
for controller in controllers {
common::write_cgroup_file_str(path.join(CGROUP_SUBTREE_CONTROL), controller)?;
}
Expand Down
67 changes: 67 additions & 0 deletions src/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::fs;
use std::path::Path;
use std::path::PathBuf;

use anyhow::{bail, Result};
use clap::Clap;

use crate::cgroups;
use crate::container::Container;
use crate::utils;

#[derive(Clap, Debug)]
pub struct Delete {
container_id: String,
// forces deletion of the container.
#[clap(short, long)]
force: bool,
}

impl Delete {
pub fn exec(&self, root_path: PathBuf, systemd_cgroup: bool) -> Result<()> {
log::debug!("start deleting {}", self.container_id);
// state of container is stored in a directory named as container id inside
// root directory given in commandline options
let container_root = root_path.join(&self.container_id);
if !container_root.exists() {
bail!("{} doesn't exist.", self.container_id)
}
// load container state from json file, and check status of the container
// it might be possible that delete is invoked on a running container.
log::debug!("load the container from {:?}", container_root);
let container = Container::load(container_root)?.refresh_status()?;
if container.can_delete() {
if container.root.exists() {
nix::unistd::chdir(&PathBuf::from(&container.state.bundle))?;
let config_absolute_path = &PathBuf::from(&container.state.bundle)
.join(Path::new("config.json"))
.to_string_lossy()
.to_string();
log::debug!("load spec from {:?}", config_absolute_path);
let spec = oci_spec::Spec::load(config_absolute_path)?;
log::debug!("spec: {:?}", spec);

// remove the directory storing container state
log::debug!("remove dir {:?}", container.root);
fs::remove_dir_all(&container.root)?;

let cgroups_path =
utils::get_cgroup_path(&spec.linux.unwrap().cgroups_path, container.id());

// remove the cgroup created for the container
// check https://man7.org/linux/man-pages/man7/cgroups.7.html
// creating and removing cgroups section for more information on cgroups
let cmanager =
cgroups::common::create_cgroup_manager(cgroups_path, systemd_cgroup)?;
cmanager.remove()?;
}
std::process::exit(0)
} else {
bail!(
"{} could not be deleted because it was {:?}",
container.id(),
container.status()
)
}
}
}
20 changes: 19 additions & 1 deletion src/info.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
use procfs::{CpuInfo, Meminfo};
use std::{fs, path::Path};

use anyhow::Result;
use clap::Clap;
use procfs::{CpuInfo, Meminfo};

use crate::cgroups;

#[derive(Clap, Debug)]
pub struct Info {}

impl Info {
pub fn exec(&self) -> Result<()> {
print_youki();
print_kernel();
print_os();
print_hardware();
print_cgroups();

Ok(())
}
}

pub fn print_youki() {
println!("{:<18}{}", "Version", env!("CARGO_PKG_VERSION"));
}
Expand Down
46 changes: 46 additions & 0 deletions src/kill.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use std::{fs, path::PathBuf};

use anyhow::{bail, Result};
use clap::Clap;
use nix::sys::signal as nix_signal;

use crate::{
container::{Container, ContainerStatus},
signal,
};

#[derive(Clap, Debug)]
pub struct Kill {
container_id: String,
signal: String,
}

impl Kill {
pub fn exec(&self, root_path: PathBuf) -> Result<()> {
// resolves relative paths, symbolic links etc. and get complete path
let root_path = fs::canonicalize(root_path)?;
// state of container is stored in a directory named as container id inside
// root directory given in commandline options
let container_root = root_path.join(&self.container_id);
if !container_root.exists() {
bail!("{} doesn't exist.", self.container_id)
}

// load container state from json file, and check status of the container
// it might be possible that kill is invoked on a already stopped container etc.
let container = Container::load(container_root)?.refresh_status()?;
if container.can_kill() {
let sig = signal::from_str(self.signal.as_str())?;
log::debug!("kill signal {} to {}", sig, container.pid().unwrap());
nix_signal::kill(container.pid().unwrap(), sig)?;
container.update_status(ContainerStatus::Stopped).save()?;
std::process::exit(0)
} else {
bail!(
"{} could not be killed because it was {:?}",
container.id(),
container.status()
)
}
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ pub mod command;
pub mod container;
pub mod create;
pub mod dbus;
pub mod delete;
pub mod info;
pub mod kill;
pub mod list;
pub mod logger;
pub mod namespaces;
pub mod notify_socket;
Expand All @@ -18,6 +21,7 @@ pub mod rootfs;
pub mod rootless;
pub mod signal;
pub mod start;
pub mod state;
pub mod stdio;
pub mod tty;
pub mod utils;
67 changes: 67 additions & 0 deletions src/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::ffi::OsString;
use std::fs;
use std::io;
use std::io::Write;
use std::path::PathBuf;

use anyhow::Result;
use chrono::{DateTime, Local};
use clap::Clap;
use tabwriter::TabWriter;

use crate::container::Container;

#[derive(Clap, Debug)]
pub struct List {}

impl List {
pub fn exec(&self, root_path: PathBuf) -> Result<()> {
let root_path = fs::canonicalize(root_path)?;
let mut content = String::new();

for container_dir in fs::read_dir(root_path)? {
let container_dir = container_dir?.path();
let state_file = container_dir.join("state.json");
if !state_file.exists() {
continue;
}

let container = Container::load(container_dir)?.refresh_status()?;
let pid = if let Some(pid) = container.pid() {
pid.to_string()
} else {
"".to_owned()
};

let user_name = if let Some(creator) = container.creator() {
creator
} else {
OsString::new()
};

let created = if let Some(utc) = container.created() {
let local: DateTime<Local> = DateTime::from(utc);
local.to_rfc3339_opts(chrono::SecondsFormat::Secs, false)
} else {
"".to_owned()
};

content.push_str(&format!(
"{}\t{}\t{}\t{}\t{}\t{}\n",
container.id(),
pid,
container.status(),
container.bundle(),
created,
user_name.to_string_lossy()
));
}

let mut tab_writer = TabWriter::new(io::stdout());
writeln!(&mut tab_writer, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tCREATOR")?;
write!(&mut tab_writer, "{}", content)?;
tab_writer.flush()?;

Ok(())
}
}
Loading