1
0
mirror of https://github.com/containers/youki synced 2024-11-23 17:32:15 +01:00

Merge pull request #363 from alfonsoros88/signal

Use generic for signal argument in container_kill
This commit is contained in:
Furisto 2021-10-06 13:45:11 +02:00 committed by GitHub
commit 1e8329cb67
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 21 deletions

@ -1,10 +1,10 @@
//! Contains functionality of kill container command
use std::path::PathBuf;
use std::{convert::TryInto, path::PathBuf};
use anyhow::{Context, Result};
use anyhow::Result;
use clap::Clap;
use crate::{commands::load_container, signal::ToSignal};
use crate::{commands::load_container, signal::Signal};
/// Send the specified signal to the container
#[derive(Clap, Debug)]
@ -17,10 +17,7 @@ pub struct Kill {
impl Kill {
pub fn exec(&self, root_path: PathBuf) -> Result<()> {
let mut container = load_container(root_path, &self.container_id)?;
let signal = self
.signal
.to_signal()
.with_context(|| format!("signal {} is unknown", self.signal))?;
let signal: Signal = self.signal.as_str().try_into()?;
container.kill(signal)
}
}

@ -1,6 +1,7 @@
use super::{Container, ContainerStatus};
use crate::signal::Signal;
use anyhow::{bail, Context, Result};
use nix::sys::signal::{self, Signal};
use nix::sys::signal::{self};
impl Container {
/// Sends the specified signal to the container init process
@ -21,7 +22,8 @@ impl Container {
/// # Ok(())
/// # }
/// ```
pub fn kill(&mut self, signal: Signal) -> Result<()> {
pub fn kill<S: Into<Signal>>(&mut self, signal: S) -> Result<()> {
let signal = signal.into().into_raw();
self.refresh_status()
.context("failed to refresh container status")?;
if self.can_kill() {

@ -1,16 +1,19 @@
//! Returns *nix signal enum value from passed string
use anyhow::{bail, Result};
use nix::sys::signal::Signal;
use anyhow::{bail, Context, Result};
use nix::sys::signal::Signal as NixSignal;
use std::convert::TryFrom;
pub trait ToSignal<From = Self> {
fn to_signal(&self) -> Result<Signal>;
}
/// POSIX Signal
#[derive(Debug)]
pub struct Signal(NixSignal);
impl ToSignal for String {
fn to_signal(&self) -> Result<Signal> {
use Signal::*;
Ok(match self.to_ascii_uppercase().as_str() {
impl TryFrom<&str> for Signal {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
use NixSignal::*;
Ok(match s.to_ascii_uppercase().as_str() {
"1" | "HUP" | "SIGHUP" => SIGHUP,
"2" | "INT" | "SIGINT" => SIGINT,
"3" | "QUIT" | "SIGQUIT" => SIGQUIT,
@ -42,8 +45,31 @@ impl ToSignal for String {
"29" | "IO" | "SIGIO" => SIGIO,
"30" | "PWR" | "SIGPWR" => SIGPWR,
"31" | "SYS" | "SIGSYS" => SIGSYS,
_ => bail! {"{} is not a valid signal", self},
_ => bail! {"{} is not a valid signal", s},
})
.map(Signal)
}
}
impl TryFrom<i32> for Signal {
type Error = anyhow::Error;
fn try_from(value: i32) -> Result<Self, Self::Error> {
NixSignal::try_from(value)
.with_context(|| format!("{} is not a valid signal", value))
.map(Signal)
}
}
impl From<NixSignal> for Signal {
fn from(s: NixSignal) -> Self {
Signal(s)
}
}
impl Signal {
pub(crate) fn into_raw(self) -> NixSignal {
self.0
}
}
@ -89,13 +115,13 @@ mod tests {
test_sets.insert(SIGSYS, vec!["31", "SYS", "SIGSYS"]);
for (signal, strings) in test_sets {
for s in strings {
assert_eq!(signal, s.to_string().to_signal().unwrap());
assert_eq!(signal, Signal::try_from(s).unwrap().into_raw());
}
}
}
#[test]
fn test_conversion_from_string_should_be_failed() {
assert!("invalid".to_string().to_signal().is_err())
assert!(Signal::try_from("invalid").is_err())
}
}