use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; use crate::service::ServiceTrait; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; use bollard::Docker; use local_ip_address::list_afinet_netifas; use maplit::hashmap; use miette::{IntoDiagnostic, Result}; #[derive(Debug, Clone, Eq, PartialEq)] pub struct NotifyPush; #[async_trait::async_trait] impl ServiceTrait for NotifyPush { fn name(&self) -> &str { "push" } fn env(&self) -> &[&str] { &[] } async fn spawn( &self, docker: &Docker, cloud_id: &str, network: &str, config: &HazeConfig, _options: &CloudOptions, ) -> Result> { let image = "icewind1991/notify_push"; pull_image(docker, image).await?; let options = Some(CreateContainerOptions { name: self.container_name(cloud_id), ..CreateContainerOptions::default() }); let config = ContainerCreateBody { image: Some(image.into()), host_config: Some(HostConfig { network_mode: Some(network.to_string()), binds: Some(vec![ format!("{}/config:/config:ro", config.work_dir.join(cloud_id)), format!("{}/data:/var/www/html/data", config.work_dir.join(cloud_id)), ]), ..Default::default() }), env: Some(vec![ "NEXTCLOUD_URL=http://cloud/".into(), "LOG=debug".into(), "REDIS_URL=redis://cloud/".into(), ]), labels: Some(hashmap! { "haze-type".into() => self.name().into(), "haze-cloud-id".into() => cloud_id.into(), }), networking_config: Some(NetworkingConfig { endpoints_config: Some(hashmap! { network.into() => EndpointSettings { aliases: Some(vec![self.name().to_string()]), ..Default::default() } }), }), cmd: Some(vec!["/notify_push".into(), "/config/config.php".into()]), ..Default::default() }; let id = docker .create_container(options, config) .await .into_diagnostic()? .id; Ok(vec![id]) } fn container_name(&self, cloud_id: &str) -> Option { Some(format!("{}-push", cloud_id)) } fn apps(&self) -> &'static [&'static str] { &["notify_push"] } async fn post_setup( &self, docker: &Docker, cloud_id: &str, config: &HazeConfig, ) -> Result> { let mut ips: Vec<_> = self.get_ips(docker, cloud_id).await?.collect(); if let Ok(local_interfaces) = list_afinet_netifas() { ips.extend(local_interfaces.into_iter().map(|(_, ip)| ip)); } let mut commands: Vec<_> = ips .iter() .enumerate() .map(|(i, ip)| { format!( "occ config:system:set trusted_proxies {} --value {ip}", i + 1 ) }) .collect(); let addr = config .proxy .addr_with_port(&self.container_name(cloud_id).unwrap(), ips[0], 7867); commands.push(format!("occ notify_push:setup {}", addr)); Ok(commands) } fn proxy_port(&self) -> u16 { 7867 } }