diff options
author | Matthias Beyer <matthias.beyer@atos.net> | 2021-04-27 09:32:45 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-05-11 10:48:44 +0200 |
commit | 60f0712a95d7cdf46554a87893fb71354f2631c5 (patch) | |
tree | b5176d6b9366593feac28b5f1c81afc55a3fc889 /src/commands/endpoint.rs | |
parent | 7d71ae3bf605a0c5ed38c8dfd9dc6abafbeae315 (diff) |
Add subcommand: endpoint containers stop
Implementation of the "endpoint containers stop" subcommand.
Signed-off-by: Matthias Beyer <matthias.beyer@atos.net>
Diffstat (limited to 'src/commands/endpoint.rs')
-rw-r--r-- | src/commands/endpoint.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/commands/endpoint.rs b/src/commands/endpoint.rs index 79f1d98..2aa8fe5 100644 --- a/src/commands/endpoint.rs +++ b/src/commands/endpoint.rs @@ -168,6 +168,7 @@ async fn containers(endpoint_names: Vec<EndpointName>, Some(("list", matches)) => containers_list(endpoint_names, matches, config).await, Some(("prune", matches)) => containers_prune(endpoint_names, matches, config).await, Some(("top", matches)) => containers_top(endpoint_names, matches, config).await, + Some(("stop", matches)) => containers_stop(endpoint_names, matches, config).await, Some((other, _)) => Err(anyhow!("Unknown subcommand: {}", other)), None => Err(anyhow!("No subcommand")), } @@ -367,6 +368,58 @@ async fn containers_top(endpoint_names: Vec<EndpointName>, } +async fn containers_stop(endpoint_names: Vec<EndpointName>, + matches: &ArgMatches, + config: &Configuration, +) -> Result<()> { + let older_than_filter = get_date_filter("older_than", matches)?; + let newer_than_filter = get_date_filter("newer_than", matches)?; + + let stop_timeout = matches.value_of("timeout") + .map(u64::from_str) + .transpose()? + .map(std::time::Duration::from_secs); + + let stats = connect_to_endpoints(config, &endpoint_names) + .await? + .into_iter() + .map(move |ep| async move { + let stats = ep.container_stats() + .await? + .into_iter() + .filter(|stat| stat.state == "exited") + .filter(|stat| older_than_filter.as_ref().map(|time| time > &stat.created).unwrap_or(true)) + .filter(|stat| newer_than_filter.as_ref().map(|time| time < &stat.created).unwrap_or(true)) + .map(|stat| (ep.clone(), stat)) + .collect::<Vec<(_, _)>>(); + Ok(stats) + }) + .collect::<futures::stream::FuturesUnordered<_>>() + .collect::<Result<Vec<_>>>() + .await?; + + let prompt = format!("Really stop {} Containers?", stats.iter().flatten().count()); + if !dialoguer::Confirm::new().with_prompt(prompt).interact()? { + return Ok(()) + } + + stats.into_iter() + .map(Vec::into_iter) + .flatten() + .map(|(ep, stat)| async move { + ep.get_container_by_id(&stat.id) + .await? + .ok_or_else(|| anyhow!("Failed to find existing container {}", stat.id))? + .stop(stop_timeout) + .await + .map_err(Error::from) + }) + .collect::<futures::stream::FuturesUnordered<_>>() + .collect::<Result<()>>() + .await +} + + fn get_date_filter(name: &str, matches: &ArgMatches) -> Result<Option<chrono::DateTime::<chrono::Local>>> { matches.value_of(name) .map(humantime::parse_rfc3339_weak) |