From 8e89aeba752bf56afa655ad284a2821278248740 Mon Sep 17 00:00:00 2001 From: aleidk Date: Wed, 25 Jun 2025 16:54:31 -0400 Subject: [PATCH] feat: stop and start containers --- .idea/epoch.iml | 1 + Cargo.lock | 38 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/manager.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/.idea/epoch.iml b/.idea/epoch.iml index cf84ae4..7c12fe5 100644 --- a/.idea/epoch.iml +++ b/.idea/epoch.iml @@ -2,6 +2,7 @@ + diff --git a/Cargo.lock b/Cargo.lock index 3652901..2a50a5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,6 +182,7 @@ name = "epoch" version = "0.1.0" dependencies = [ "bollard", + "futures", "thiserror", "tokio", ] @@ -207,6 +208,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -214,6 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -222,6 +239,23 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + [[package]] name = "futures-macro" version = "0.3.31" @@ -251,9 +285,13 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", diff --git a/Cargo.toml b/Cargo.toml index adce182..3bc80a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,5 +5,6 @@ edition = "2024" [dependencies] bollard = "0.19.1" +futures = "0.3.31" thiserror = "2.0.12" tokio = { version = "1.45.1", features = ["macros", "rt", "rt-multi-thread"] } diff --git a/src/manager.rs b/src/manager.rs index d6ced6c..086dab3 100644 --- a/src/manager.rs +++ b/src/manager.rs @@ -1,3 +1,5 @@ +use crate::Error; +use bollard::Docker; use bollard::models::ContainerSummary; use std::collections::HashMap; @@ -53,7 +55,51 @@ impl From<&Vec> for Services { pub async fn manage(containers: &Vec) -> crate::Result<()> { let services = Services::from(containers); - println!("{:#?}", services); + // TODO: reuse main instance + let docker = Docker::connect_with_local_defaults()?; + + // TODO: iterate over groups in parallel + for (group, containers) in services.0.iter() { + // stop containers of service group + let stop_tasks = containers.into_iter().map(async |container| { + let id = container + .id + .as_ref() + .ok_or(Error::Static("Error getting containers id"))?; + + eprintln!("Stoping container: {:#?}", id); + + let stop_opts = bollard::query_parameters::StopContainerOptionsBuilder::new().build(); + + docker.stop_container(id, Some(stop_opts)).await?; + + Ok::<(), crate::Error>(()) + }); + + futures::future::try_join_all(stop_tasks).await?; + + // create container with the same mounts as each container in the group + + // run the new container + + // restart the containers + let start_tasks = containers.into_iter().map(async |container| { + let id = container + .id + .as_ref() + .ok_or(Error::Static("Error getting containers id"))?; + + eprintln!("Starting container: {:#?}", id); + + let start_opts = bollard::query_parameters::StartContainerOptionsBuilder::new().build(); + + docker.start_container(id, Some(start_opts)).await?; + + Ok::<(), crate::Error>(()) + }); + + futures::future::try_join_all(start_tasks).await?; + } Ok(()) }