use bollard::{Docker, query_parameters::ListServicesOptions}; use std::sync::Arc; use tokio::sync::Mutex; pub struct BollardAdapter { client: Arc>>, } impl BollardAdapter { pub fn new() -> Self { Self { client: Arc::new(Mutex::new(None)), } } } impl crate::docker::DockerAdapter for BollardAdapter { async fn connect_docker(&self, docker_host: Option) -> anyhow::Result<()> { let docker = match docker_host { Some(host) => Docker::connect_with_http(&host, 60, bollard::API_DEFAULT_VERSION)?, None => Docker::connect_with_socket_defaults()?, }; docker.ping().await?; let mut client = self.client.lock().await; *client = Some(docker); Ok(()) } async fn version(&self) -> anyhow::Result { let client = self.client.lock().await; if let Some(docker) = &*client { let version_info = docker.version().await?; let version = version_info.version; version.ok_or_else(|| anyhow::anyhow!("Version not available")) } else { Err(anyhow::anyhow!("Docker client is not connected")) } } async fn find_enabled_services(&self) -> anyhow::Result> { let client = self.client.lock().await; let docker = client.as_ref().ok_or_else(|| anyhow::anyhow!("Docker client is not connected"))?; let services = docker.list_services(None::).await?; let mut enabled_services = Vec::new(); for service in services { if let Some(spec) = service.spec { let enabled = spec.labels .map(|hash| hash.contains_key("beekeper.enable")) .is_some(); if enabled && let Some(name) = spec.name { enabled_services.push(name); } } } Ok(enabled_services) } } impl Default for BollardAdapter { fn default() -> Self { Self::new() } }