Skip to content

Commit

Permalink
[#6] implemented remaining ps flags (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
MitchellBerend authored Oct 7, 2022
1 parent 5775384 commit 461708c
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 48 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

[#5](https://github.com/MitchellBerend/docker-manager/issues/5)
Implementremaining logs flags

[#6](https://github.com/MitchellBerend/docker-manager/issues/6)
Implement remaining ps flags
30 changes: 29 additions & 1 deletion src/cli/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,37 @@ pub struct App {
pub enum Command {
/// Lists all containers on remote nodes
Ps {
/// include inactive containers
/// Show all containers (default shows just running)
#[arg(short, long)]
all: bool,

/// Filter output based on conditions provided
#[arg(short, long, value_name = "filter")]
filter: Option<String>,

/// Pretty-print containers using a Go template
#[arg(long, value_name = "string")]
format: Option<String>,

/// Show n last created containers (includes all states) (default -1)
#[arg(short = 'n', long)]
last: bool,

/// Show the latest created container (includes all states)
#[arg(short, long)]
latests: bool,

/// Don't truncate output
#[arg(long)]
no_trunc: bool,

/// Only display container IDs
#[arg(short, long)]
quiet: bool,

/// Display total file sizes
#[arg(short, long)]
size: bool,
},

/// Stops a given container unless 2 or more containers are found on remote nodes
Expand Down
158 changes: 158 additions & 0 deletions src/cli/flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
pub struct LogsFlags {
pub details: bool,
pub follow: bool,
pub since: String,
pub tail: String,
pub timestamps: bool,
pub until: String,
}

impl LogsFlags {
pub fn new(
details: bool,
follow: bool,
since: Option<String>,
tail: Option<String>,
timestamps: bool,
until: Option<String>,
) -> Self {
let since: String = match since {
Some(since) => since,
None => "".into(),
};
let tail: String = match tail {
Some(tail) => tail,
None => "".into(),
};
let until: String = match until {
Some(until) => until,
None => "".into(),
};

Self {
details,
follow,
since,
tail,
timestamps,
until,
}
}

pub fn flags(&self) -> Vec<String> {
let mut v: Vec<String> = vec![];
if self.details {
v.push("-d".into())
}

// special case which is handled in the run_logs function
//if self.follow {
// v.push("-f".into())

if !self.since.is_empty() {
v.push("--since".into());
v.push(self.since.clone());
};

if !self.tail.is_empty() {
v.push("--tail".into());
v.push(self.tail.clone());
};

if self.timestamps {
v.push("--timestamps".into())
}

if !self.until.is_empty() {
v.push("--until".into());
v.push(self.until.clone());
};

v
}
}

pub struct PsFlags {
pub all: bool,
pub filter: String,
pub format: String,
pub last: bool,
pub latests: bool,
pub no_trunc: bool,
pub quiet: bool,
pub size: bool,
}

#[allow(clippy::too_many_arguments)]
impl PsFlags {
pub fn new(
all: bool,
filter: Option<String>,
format: Option<String>,
last: bool,
latests: bool,
no_trunc: bool,
quiet: bool,
size: bool,
) -> Self {
let filter: String = match filter {
Some(filter) => filter,
None => "".into(),
};
let format: String = match format {
Some(format) => format,
None => "".into(),
};

Self {
all,
filter,
format,
last,
latests,
no_trunc,
quiet,
size,
}
}

pub fn flags(&self) -> Vec<String> {
let mut v: Vec<String> = vec![];
if self.all {
v.push("-a".into())
}

if !self.filter.is_empty() {
v.push("--filter".into());
v.push(self.filter.clone());
};

if !self.format.is_empty() {
v.push("--format".into());
v.push(self.format.clone());
};

if self.last {
v.push("--last".into())
}

if self.last {
v.push("--last".into())
}

if self.latests {
v.push("--latests".into())
}
if self.no_trunc {
v.push("--no_trunc".into())
}
if self.quiet {
v.push("--quiet".into())
}
if self.size {
v.push("--size".into())
}

v
}
}
1 change: 1 addition & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod app;
pub mod flags;

pub use app::{App, Command};
24 changes: 14 additions & 10 deletions src/client/connector.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::Path;

use crate::cli::flags::{LogsFlags, PsFlags};
use crate::cli::Command;
use crate::utility::command;

Expand Down Expand Up @@ -52,8 +53,18 @@ impl Node {
};

match command {
Command::Ps { all } => {
match command::run_ps(self.address.clone(), session, all).await {
Command::Ps {
all,
filter,
format,
last,
latests,
no_trunc,
quiet,
size,
} => {
let flags = PsFlags::new(all, filter, format, last, latests, no_trunc, quiet, size);
match command::run_ps(self.address.clone(), session, flags).await {
Ok(result) => Ok(result),
Err(e) => Err(NodeError::SessionError(self.address.clone(), e)),
}
Expand All @@ -73,14 +84,7 @@ impl Node {
timestamps,
until,
} => {
let flags = command::LogsFlags {
details,
follow,
since,
tail,
timestamps,
until,
};
let flags = LogsFlags::new(details, follow, since, tail, timestamps, until);

match command::run_logs(self.address.clone(), session, container_id, flags).await {
//, follow).await {
Expand Down
43 changes: 10 additions & 33 deletions src/utility/command.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::cli::flags::{LogsFlags, PsFlags};

pub async fn run_ps(
hostname: String,
session: openssh::Session,
all: bool,
flags: PsFlags,
) -> Result<String, openssh::Error> {
let mut command = vec!["docker", "ps"];
if all {
command.push("-a");
};
let mut command: Vec<String> = vec!["docker".into(), "ps".into()];

for flag in flags.flags() {
command.push(flag)
}

let output = match session.command("sudo").args(command).output().await {
Ok(output) => output,
Expand Down Expand Up @@ -42,15 +45,6 @@ pub async fn run_stop(
Ok(rv)
}

pub struct LogsFlags {
pub details: bool,
pub follow: bool,
pub since: Option<String>,
pub tail: Option<String>,
pub timestamps: bool,
pub until: Option<String>,
}

pub async fn run_logs(
hostname: String,
session: openssh::Session,
Expand All @@ -59,25 +53,8 @@ pub async fn run_logs(
) -> Result<String, openssh::Error> {
let mut command: Vec<String> = vec!["docker".into(), "logs".into()];

if flags.details {
command.push("--details".into());
}

if flags.timestamps {
command.push("--timestamps".into());
}

if let Some(s) = flags.since {
command.push("--since".into());
command.push(s);
}
if let Some(s) = flags.tail {
command.push("--tail".into());
command.push(s);
}
if let Some(s) = flags.until {
command.push("--until".into());
command.push(s);
for item in flags.flags() {
command.push(item)
}

if flags.follow {
Expand Down
14 changes: 13 additions & 1 deletion src/utility/other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@ use futures::{stream, StreamExt};
pub async fn find_container(client: Client, container_id: &str) -> Vec<(String, String)> {
let bodies = stream::iter(client.nodes_info())
.map(|(hostname, node)| async move {
match node.run_command(Command::Ps { all: false }).await {
match node
.run_command(Command::Ps {
all: false,
filter: None,
format: None,
last: false,
latests: false,
no_trunc: false,
quiet: false,
size: false,
})
.await
{
Ok(result) => (hostname.clone(), Ok(result)),
Err(e) => (hostname.clone(), Err(e)),
}
Expand Down
31 changes: 28 additions & 3 deletions src/utility/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,35 @@ pub async fn run_command(command: Command) -> Vec<Result<String, CommandError>>
let client = Client::from_config(config_path);

match command {
Command::Ps { all } => {
Command::Ps {
all,
filter,
format,
last,
latests,
no_trunc,
quiet,
size,
} => {
let bodies = stream::iter(client.nodes_info())
.map(|(_, node)| async move {
match node.run_command(Command::Ps { all }).await {
.map(|(_, node)| async {
let _filter: Option<String> =
filter.as_ref().map(|filter| String::from(&filter.clone()));
let _format: Option<String> =
format.as_ref().map(|format| String::from(&format.clone()));
match node
.run_command(Command::Ps {
all,
filter: _filter,
format: _format,
last,
latests,
no_trunc,
quiet,
size,
})
.await
{
Ok(result) => Ok(result),
Err(e) => Err(CommandError::NodeError(e)),
}
Expand Down

0 comments on commit 461708c

Please sign in to comment.