refactor: introduce local library strucs for containers

This commit is contained in:
Alexander Navarro 2025-06-26 11:52:49 -04:00
parent 8e89aeba75
commit f613efc882
6 changed files with 136 additions and 41 deletions

View file

@ -1,6 +1,6 @@
use crate::Error;
use bollard::Docker;
use bollard::models::ContainerSummary;
use bollard::Docker;
use std::collections::HashMap;
/// Namespace to manage containers together (like compose projects)
@ -9,42 +9,33 @@ type ServiceGroup = String;
const DEFAULT_GROUP: &str = "NONE";
#[derive(Debug)]
struct Services(HashMap<ServiceGroup, Vec<ContainerSummary>>);
struct Services(HashMap<ServiceGroup, Vec<crate::docker::Container>>);
impl From<&Vec<ContainerSummary>> for Services {
fn from(value: &Vec<ContainerSummary>) -> Self {
let mut services = HashMap::new();
for container in value.iter().cloned() {
if container
.mounts
.as_deref()
.is_none_or(|mounts| mounts.is_empty())
{
for summary in value.iter().cloned() {
let container = crate::docker::Container::from(summary);
if container.mounts.is_empty() {
continue;
}
let project = match &container.labels {
None => DEFAULT_GROUP.to_owned(),
Some(labels) => {
// Returns user provided group if exits
if labels.contains_key("epoch.service.group") {
labels
.get("epoch.service.group")
.and_then(|value| Some(value.to_owned()))
.unwrap()
} else {
labels
// Group by compose hash
.get("com.docker.compose.config-hash")
.and_then(|value| Some(value.to_owned()))
// No group found
.unwrap_or(DEFAULT_GROUP.to_owned())
}
}
let group = match &container.labels.service.group {
// Doesn't have a group defined by the user,
// try to use the compose hash or throw it with the default group
None => container
.labels
.service
.compose_hash
.as_ref()
.map(|s| s.to_string())
.unwrap_or_else(|| DEFAULT_GROUP.to_owned()),
Some(group) => group.to_owned(),
};
let list: &mut Vec<ContainerSummary> = services.entry(project).or_default();
let list: &mut Vec<crate::docker::Container> = services.entry(group).or_default();
list.push(container);
}
@ -62,16 +53,11 @@ pub async fn manage(containers: &Vec<ContainerSummary>) -> crate::Result<()> {
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);
eprintln!("Stoping container: {:#?}", container.id);
let stop_opts = bollard::query_parameters::StopContainerOptionsBuilder::new().build();
docker.stop_container(id, Some(stop_opts)).await?;
docker.stop_container(&container.id, Some(stop_opts)).await?;
Ok::<(), crate::Error>(())
});
@ -84,16 +70,11 @@ pub async fn manage(containers: &Vec<ContainerSummary>) -> crate::Result<()> {
// 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);
eprintln!("Starting container: {:#?}", container.id);
let start_opts = bollard::query_parameters::StartContainerOptionsBuilder::new().build();
docker.start_container(id, Some(start_opts)).await?;
docker.start_container(&container.id, Some(start_opts)).await?;
Ok::<(), crate::Error>(())
});