summaryrefslogtreecommitdiffstats
path: root/src/commands/endpoint.rs
diff options
context:
space:
mode:
authorMatthias Beyer <matthias.beyer@atos.net>2021-04-27 09:32:45 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-05-11 10:48:44 +0200
commit60f0712a95d7cdf46554a87893fb71354f2631c5 (patch)
treeb5176d6b9366593feac28b5f1c81afc55a3fc889 /src/commands/endpoint.rs
parent7d71ae3bf605a0c5ed38c8dfd9dc6abafbeae315 (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.rs53
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)