Skip to content

Commit

Permalink
Merge pull request #38 from jacobtread-contrib/fix-windows-builds
Browse files Browse the repository at this point in the history
fix: update windows for new changes
  • Loading branch information
jkfran committed May 29, 2024
2 parents 4997258 + 64d2e5a commit 0412124
Show file tree
Hide file tree
Showing 16 changed files with 617 additions and 200 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
- s390x-unknown-linux-gnu
- aarch64-apple-darwin
- x86_64-apple-darwin
- x86_64-pc-windows-gnu
runs-on: ${{ (matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin') && 'macos-latest' || 'ubuntu-latest' }}
steps:
- name: Checkout repository
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
- s390x-unknown-linux-gnu
- aarch64-apple-darwin
- x86_64-apple-darwin
# - x86_64-pc-windows-gnu
- x86_64-pc-windows-gnu
runs-on: ${{ (matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin') && 'macos-latest' || 'ubuntu-latest' }}
steps:
- name: Checkout repository
Expand Down
18 changes: 5 additions & 13 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use clap::{Parser, ValueEnum};
use clap_verbosity_flag::{Verbosity, WarnLevel};
use core::fmt;
use nix::sys::signal::Signal;
use std::str::FromStr;

use crate::signal::KillportSignal;

/// Modes of operation for killport.
#[derive(Debug, Clone, Copy, PartialEq, ValueEnum)]
Expand Down Expand Up @@ -67,7 +67,7 @@ pub struct KillPortArgs {
default_value = "sigkill",
value_parser = parse_signal
)]
pub signal: Signal,
pub signal: KillportSignal,

/// A verbosity flag to control the level of logging output.
#[command(flatten)]
Expand All @@ -81,14 +81,6 @@ pub struct KillPortArgs {
pub dry_run: bool,
}

fn parse_signal(arg: &str) -> Result<Signal, std::io::Error> {
let str_arg = arg.parse::<String>();
match str_arg {
Ok(str_arg) => {
let signal_str = str_arg.to_uppercase();
let signal = Signal::from_str(signal_str.as_str())?;
return Ok(signal);
}
Err(e) => Err(std::io::Error::new(std::io::ErrorKind::Other, e)),
}
fn parse_signal(arg: &str) -> Result<KillportSignal, std::io::Error> {
arg.to_uppercase().parse()
}
10 changes: 3 additions & 7 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::signal::KillportSignal;
use bollard::container::{KillContainerOptions, ListContainersOptions};
use bollard::Docker;
use log::debug;
use nix::sys::signal::Signal;
use std::collections::HashMap;
use std::io::Error;
use tokio::runtime::Runtime;
Expand All @@ -17,7 +17,7 @@ impl DockerContainer {
///
/// * `name` - A container name.
/// * `signal` - A enum value representing the signal type.
pub fn kill_container(name: &String, signal: Signal) -> Result<(), Error> {
pub fn kill_container(name: &str, signal: KillportSignal) -> Result<(), Error> {
let rt = Runtime::new()?;
rt.block_on(async {
let docker = Docker::connect_with_socket_defaults()
Expand Down Expand Up @@ -63,11 +63,7 @@ impl DockerContainer {
.as_ref()?
.first()
.map(|name| DockerContainer {
name: if name.starts_with('/') {
name[1..].to_string()
} else {
name.clone()
},
name: name.strip_prefix('/').unwrap_or(name).to_string(),
})
})
.collect())
Expand Down
93 changes: 31 additions & 62 deletions src/killport.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,34 @@
use crate::cli::Mode;
use crate::docker::DockerContainer;
#[cfg(target_os = "linux")]
use crate::linux::find_target_processes;
#[cfg(target_os = "macos")]
use crate::macos::find_target_processes;
use log::info;
use nix::sys::signal::{kill, Signal};
use nix::unistd::Pid;
use std::io::Error;

#[derive(Debug)]
pub struct NativeProcess {
/// System native process ID.
pub pid: Pid,
pub name: String,
}
#[cfg(target_os = "windows")]
use crate::windows::find_target_processes;
use crate::{cli::Mode, signal::KillportSignal};
use std::{fmt::Display, io::Error};

/// Interface for killable targets such as native process and docker container.
pub trait Killable {
fn kill(&self, signal: Signal) -> Result<bool, Error>;
fn get_type(&self) -> String;
fn kill(&self, signal: KillportSignal) -> Result<bool, Error>;

fn get_type(&self) -> KillableType;

fn get_name(&self) -> String;
}

impl Killable for NativeProcess {
/// Entry point to kill the linux native process.
///
/// # Arguments
///
/// * `signal` - A enum value representing the signal type.
fn kill(&self, signal: Signal) -> Result<bool, Error> {
info!("Killing process '{}' with PID {}", self.name, self.pid);

kill(self.pid, signal).map(|_| true).map_err(|e| {
Error::new(
std::io::ErrorKind::Other,
format!(
"Failed to kill process '{}' with PID {}: {}",
self.name, self.pid, e
),
)
})
}

/// Returns the type of the killable target.
///
/// This method is used to identify the type of the target (either a native process or a Docker container)
/// that is being handled. This information can be useful for logging, error handling, or other needs
/// where type of the target is relevant.
///
/// # Returns
///
/// * `String` - A string that describes the type of the killable target. For a `NativeProcess` it will return "process",
/// and for a `DockerContainer` it will return "container".
fn get_type(&self) -> String {
"process".to_string()
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum KillableType {
Process,
Container,
}

fn get_name(&self) -> String {
self.name.to_string()
impl Display for KillableType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
KillableType::Process => "process",
KillableType::Container => "container",
})
}
}

Expand All @@ -68,10 +38,8 @@ impl Killable for DockerContainer {
/// # Arguments
///
/// * `signal` - A enum value representing the signal type.
fn kill(&self, signal: Signal) -> Result<bool, Error> {
if let Err(err) = Self::kill_container(&self.name, signal) {
return Err(err);
}
fn kill(&self, signal: KillportSignal) -> Result<bool, Error> {
Self::kill_container(&self.name, signal)?;

Ok(true)
}
Expand All @@ -84,10 +52,10 @@ impl Killable for DockerContainer {
///
/// # Returns
///
/// * `String` - A string that describes the type of the killable target. For a `NativeProcess` it will return "process",
/// * `String` - A string that describes the type of the killable target. For a `UnixProcess` it will return "process",
/// and for a `DockerContainer` it will return "container".
fn get_type(&self) -> String {
"container".to_string()
fn get_type(&self) -> KillableType {
KillableType::Container
}

fn get_name(&self) -> String {
Expand All @@ -104,10 +72,10 @@ pub trait KillportOperations {
fn kill_service_by_port(
&self,
port: u16,
signal: Signal,
signal: KillportSignal,
mode: Mode,
dry_run: bool,
) -> Result<Vec<(String, String)>, Error>;
) -> Result<Vec<(KillableType, String)>, Error>;
}

pub struct Killport;
Expand All @@ -133,9 +101,10 @@ impl KillportOperations for Killport {

for process in target_processes {
// Check if the process name contains 'docker' and skip if in docker mode
if docker_present && process.name.to_lowercase().contains("docker") {
if docker_present && process.get_name().to_lowercase().contains("docker") {
continue;
}

target_killables.push(Box::new(process));
}
}
Expand Down Expand Up @@ -166,10 +135,10 @@ impl KillportOperations for Killport {
fn kill_service_by_port(
&self,
port: u16,
signal: Signal,
signal: KillportSignal,
mode: Mode,
dry_run: bool,
) -> Result<Vec<(String, String)>, Error> {
) -> Result<Vec<(KillableType, String)>, Error> {
let mut results = Vec::new();
let target_killables = self.find_target_killables(port, mode)?; // Use the existing function to find targets

Expand All @@ -179,7 +148,7 @@ impl KillportOperations for Killport {
results.push((killable.get_type(), killable.get_name()));
} else {
// In actual mode, attempt to kill the entity and collect its information if successful
if killable.kill(signal)? {
if killable.kill(signal.clone())? {
results.push((killable.get_type(), killable.get_name()));
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
pub mod cli;
pub mod docker;
pub mod killport;
pub mod signal;

#[cfg(unix)]
pub mod unix;

#[cfg(target_os = "linux")]
pub mod linux;
#[cfg(target_os = "macos")]
Expand Down
11 changes: 4 additions & 7 deletions src/linux.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::killport::NativeProcess;
use crate::unix::UnixProcess;

use log::debug;
use nix::unistd::Pid;
Expand Down Expand Up @@ -75,8 +75,8 @@ fn find_target_inodes(port: u16) -> Vec<u64> {
/// # Arguments
///
/// * `inodes` - Target inodes
pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, Error> {
let mut target_pids: Vec<NativeProcess> = vec![];
pub fn find_target_processes(port: u16) -> Result<Vec<UnixProcess>, Error> {
let mut target_pids: Vec<UnixProcess> = vec![];
let inodes = find_target_inodes(port);

for inode in inodes {
Expand All @@ -96,10 +96,7 @@ pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, Error> {
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
.join(" ");
debug!("Found process '{}' with PID {}", name, process.pid());
target_pids.push(NativeProcess {
pid: Pid::from_raw(process.pid),
name: name,
});
target_pids.push(UnixProcess::new(Pid::from_raw(process.pid), name));
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/macos.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::killport::NativeProcess;
use crate::unix::UnixProcess;

use libproc::libproc::file_info::pidfdinfo;
use libproc::libproc::file_info::{ListFDs, ProcFDType};
Expand All @@ -16,8 +16,8 @@ use std::io;
/// # Arguments
///
/// * `port` - Target port number
pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, io::Error> {
let mut target_pids: Vec<NativeProcess> = vec![];
pub fn find_target_processes(port: u16) -> Result<Vec<UnixProcess>, io::Error> {
let mut target_pids: Vec<UnixProcess> = vec![];

if let Ok(procs) = pids_by_type(ProcFilter::All) {
for p in procs {
Expand Down Expand Up @@ -56,10 +56,10 @@ pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, io::Error>
"Found process '{}' with PID {} listening on port {}",
process_name, pid, port
);
target_pids.push(NativeProcess {
pid: Pid::from_raw(pid),
name: process_name,
});
target_pids.push(UnixProcess::new(
Pid::from_raw(pid),
process_name,
));
}
}
_ => (),
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {

// Attempt to kill processes listening on specified ports
for port in args.ports {
match killport.kill_service_by_port(port, args.signal, args.mode, args.dry_run) {
match killport.kill_service_by_port(port, args.signal.clone(), args.mode, args.dry_run) {
Ok(killed_services) => {
if killed_services.is_empty() {
println!("No {} found using port {}", service_type_singular, port);
Expand Down
35 changes: 35 additions & 0 deletions src/signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Wrapper around signals for platforms that they are not supported on

use std::{fmt::Display, str::FromStr};

#[cfg(unix)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KillportSignal(pub nix::sys::signal::Signal);

/// On a platform where we don't have the proper signals enum
#[cfg(not(unix))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KillportSignal(pub String);

impl Display for KillportSignal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.0, f)
}
}

impl FromStr for KillportSignal {
type Err = std::io::Error;

fn from_str(value: &str) -> Result<Self, Self::Err> {
#[cfg(unix)]
{
let signal = nix::sys::signal::Signal::from_str(value)?;
Ok(KillportSignal(signal))
}

#[cfg(not(unix))]
{
Ok(KillportSignal(value.to_string()))
}
}
}
Loading

0 comments on commit 0412124

Please sign in to comment.