1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-06-03 17:14:08 +02:00

presets wip

This commit is contained in:
Robin Appelman 2023-07-16 16:39:29 +02:00
commit fdcb8de4f2
17 changed files with 192 additions and 120 deletions

View file

@ -20,6 +20,7 @@ with lib; let
read_only = volume.readOnly;
})
cfg.volumes;
preset = cfg.presets;
}
// (
if (cfg.blackfire == null)
@ -121,6 +122,23 @@ in {
});
};
presets = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
name = mkOption {
type = types.str;
description = "Name of the preset";
};
commands = mkOption {
type = types.listOf types.str;
description = "Commands to run post setup when the preset is enabled";
default = [];
};
};
});
};
proxy = mkOption {
default = null;
type = types.nullOr (types.submodule {

View file

@ -1,4 +1,5 @@
use crate::cloud::CloudOptions;
use crate::config::Preset;
use crate::service::{Service, ServiceTrait};
use miette::{IntoDiagnostic, Report, Result};
use parse_display::Display;
@ -78,20 +79,18 @@ pub enum LogService {
}
impl LogService {
pub fn from_type(ty: &str) -> Option<Self> {
pub fn from_type(presets: &[Preset], ty: &str) -> Option<Self> {
if ty == "db" {
return Some(LogService::Database);
}
Some(LogService::Service(
Service::from_type(ty)?.first()?.clone(),
Service::from_type(presets, ty)?.into_iter().next()?,
))
}
pub fn container_name(&self, cloud_id: &str) -> String {
pub fn container_name(&self, cloud_id: &str) -> Option<String> {
match self {
LogService::Database => {
format!("{}-db", cloud_id)
}
LogService::Database => Some(format!("{}-db", cloud_id)),
LogService::Service(service) => service.container_name(cloud_id),
}
}
@ -103,7 +102,7 @@ pub enum ExecService {
}
impl HazeArgs {
pub fn parse<I, S>(mut args: I) -> Result<HazeArgs>
pub fn parse<I, S>(presets: &[Preset], mut args: I) -> Result<HazeArgs>
where
S: AsRef<str> + Into<String> + Display,
I: Iterator<Item = S>,
@ -140,7 +139,7 @@ impl HazeArgs {
}),
HazeCommand::Start => {
let mut args = args.peekable();
let options = CloudOptions::parse(&mut args)?;
let options = CloudOptions::parse(presets, &mut args)?;
if let Some(leftover) = args.next() {
return Err(Report::msg(format!("unrecognized option {}", leftover)));
}
@ -149,13 +148,13 @@ impl HazeArgs {
HazeCommand::Stop => Ok(HazeArgs::Stop { filter }),
HazeCommand::Test => {
let mut args = args.peekable();
let options = CloudOptions::parse(&mut args)?;
let options = CloudOptions::parse(presets, &mut args)?;
let args = args.map(S::into).collect();
Ok(HazeArgs::Test { options, args })
}
HazeCommand::Integration => {
let mut args = args.peekable();
let options = CloudOptions::parse(&mut args)?;
let options = CloudOptions::parse(presets, &mut args)?;
let args = args.map(S::into).collect();
Ok(HazeArgs::Integration { options, args })
}
@ -190,8 +189,8 @@ impl HazeArgs {
let mut args = args.peekable();
let follow = args.next_if(|arg| arg.as_ref() == "-f").is_some();
let service = args
.next_if(|arg| LogService::from_type(arg.as_ref()).is_some())
.and_then(|arg| LogService::from_type(arg.as_ref()));
.next_if(|arg| LogService::from_type(presets, arg.as_ref()).is_some())
.and_then(|arg| LogService::from_type(presets, arg.as_ref()));
Ok(HazeArgs::Logs {
filter,
follow,
@ -213,7 +212,7 @@ impl HazeArgs {
}
HazeCommand::Shell => {
let mut args = args.peekable();
let options = CloudOptions::parse(&mut args)?;
let options = CloudOptions::parse(presets, &mut args)?;
let command = args.map(S::into).collect();
Ok(HazeArgs::Shell { options, command })
}

View file

@ -1,4 +1,4 @@
use crate::config::{HazeConfig, HazeVolumeConfig};
use crate::config::{HazeConfig, HazeVolumeConfig, Preset};
use crate::database::Database;
use crate::exec::{exec, exec_tty, ExitCode};
use crate::mapping::{default_mappings, Mapping};
@ -38,7 +38,7 @@ pub struct CloudOptions {
}
impl CloudOptions {
pub fn parse<I, S>(args: &mut Peekable<I>) -> Result<CloudOptions>
pub fn parse<I, S>(presets: &[Preset], args: &mut Peekable<I>) -> Result<CloudOptions>
where
S: AsRef<str> + Into<String> + Display,
I: Iterator<Item = S>,
@ -56,8 +56,8 @@ impl CloudOptions {
} else if let Ok(php_option) = PhpVersion::from_str(option.as_ref()) {
php = Some(php_option);
let _ = args.next();
} else if let Some(service) = Service::from_type(option.as_ref()) {
services.extend_from_slice(service);
} else if let Some(service) = Service::from_type(presets, option.as_ref()) {
services.extend_from_slice(&service);
let _ = args.next();
} else if option.as_ref().ends_with(".tar.gz") {
app_package.push(option.to_string().into());
@ -282,14 +282,14 @@ impl Cloud {
env.push(format!("BLACKFIRE_CLIENT_TOKEN={}", blackfire.client_token));
}
let service_containers = try_join_all(
let service_containers: Vec<Option<String>> = try_join_all(
options
.services
.iter()
.map(|service| service.spawn(docker, &id, &network, config)),
)
.await?;
containers.extend_from_slice(&service_containers);
containers.extend(service_containers.iter().flatten().cloned());
env.extend(
options
@ -308,10 +308,10 @@ impl Cloud {
{
Ok(container) => container,
Err(e) => {
for container in service_containers {
for container in service_containers.iter().flatten() {
docker
.remove_container(
&container,
container,
Some(RemoveContainerOptions {
force: true,
..RemoveContainerOptions::default()
@ -519,9 +519,8 @@ impl Cloud {
.flat_map(|container| &container.labels)
.flat_map(|labels| labels.get("haze-type"))
.map(String::as_str)
.flat_map(Service::from_type)
.flat_map(|ty| Service::from_type(&[], ty))
.flatten()
.cloned()
.collect();
let mut service_ids: Vec<String> = services
.iter()

View file

@ -16,6 +16,7 @@ pub struct HazeConfig {
pub volume: Vec<HazeVolumeConfig>,
pub blackfire: Option<HazeBlackfireConfig>,
pub proxy: ProxyConfig,
pub preset: Vec<Preset>,
}
#[derive(Debug, Deserialize)]
@ -31,6 +32,8 @@ pub struct RawHazeConfig {
pub blackfire: Option<HazeBlackfireConfig>,
#[serde(default)]
pub proxy: ProxyConfig,
#[serde(default)]
pub preset: Vec<Preset>,
}
impl From<RawHazeConfig> for HazeConfig {
@ -51,6 +54,7 @@ impl From<RawHazeConfig> for HazeConfig {
volume: raw.volume,
blackfire: raw.blackfire,
proxy: raw.proxy,
preset: raw.preset,
}
}
}
@ -200,3 +204,9 @@ impl HazeConfig {
.wrap_err("Failed to parse config file")
}
}
#[derive(Default, Deserialize, Debug)]
pub struct Preset {
pub name: String,
pub commands: Vec<String>,
}

View file

@ -49,7 +49,7 @@ async fn main() -> Result<()> {
.wrap_err("Failed to connect to docker")?;
let config = HazeConfig::load().wrap_err("Failed to load config")?;
let args = HazeArgs::parse(std::env::args())?;
let args = HazeArgs::parse(&config.preset, std::env::args())?;
match args {
HazeArgs::Clean => {
@ -93,7 +93,9 @@ async fn main() -> Result<()> {
} => {
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
let container = if let Some(service) = service {
service.container_name(&cloud.id)
service
.container_name(&cloud.id)
.ok_or_else(|| Report::msg(format!("service has no logs")))?
} else {
cloud.id
};

View file

@ -58,7 +58,7 @@ impl ActiveInstances {
_ => None,
})
.next()?;
let ip = push.get_ip(&self.docker, &cloud.id).await.ok()?;
let ip = push.get_ip(&self.docker, &cloud.id).await.ok()??;
SocketAddr::new(ip, 7867)
} else if let Some(name) = name.strip_suffix("-office") {
let cloud = Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config)
@ -72,7 +72,7 @@ impl ActiveInstances {
_ => None,
})
.next()?;
let ip = office.get_ip(&self.docker, &cloud.id).await.ok()?;
let ip = office.get_ip(&self.docker, &cloud.id).await.ok()??;
SocketAddr::new(ip, 9980)
} else {
SocketAddr::new(

View file

@ -9,7 +9,7 @@ mod push;
mod sftp;
mod smb;
use crate::config::HazeConfig;
use crate::config::{HazeConfig, Preset};
pub use crate::service::clam::ClamIcap;
use crate::service::dav::Dav;
use crate::service::kaspersky::{Kaspersky, KasperskyIcap};
@ -39,15 +39,20 @@ pub trait ServiceTrait {
async fn spawn(
&self,
docker: &Docker,
cloud_id: &str,
network: &str,
_docker: &Docker,
_cloud_id: &str,
_network: &str,
_config: &HazeConfig,
) -> Result<String>;
) -> Result<Option<String>> {
Ok(None)
}
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
let Some(container) = self.container_name(cloud_id) else {
return Ok(true)
};
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&container, None)
.await
.into_diagnostic()?;
Ok(matches!(
@ -59,7 +64,9 @@ pub trait ServiceTrait {
))
}
fn container_name(&self, cloud_id: &str) -> String;
fn container_name(&self, _cloud_id: &str) -> Option<String> {
None
}
async fn start_message(&self, _docker: &Docker, _cloud_id: &str) -> Result<Option<String>> {
Ok(None)
@ -79,8 +86,11 @@ pub trait ServiceTrait {
}
async fn is_running(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
let Some(container) = self.container_name(cloud_id) else {
return Ok(true)
};
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&container, None)
.await
.into_diagnostic()?;
Ok(matches!(
@ -104,9 +114,12 @@ pub trait ServiceTrait {
.wrap_err("Timeout after 30 seconds")?
}
async fn get_ip(&self, docker: &Docker, cloud_id: &str) -> Result<IpAddr> {
async fn get_ip(&self, docker: &Docker, cloud_id: &str) -> Result<Option<IpAddr>> {
let Some(container) = self.container_name(cloud_id) else {
return Ok(None);
};
docker
.start_container::<String>(&self.container_name(cloud_id), None)
.start_container::<String>(&container, None)
.await
.into_diagnostic()?;
self.wait_for_running(docker, cloud_id).await?;
@ -114,7 +127,7 @@ pub trait ServiceTrait {
sleep(Duration::from_millis(100)).await;
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&container, None)
.await
.into_diagnostic()?;
if matches!(
@ -136,6 +149,7 @@ pub trait ServiceTrait {
.unwrap()
.parse()
.into_diagnostic()
.map(Some)
.wrap_err("Invalid ip address")
} else {
Err(Report::msg("service not started"))
@ -158,26 +172,31 @@ pub enum Service {
Kaspersky(Kaspersky),
KasperskyIcap(KasperskyIcap),
ClamIcap(ClamIcap),
Preset(PresetService),
}
impl Service {
pub fn from_type(ty: &str) -> Option<&'static [Self]> {
pub fn from_type(presets: &[Preset], ty: &str) -> Option<Vec<Self>> {
match ty {
"s3" => Some(&[Service::ObjectStore(ObjectStore::S3)]),
"s3m" => Some(&[Service::ObjectStore(ObjectStore::S3m)]),
"s3mb" => Some(&[Service::ObjectStore(ObjectStore::S3mb)]),
"azure" => Some(&[Service::ObjectStore(ObjectStore::Azure)]),
"ldap" => Some(&[Service::Ldap(Ldap), Service::LdapAdmin(LdapAdmin)]),
"onlyoffice" => Some(&[Service::OnlyOffice(OnlyOffice)]),
"office" => Some(&[Service::Office(Office)]),
"push" => Some(&[Service::Push(NotifyPush)]),
"smb" => Some(&[Service::Smb(Smb)]),
"dav" => Some(&[Service::Dav(Dav)]),
"sftp" => Some(&[Service::Sftp(Sftp)]),
"kaspersky" => Some(&[Service::Kaspersky(Kaspersky)]),
"kaspersky-icap" => Some(&[Service::KasperskyIcap(KasperskyIcap)]),
"clamav-icap" => Some(&[Service::ClamIcap(ClamIcap)]),
_ => None,
"s3" => Some(vec![Service::ObjectStore(ObjectStore::S3)]),
"s3m" => Some(vec![Service::ObjectStore(ObjectStore::S3m)]),
"s3mb" => Some(vec![Service::ObjectStore(ObjectStore::S3mb)]),
"azure" => Some(vec![Service::ObjectStore(ObjectStore::Azure)]),
"ldap" => Some(vec![Service::Ldap(Ldap), Service::LdapAdmin(LdapAdmin)]),
"onlyoffice" => Some(vec![Service::OnlyOffice(OnlyOffice)]),
"office" => Some(vec![Service::Office(Office)]),
"push" => Some(vec![Service::Push(NotifyPush)]),
"smb" => Some(vec![Service::Smb(Smb)]),
"dav" => Some(vec![Service::Dav(Dav)]),
"sftp" => Some(vec![Service::Sftp(Sftp)]),
"kaspersky" => Some(vec![Service::Kaspersky(Kaspersky)]),
"kaspersky-icap" => Some(vec![Service::KasperskyIcap(KasperskyIcap)]),
"clamav-icap" => Some(vec![Service::ClamIcap(ClamIcap)]),
_ => presets
.iter()
.find_map(|preset| (preset.name == ty).then(|| PresetService(preset.name.clone())))
.map(Service::Preset)
.map(|service| vec![service]),
}
}
@ -193,3 +212,28 @@ impl Service {
.wrap_err("Timeout after 30 seconds")?
}
}
fn get_preset<'a>(presets: &'a [Preset], name: &str) -> Option<&'a Preset> {
presets.iter().find(|preset| preset.name == name)
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct PresetService(String);
#[async_trait::async_trait]
impl ServiceTrait for PresetService {
fn name(&self) -> &str {
self.0.as_str()
}
async fn post_setup(
&self,
_docker: &Docker,
_cloud_id: &str,
config: &HazeConfig,
) -> Result<Vec<String>> {
let preset =
get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?;
Ok(preset.commands.clone())
}
}

View file

@ -32,11 +32,11 @@ impl ServiceTrait for ClamIcap {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "deepdiver/icap-clamav-service";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -68,11 +68,11 @@ impl ServiceTrait for ClamIcap {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-clamav-icap", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-clamav-icap", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {

View file

@ -23,11 +23,11 @@ impl ServiceTrait for Dav {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "ugeek/webdav:amd64";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -60,11 +60,11 @@ impl ServiceTrait for Dav {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-dav", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-dav", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {

View file

@ -29,14 +29,14 @@ impl ServiceTrait for Kaspersky {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "kaspersky";
if !image_exists(docker, image).await {
bail!("You need to manually create the 'kaspersky' image");
}
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -68,13 +68,13 @@ impl ServiceTrait for Kaspersky {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
let exit = exec(
docker,
self.container_name(cloud_id),
self.container_name(cloud_id).unwrap(),
"root",
vec!["curl", "localhost/licenseinfo"],
Vec::<String>::default(),
@ -84,8 +84,8 @@ impl ServiceTrait for Kaspersky {
Ok(exit.to_result().is_ok())
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-kaspersky", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-kaspersky", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {
@ -130,14 +130,14 @@ impl ServiceTrait for KasperskyIcap {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "kaspersky-icap";
if !image_exists(docker, image).await {
bail!("You need to manually create the 'kaspersky-icap' image");
}
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -169,7 +169,7 @@ impl ServiceTrait for KasperskyIcap {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
// async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
@ -185,8 +185,8 @@ impl ServiceTrait for KasperskyIcap {
// Ok(exit.to_result().is_ok())
// }
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-kaspersky-icap", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-kaspersky-icap", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {

View file

@ -27,11 +27,11 @@ impl ServiceTrait for Ldap {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "icewind1991/haze-ldap";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -65,11 +65,11 @@ impl ServiceTrait for Ldap {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-ldap", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-ldap", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {
@ -96,11 +96,11 @@ impl ServiceTrait for LdapAdmin {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "osixia/phpldapadmin";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -134,16 +134,16 @@ impl ServiceTrait for LdapAdmin {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-ldap-admin", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-ldap-admin", cloud_id))
}
async fn start_message(&self, docker: &Docker, cloud_id: &str) -> Result<Option<String>> {
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&self.container_name(cloud_id).unwrap(), None)
.await
.into_diagnostic()?;
let ip = if matches!(

View file

@ -77,7 +77,7 @@ impl ServiceTrait for ObjectStore {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
pull_image(docker, self.image()).await?;
let options = Some(CreateContainerOptions {
name: format!("{}-object", cloud_id),
@ -114,7 +114,7 @@ impl ServiceTrait for ObjectStore {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
@ -134,7 +134,7 @@ impl ServiceTrait for ObjectStore {
}
_ => {
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&self.container_name(cloud_id).unwrap(), None)
.await
.into_diagnostic()?;
Ok(matches!(
@ -148,8 +148,8 @@ impl ServiceTrait for ObjectStore {
}
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-object", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-object", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {

View file

@ -27,10 +27,10 @@ impl ServiceTrait for Office {
cloud_id: &str,
network: &str,
config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "collabora/code";
pull_image(docker, image).await?;
let container_id = self.container_name(cloud_id);
let container_id = self.container_name(cloud_id).unwrap();
let options = Some(CreateContainerOptions {
name: container_id.clone(),
..CreateContainerOptions::default()
@ -82,11 +82,11 @@ impl ServiceTrait for Office {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-office", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-office", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {
@ -99,7 +99,7 @@ impl ServiceTrait for Office {
cloud_id: &str,
config: &HazeConfig,
) -> Result<Vec<String>> {
let container = &self.container_name(cloud_id);
let container = &self.container_name(cloud_id).unwrap();
let info = docker
.inspect_container(container, None)
.await

View file

@ -27,11 +27,11 @@ impl ServiceTrait for OnlyOffice {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "onlyoffice/documentserver";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -63,11 +63,11 @@ impl ServiceTrait for OnlyOffice {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-onlyoffice", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-onlyoffice", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {
@ -81,7 +81,7 @@ impl ServiceTrait for OnlyOffice {
_config: &HazeConfig,
) -> Result<Vec<String>> {
let info = docker
.inspect_container(&self.container_name(cloud_id), None)
.inspect_container(&self.container_name(cloud_id).unwrap(), None)
.await
.into_diagnostic()?;
let ip = if matches!(

View file

@ -26,11 +26,11 @@ impl ServiceTrait for NotifyPush {
cloud_id: &str,
network: &str,
config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "icewind1991/notify_push";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -68,11 +68,11 @@ impl ServiceTrait for NotifyPush {
.await
.into_diagnostic()?
.id;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-push", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-push", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {
@ -89,10 +89,10 @@ impl ServiceTrait for NotifyPush {
cloud_id: &str,
config: &HazeConfig,
) -> Result<Vec<String>> {
let ip = self.get_ip(docker, cloud_id).await?;
let ip = self.get_ip(docker, cloud_id).await?.unwrap();
let addr = config
.proxy
.addr_with_port(&self.container_name(cloud_id), ip, 7867);
.addr_with_port(&self.container_name(cloud_id).unwrap(), ip, 7867);
Ok(vec![
format!("occ config:system:set trusted_proxies 1 --value {}", ip),
format!("occ notify_push:setup {}", addr),

View file

@ -23,11 +23,11 @@ impl ServiceTrait for Sftp {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "atmoz/sftp:alpine";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -60,11 +60,11 @@ impl ServiceTrait for Sftp {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-sftp", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-sftp", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {

View file

@ -23,11 +23,11 @@ impl ServiceTrait for Smb {
cloud_id: &str,
network: &str,
_config: &HazeConfig,
) -> Result<String> {
) -> Result<Option<String>> {
let image = "servercontainers/samba";
pull_image(docker, image).await?;
let options = Some(CreateContainerOptions {
name: self.container_name(cloud_id),
name: self.container_name(cloud_id).unwrap(),
..CreateContainerOptions::default()
});
let config = Config {
@ -64,11 +64,11 @@ impl ServiceTrait for Smb {
.start_container::<String>(&id, None)
.await
.into_diagnostic()?;
Ok(id)
Ok(Some(id))
}
fn container_name(&self, cloud_id: &str) -> String {
format!("{}-smb", cloud_id)
fn container_name(&self, cloud_id: &str) -> Option<String> {
Some(format!("{}-smb", cloud_id))
}
fn apps(&self) -> &'static [&'static str] {