mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 17:14:08 +02:00
sharding option
This commit is contained in:
parent
e13f53e0e5
commit
ce0d3ff3e4
19 changed files with 248 additions and 121 deletions
73
src/cloud.rs
73
src/cloud.rs
|
|
@ -14,6 +14,7 @@ use flate2::read::GzDecoder;
|
||||||
use futures_util::future::try_join_all;
|
use futures_util::future::try_join_all;
|
||||||
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
||||||
use petname::petname;
|
use petname::petname;
|
||||||
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
@ -27,15 +28,14 @@ use tokio::fs::create_dir_all;
|
||||||
use tokio::fs::remove_dir_all;
|
use tokio::fs::remove_dir_all;
|
||||||
use tokio::task::spawn;
|
use tokio::task::spawn;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use toml::Value;
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Eq, PartialEq)]
|
#[derive(Clone, Default, Debug, Eq, PartialEq)]
|
||||||
pub struct CloudOptions {
|
pub struct CloudOptions {
|
||||||
name: Option<String>,
|
pub name: Option<String>,
|
||||||
db: Database,
|
pub db: Database,
|
||||||
php: PhpVersion,
|
pub php: PhpVersion,
|
||||||
services: Vec<Service>,
|
pub services: Vec<Service>,
|
||||||
app_packages: Vec<Utf8PathBuf>,
|
pub app_packages: Vec<Utf8PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CloudOptions {
|
impl CloudOptions {
|
||||||
|
|
@ -176,11 +176,9 @@ pub struct Cloud {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub network: String,
|
pub network: String,
|
||||||
pub containers: Vec<String>,
|
pub containers: Vec<String>,
|
||||||
pub php: PhpVersion,
|
|
||||||
pub db: Database,
|
|
||||||
pub ip: Option<IpAddr>,
|
pub ip: Option<IpAddr>,
|
||||||
pub workdir: Utf8PathBuf,
|
pub workdir: Utf8PathBuf,
|
||||||
pub services: Vec<Service>,
|
pub options: CloudOptions,
|
||||||
pub pinned: bool,
|
pub pinned: bool,
|
||||||
pub address: String,
|
pub address: String,
|
||||||
pub preset_config: HashMap<String, Value>,
|
pub preset_config: HashMap<String, Value>,
|
||||||
|
|
@ -194,6 +192,7 @@ impl Cloud {
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let id = options
|
let id = options
|
||||||
.name
|
.name
|
||||||
|
.as_deref()
|
||||||
.map(|name| format!("haze-{}", name))
|
.map(|name| format!("haze-{}", name))
|
||||||
.unwrap_or_else(|| format!("haze-{}", petname(2, "-").unwrap()));
|
.unwrap_or_else(|| format!("haze-{}", petname(2, "-").unwrap()));
|
||||||
|
|
||||||
|
|
@ -209,12 +208,12 @@ impl Cloud {
|
||||||
|
|
||||||
let app_volumes = options
|
let app_volumes = options
|
||||||
.app_packages
|
.app_packages
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|app_package| {
|
.map(|app_package| {
|
||||||
let app_name = app_package.file_name().unwrap().trim_end_matches(".tar.gz");
|
let app_name = app_package.file_name().unwrap().trim_end_matches(".tar.gz");
|
||||||
let app_dir = app_package_dir.join(app_name);
|
let app_dir = app_package_dir.join(app_name);
|
||||||
|
|
||||||
let app_package_file = fs::File::open(&app_package)
|
let app_package_file = fs::File::open(app_package)
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
.wrap_err_with(|| format!("Failed to open app bundle {}", app_package))?;
|
.wrap_err_with(|| format!("Failed to open app bundle {}", app_package))?;
|
||||||
if app_package.metadata().into_diagnostic()?.len() > 1024 * 1024 {
|
if app_package.metadata().into_diagnostic()?.len() > 1024 * 1024 {
|
||||||
|
|
@ -296,7 +295,7 @@ impl Cloud {
|
||||||
|
|
||||||
if let Some(db_name) = options
|
if let Some(db_name) = options
|
||||||
.db
|
.db
|
||||||
.spawn(docker, &id, &network)
|
.spawn(docker, &id, &network, "")
|
||||||
.await
|
.await
|
||||||
.wrap_err("Failed to start database")?
|
.wrap_err("Failed to start database")?
|
||||||
{
|
{
|
||||||
|
|
@ -315,7 +314,7 @@ impl Cloud {
|
||||||
options
|
options
|
||||||
.services
|
.services
|
||||||
.iter()
|
.iter()
|
||||||
.map(|service| service.spawn(docker, &id, &network, config)),
|
.map(|service| service.spawn(docker, &id, &network, config, &options)),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
containers.extend(service_containers.iter().flatten().cloned());
|
containers.extend(service_containers.iter().flatten().cloned());
|
||||||
|
|
@ -395,21 +394,20 @@ impl Cloud {
|
||||||
|
|
||||||
containers.push(container);
|
containers.push(container);
|
||||||
|
|
||||||
let services_clone = options.services.clone();
|
let options_clone = options.clone();
|
||||||
let cloud_id = id.clone();
|
let cloud_id = id.clone();
|
||||||
let docker_clone = docker.clone();
|
let docker_clone = docker.clone();
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
if let Err(e) = try_join_all(
|
if let Err(e) =
|
||||||
services_clone
|
try_join_all(options_clone.services.iter().map(|service| {
|
||||||
.iter()
|
service.wait_for_start(&docker_clone, &cloud_id, &options_clone)
|
||||||
.map(|service| service.wait_for_start(&docker_clone, &cloud_id)),
|
}))
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
println!("{:#}", e);
|
println!("{:#}", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for service in services_clone {
|
for service in options_clone.services {
|
||||||
match service.start_message(&docker_clone, &cloud_id).await {
|
match service.start_message(&docker_clone, &cloud_id).await {
|
||||||
Ok(Some(msg)) => {
|
Ok(Some(msg)) => {
|
||||||
println!("{}", msg);
|
println!("{}", msg);
|
||||||
|
|
@ -428,11 +426,9 @@ impl Cloud {
|
||||||
id,
|
id,
|
||||||
network,
|
network,
|
||||||
containers,
|
containers,
|
||||||
php: options.php,
|
|
||||||
db: options.db,
|
|
||||||
ip: Some(ip),
|
ip: Some(ip),
|
||||||
workdir,
|
workdir,
|
||||||
services: options.services,
|
options,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
address,
|
address,
|
||||||
preset_config,
|
preset_config,
|
||||||
|
|
@ -610,12 +606,16 @@ impl Cloud {
|
||||||
Cloud {
|
Cloud {
|
||||||
id,
|
id,
|
||||||
network,
|
network,
|
||||||
db,
|
|
||||||
php,
|
|
||||||
containers: service_ids,
|
containers: service_ids,
|
||||||
ip,
|
ip,
|
||||||
workdir,
|
workdir,
|
||||||
|
options: CloudOptions {
|
||||||
|
name: None,
|
||||||
|
php,
|
||||||
|
db,
|
||||||
services: found_services,
|
services: found_services,
|
||||||
|
app_packages: vec![],
|
||||||
|
},
|
||||||
pinned,
|
pinned,
|
||||||
address,
|
address,
|
||||||
preset_config: HashMap::default(),
|
preset_config: HashMap::default(),
|
||||||
|
|
@ -645,18 +645,19 @@ impl Cloud {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wait_for_start(&self, docker: &Docker) -> Result<()> {
|
pub async fn wait_for_start(&self, docker: &Docker) -> Result<()> {
|
||||||
self.php
|
self.options
|
||||||
|
.php
|
||||||
.wait_for_start(self.ip)
|
.wait_for_start(self.ip)
|
||||||
.await
|
.await
|
||||||
.wrap_err("Failed to wait for php container")?;
|
.wrap_err("Failed to wait for php container")?;
|
||||||
self.db
|
self.options
|
||||||
|
.db
|
||||||
.wait_for_start(docker, &self.id)
|
.wait_for_start(docker, &self.id)
|
||||||
.await
|
.await
|
||||||
.wrap_err("Failed to wait for database container")?;
|
.wrap_err("Failed to wait for database container")?;
|
||||||
try_join_all(
|
try_join_all(
|
||||||
self.services
|
self.services()
|
||||||
.iter()
|
.map(|service| service.wait_for_start(docker, &self.id, &self.options)),
|
||||||
.map(|service| service.wait_for_start(docker, &self.id)),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.wrap_err("Failed to wait for service containers")?;
|
.wrap_err("Failed to wait for service containers")?;
|
||||||
|
|
@ -706,4 +707,16 @@ impl Cloud {
|
||||||
.await
|
.await
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn services(&self) -> impl Iterator<Item = &Service> {
|
||||||
|
self.options.services.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn db(&self) -> &Database {
|
||||||
|
&self.options.db
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn php(&self) -> &PhpVersion {
|
||||||
|
&self.options.php
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,7 @@ impl Database {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
|
postfix: &str,
|
||||||
) -> Result<Option<String>> {
|
) -> Result<Option<String>> {
|
||||||
if matches!(self, Database::Sqlite) {
|
if matches!(self, Database::Sqlite) {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|
@ -191,7 +192,7 @@ impl Database {
|
||||||
.wrap_err("Failed to pull database image")?;
|
.wrap_err("Failed to pull database image")?;
|
||||||
}
|
}
|
||||||
let options = Some(CreateContainerOptions {
|
let options = Some(CreateContainerOptions {
|
||||||
name: format!("{}-db", cloud_id),
|
name: format!("{}-db{}", cloud_id, postfix),
|
||||||
..CreateContainerOptions::default()
|
..CreateContainerOptions::default()
|
||||||
});
|
});
|
||||||
let config = Config {
|
let config = Config {
|
||||||
|
|
@ -208,7 +209,10 @@ impl Database {
|
||||||
networking_config: Some(NetworkingConfig {
|
networking_config: Some(NetworkingConfig {
|
||||||
endpoints_config: hashmap! {
|
endpoints_config: hashmap! {
|
||||||
network => EndpointSettings {
|
network => EndpointSettings {
|
||||||
aliases: Some(vec![self.name().to_string()]),
|
aliases: Some(vec![
|
||||||
|
format!("{}{}", self.name(), postfix),
|
||||||
|
format!("db{}", postfix),
|
||||||
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -320,7 +324,7 @@ impl Database {
|
||||||
};
|
};
|
||||||
|
|
||||||
timeout(Duration::from_secs(time), async {
|
timeout(Duration::from_secs(time), async {
|
||||||
while !self.is_healthy(docker, cloud_id).await? {
|
while !self.is_healthy(docker, cloud_id, "").await? {
|
||||||
sleep(Duration::from_millis(250)).await
|
sleep(Duration::from_millis(250)).await
|
||||||
}
|
}
|
||||||
Result::<(), Report>::Ok(())
|
Result::<(), Report>::Ok(())
|
||||||
|
|
@ -348,14 +352,14 @@ impl Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
|
pub async fn is_healthy(&self, docker: &Docker, cloud_id: &str, postfix: &str) -> Result<bool> {
|
||||||
match self.family() {
|
match self.family() {
|
||||||
DatabaseFamily::Sqlite => Ok(true),
|
DatabaseFamily::Sqlite => Ok(true),
|
||||||
DatabaseFamily::Mysql | DatabaseFamily::MariaDB => {
|
DatabaseFamily::Mysql | DatabaseFamily::MariaDB => {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
exec(
|
exec(
|
||||||
docker,
|
docker,
|
||||||
format!("{}-db", cloud_id),
|
format!("{}-db{}", cloud_id, postfix),
|
||||||
"root",
|
"root",
|
||||||
vec!["mysql", "-u", "haze", "-phaze", "-e", "SELECT 1"],
|
vec!["mysql", "-u", "haze", "-phaze", "-e", "SELECT 1"],
|
||||||
Vec::<String>::default(),
|
Vec::<String>::default(),
|
||||||
|
|
@ -368,7 +372,7 @@ impl Database {
|
||||||
DatabaseFamily::Postgres => {
|
DatabaseFamily::Postgres => {
|
||||||
let is_ready_status = exec(
|
let is_ready_status = exec(
|
||||||
docker,
|
docker,
|
||||||
format!("{}-db", cloud_id),
|
format!("{}-db{}", cloud_id, postfix),
|
||||||
"root",
|
"root",
|
||||||
vec!["pg_isready", "-U", "haze", "-q"],
|
vec!["pg_isready", "-U", "haze", "-q"],
|
||||||
Vec::<String>::default(),
|
Vec::<String>::default(),
|
||||||
|
|
@ -378,7 +382,7 @@ impl Database {
|
||||||
if is_ready_status == 0 {
|
if is_ready_status == 0 {
|
||||||
let connect_status = exec(
|
let connect_status = exec(
|
||||||
docker,
|
docker,
|
||||||
format!("{}-db", cloud_id),
|
format!("{}-db{}", cloud_id, postfix),
|
||||||
"root",
|
"root",
|
||||||
vec!["psql", "-U", "haze", "-qtA", "-c", ""],
|
vec!["psql", "-U", "haze", "-qtA", "-c", ""],
|
||||||
Vec::<String>::default(),
|
Vec::<String>::default(),
|
||||||
|
|
@ -394,7 +398,7 @@ impl Database {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
exec(
|
exec(
|
||||||
docker,
|
docker,
|
||||||
format!("{}-db", cloud_id),
|
format!("{}-db{}", cloud_id, postfix),
|
||||||
"root",
|
"root",
|
||||||
vec!["sh", "-c", r#"echo "show user" | sqlplus -S system/haze"#],
|
vec!["sh", "-c", r#"echo "show user" | sqlplus -S system/haze"#],
|
||||||
Vec::<String>::default(),
|
Vec::<String>::default(),
|
||||||
|
|
|
||||||
18
src/main.rs
18
src/main.rs
|
|
@ -64,15 +64,15 @@ async fn main() -> Result<()> {
|
||||||
HazeArgs::List { filter } => {
|
HazeArgs::List { filter } => {
|
||||||
let list = Cloud::list(&docker, filter, &config).await?;
|
let list = Cloud::list(&docker, filter, &config).await?;
|
||||||
for cloud in list {
|
for cloud in list {
|
||||||
let mut services: Vec<_> = cloud.services.iter().map(Service::name).collect();
|
let mut services: Vec<_> = cloud.services().map(Service::name).collect();
|
||||||
services.push(cloud.db.name());
|
services.push(cloud.db().name());
|
||||||
let services = services.join(", ");
|
let services = services.join(", ");
|
||||||
let pin = if cloud.pinned { "*" } else { "" };
|
let pin = if cloud.pinned { "*" } else { "" };
|
||||||
println!(
|
println!(
|
||||||
"Cloud {}{}, {}, {}, running on {}",
|
"Cloud {}{}, {}, {}, running on {}",
|
||||||
cloud.id,
|
cloud.id,
|
||||||
pin,
|
pin,
|
||||||
cloud.php.name(),
|
cloud.php().name(),
|
||||||
services,
|
services,
|
||||||
cloud.address
|
cloud.address
|
||||||
);
|
);
|
||||||
|
|
@ -124,7 +124,7 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
Some(ExecService::Db) => {
|
Some(ExecService::Db) => {
|
||||||
cloud
|
cloud
|
||||||
.db
|
.db()
|
||||||
.exec_sh(
|
.exec_sh(
|
||||||
&docker,
|
&docker,
|
||||||
&cloud.id,
|
&cloud.id,
|
||||||
|
|
@ -156,7 +156,7 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
HazeArgs::Db { filter, root } => {
|
HazeArgs::Db { filter, root } => {
|
||||||
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
||||||
cloud.db.exec(&docker, &cloud.id, root).await?;
|
cloud.db().exec(&docker, &cloud.id, root).await?;
|
||||||
}
|
}
|
||||||
HazeArgs::Open { filter } => {
|
HazeArgs::Open { filter } => {
|
||||||
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
||||||
|
|
@ -342,7 +342,7 @@ async fn main() -> Result<()> {
|
||||||
let ip = cloud
|
let ip = cloud
|
||||||
.ip
|
.ip
|
||||||
.ok_or_else(|| Report::msg(format!("{} is not running", cloud.id)))?;
|
.ok_or_else(|| Report::msg(format!("{} is not running", cloud.id)))?;
|
||||||
let db_type = match cloud.db.family() {
|
let db_type = match cloud.db().family() {
|
||||||
DatabaseFamily::Sqlite => {
|
DatabaseFamily::Sqlite => {
|
||||||
return Err(Report::msg("sqlite is not supported with `haze env`"))
|
return Err(Report::msg("sqlite is not supported with `haze env`"))
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +353,7 @@ async fn main() -> Result<()> {
|
||||||
DatabaseFamily::Postgres => "postgresql",
|
DatabaseFamily::Postgres => "postgresql",
|
||||||
};
|
};
|
||||||
let db_ip = cloud
|
let db_ip = cloud
|
||||||
.db
|
.db()
|
||||||
.ip(&docker, &cloud.id)
|
.ip(&docker, &cloud.id)
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| Report::msg(format!("{}-db is not running", cloud.id)))?;
|
.ok_or_else(|| Report::msg(format!("{}-db is not running", cloud.id)))?;
|
||||||
|
|
@ -459,7 +459,7 @@ async fn setup(docker: &Docker, options: CloudOptions, config: &HazeConfig) -> R
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for service in &cloud.services {
|
for service in cloud.services() {
|
||||||
for app in service.apps() {
|
for app in service.apps() {
|
||||||
cloud
|
cloud
|
||||||
.exec(
|
.exec(
|
||||||
|
|
@ -471,7 +471,7 @@ async fn setup(docker: &Docker, options: CloudOptions, config: &HazeConfig) -> R
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for service in &cloud.services {
|
for service in cloud.services() {
|
||||||
for cmd in service.post_setup(docker, &cloud.id, config).await? {
|
for cmd in service.post_setup(docker, &cloud.id, config).await? {
|
||||||
cloud
|
cloud
|
||||||
.exec(
|
.exec(
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ impl ActiveInstances {
|
||||||
.await
|
.await
|
||||||
.ok()?;
|
.ok()?;
|
||||||
let service = cloud
|
let service = cloud
|
||||||
.services
|
.services()
|
||||||
.iter()
|
|
||||||
.find(|service| service.name() == service_name)?;
|
.find(|service| service.name() == service_name)?;
|
||||||
let ip = service.get_ip(&self.docker, &cloud.id).await.ok()??;
|
let ip = service.get_ip(&self.docker, &cloud.id).await.ok()??;
|
||||||
SocketAddr::new(ip, service.proxy_port())
|
SocketAddr::new(ip, service.proxy_port())
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@ mod office;
|
||||||
mod onlyoffice;
|
mod onlyoffice;
|
||||||
mod push;
|
mod push;
|
||||||
mod sftp;
|
mod sftp;
|
||||||
|
// mod sharding;
|
||||||
|
mod sharded;
|
||||||
mod smb;
|
mod smb;
|
||||||
|
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::{HazeConfig, Preset};
|
use crate::config::{HazeConfig, Preset};
|
||||||
pub use crate::service::clam::{ClamIcap, ClamIcapTls};
|
pub use crate::service::clam::{ClamIcap, ClamIcapTls};
|
||||||
use crate::service::dav::Dav;
|
use crate::service::dav::Dav;
|
||||||
|
|
@ -25,16 +28,17 @@ pub use crate::service::office::Office;
|
||||||
pub use crate::service::onlyoffice::OnlyOffice;
|
pub use crate::service::onlyoffice::OnlyOffice;
|
||||||
pub use crate::service::push::NotifyPush;
|
pub use crate::service::push::NotifyPush;
|
||||||
use crate::service::sftp::Sftp;
|
use crate::service::sftp::Sftp;
|
||||||
|
use crate::service::sharded::Sharding;
|
||||||
use crate::service::smb::Smb;
|
use crate::service::smb::Smb;
|
||||||
use bollard::models::ContainerState;
|
use bollard::models::ContainerState;
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
use miette::{IntoDiagnostic, Report, Result, WrapErr};
|
||||||
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::{sleep, timeout};
|
use tokio::time::{sleep, timeout};
|
||||||
use toml::Value;
|
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
#[enum_dispatch(Service)]
|
#[enum_dispatch(Service)]
|
||||||
|
|
@ -51,25 +55,18 @@ pub trait ServiceTrait {
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_network: &str,
|
_network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Option<String>> {
|
_options: &CloudOptions,
|
||||||
Ok(None)
|
) -> Result<Vec<String>> {
|
||||||
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
|
async fn is_healthy(
|
||||||
let Some(container) = self.container_name(cloud_id) else {
|
&self,
|
||||||
return Ok(true);
|
_docker: &Docker,
|
||||||
};
|
_cloud_id: &str,
|
||||||
let info = docker
|
_options: &CloudOptions,
|
||||||
.inspect_container(&container, None)
|
) -> Result<bool> {
|
||||||
.await
|
Ok(true)
|
||||||
.into_diagnostic()?;
|
|
||||||
Ok(matches!(
|
|
||||||
info.state,
|
|
||||||
Some(ContainerState {
|
|
||||||
running: Some(true),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn container_name(&self, _cloud_id: &str) -> Option<String> {
|
fn container_name(&self, _cloud_id: &str) -> Option<String> {
|
||||||
|
|
@ -189,6 +186,7 @@ pub enum Service {
|
||||||
Push(NotifyPush),
|
Push(NotifyPush),
|
||||||
Smb(Smb),
|
Smb(Smb),
|
||||||
Dav(Dav),
|
Dav(Dav),
|
||||||
|
Sharding(Sharding),
|
||||||
Sftp(Sftp),
|
Sftp(Sftp),
|
||||||
Kaspersky(Kaspersky),
|
Kaspersky(Kaspersky),
|
||||||
KasperskyIcap(KasperskyIcap),
|
KasperskyIcap(KasperskyIcap),
|
||||||
|
|
@ -212,6 +210,8 @@ impl Service {
|
||||||
"office" => Some(vec![Service::Office(Office)]),
|
"office" => Some(vec![Service::Office(Office)]),
|
||||||
"push" => Some(vec![Service::Push(NotifyPush)]),
|
"push" => Some(vec![Service::Push(NotifyPush)]),
|
||||||
"smb" => Some(vec![Service::Smb(Smb)]),
|
"smb" => Some(vec![Service::Smb(Smb)]),
|
||||||
|
"sharded" => Some(vec![Service::Sharding(Sharding)]),
|
||||||
|
"sharding" => Some(vec![Service::Sharding(Sharding)]),
|
||||||
"dav" => Some(vec![Service::Dav(Dav)]),
|
"dav" => Some(vec![Service::Dav(Dav)]),
|
||||||
"sftp" => Some(vec![Service::Sftp(Sftp)]),
|
"sftp" => Some(vec![Service::Sftp(Sftp)]),
|
||||||
"oc" => Some(vec![Service::Oc(Oc)]),
|
"oc" => Some(vec![Service::Oc(Oc)]),
|
||||||
|
|
@ -231,9 +231,14 @@ impl Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wait_for_start(&self, docker: &Docker, cloud_id: &str) -> Result<()> {
|
pub async fn wait_for_start(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
options: &CloudOptions,
|
||||||
|
) -> Result<()> {
|
||||||
timeout(Duration::from_secs(30), async {
|
timeout(Duration::from_secs(30), async {
|
||||||
while !self.is_healthy(docker, cloud_id).await? {
|
while !self.is_healthy(docker, cloud_id, options).await? {
|
||||||
sleep(Duration::from_millis(100)).await
|
sleep(Duration::from_millis(100)).await
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -265,7 +270,12 @@ impl ServiceTrait for PresetService {
|
||||||
) -> Result<HashMap<String, Value>> {
|
) -> Result<HashMap<String, Value>> {
|
||||||
let preset =
|
let preset =
|
||||||
get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?;
|
get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?;
|
||||||
Ok(preset.config.clone())
|
let config = preset
|
||||||
|
.config
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| Ok((k.clone(), serde_json::to_value(v).into_diagnostic()?)))
|
||||||
|
.collect::<Result<HashMap<_, _>>>()?;
|
||||||
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
|
|
@ -34,6 +35,7 @@ impl ServiceTrait for ClamIcap {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "ghcr.io/icewind1991/icap-clamav-service-tls";
|
let image = "ghcr.io/icewind1991/icap-clamav-service-tls";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -122,6 +124,7 @@ impl ServiceTrait for ClamIcapTls {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "ghcr.io/icewind1991/icap-clamav-service-tls";
|
let image = "ghcr.io/icewind1991/icap-clamav-service-tls";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -23,6 +24,7 @@ impl ServiceTrait for Dav {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "ugeek/webdav:amd64";
|
let image = "ugeek/webdav:amd64";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -71,11 +73,6 @@ impl ServiceTrait for Dav {
|
||||||
&["files_external"]
|
&["files_external"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for dav, as it won't be used until the user logs in
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -23,6 +24,7 @@ impl ServiceTrait for Imaginary {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "nextcloud/aio-imaginary:latest";
|
let image = "nextcloud/aio-imaginary:latest";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -66,11 +68,6 @@ impl ServiceTrait for Imaginary {
|
||||||
Some(format!("{}-imaginary", cloud_id))
|
Some(format!("{}-imaginary", cloud_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for imaginary, as it won't be used until the user logs in
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::{image_exists, pull_image};
|
use crate::image::{image_exists, pull_image};
|
||||||
|
|
@ -29,6 +30,7 @@ impl ServiceTrait for Kaspersky {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "kaspersky";
|
let image = "kaspersky";
|
||||||
if !image_exists(docker, image).await {
|
if !image_exists(docker, image).await {
|
||||||
|
|
@ -71,7 +73,12 @@ impl ServiceTrait for Kaspersky {
|
||||||
Ok(vec![id])
|
Ok(vec![id])
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
|
async fn is_healthy(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
_options: &CloudOptions,
|
||||||
|
) -> Result<bool> {
|
||||||
let exit = exec(
|
let exit = exec(
|
||||||
docker,
|
docker,
|
||||||
self.container_name(cloud_id).unwrap(),
|
self.container_name(cloud_id).unwrap(),
|
||||||
|
|
@ -130,6 +137,7 @@ impl ServiceTrait for KasperskyIcap {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "kaspersky-icap";
|
let image = "kaspersky-icap";
|
||||||
if !image_exists(docker, image).await {
|
if !image_exists(docker, image).await {
|
||||||
|
|
@ -172,19 +180,6 @@ impl ServiceTrait for KasperskyIcap {
|
||||||
Ok(vec![id])
|
Ok(vec![id])
|
||||||
}
|
}
|
||||||
|
|
||||||
// async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
|
|
||||||
// let exit = exec(
|
|
||||||
// docker,
|
|
||||||
// self.container_name(cloud_id),
|
|
||||||
// "root",
|
|
||||||
// vec!["curl", "localhost/licenseinfo"],
|
|
||||||
// vec![],
|
|
||||||
// Option::<Stdout>::None,
|
|
||||||
// )
|
|
||||||
// .await?;
|
|
||||||
// Ok(exit.to_result().is_ok())
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn container_name(&self, cloud_id: &str) -> Option<String> {
|
fn container_name(&self, cloud_id: &str) -> Option<String> {
|
||||||
Some(format!("{}-kaspersky-icap", cloud_id))
|
Some(format!("{}-kaspersky-icap", cloud_id))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -27,6 +28,7 @@ impl ServiceTrait for Ldap {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "icewind1991/haze-ldap";
|
let image = "icewind1991/haze-ldap";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -75,6 +77,15 @@ impl ServiceTrait for Ldap {
|
||||||
fn apps(&self) -> &'static [&'static str] {
|
fn apps(&self) -> &'static [&'static str] {
|
||||||
&["user_ldap"]
|
&["user_ldap"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn is_healthy(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
_options: &CloudOptions,
|
||||||
|
) -> Result<bool> {
|
||||||
|
self.is_running(docker, cloud_id).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
|
@ -96,6 +107,7 @@ impl ServiceTrait for LdapAdmin {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "osixia/phpldapadmin";
|
let image = "osixia/phpldapadmin";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -23,6 +24,7 @@ impl ServiceTrait for Mail {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "rnwood/smtp4dev";
|
let image = "rnwood/smtp4dev";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -66,11 +68,6 @@ impl ServiceTrait for Mail {
|
||||||
Some(format!("{}-mail", cloud_id))
|
Some(format!("{}-mail", cloud_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for mail, as it won't be used until the user logs in
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
|
|
@ -77,6 +78,7 @@ impl ServiceTrait for ObjectStore {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
pull_image(docker, self.image()).await?;
|
pull_image(docker, self.image()).await?;
|
||||||
let options = Some(CreateContainerOptions {
|
let options = Some(CreateContainerOptions {
|
||||||
|
|
@ -117,7 +119,15 @@ impl ServiceTrait for ObjectStore {
|
||||||
Ok(vec![id])
|
Ok(vec![id])
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_healthy(&self, docker: &Docker, cloud_id: &str) -> Result<bool> {
|
async fn is_healthy(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
_options: &CloudOptions,
|
||||||
|
) -> Result<bool> {
|
||||||
|
if !self.is_running(docker, cloud_id).await? {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
match self {
|
match self {
|
||||||
ObjectStore::S3 | ObjectStore::S3mb => {
|
ObjectStore::S3 | ObjectStore::S3mb => {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
|
|
@ -27,6 +28,7 @@ impl ServiceTrait for Oc {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "owncloud/server:10.12.2";
|
let image = "owncloud/server:10.12.2";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -78,11 +80,6 @@ impl ServiceTrait for Oc {
|
||||||
Some(format!("{}-oc", cloud_id))
|
Some(format!("{}-oc", cloud_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for oc
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -27,6 +28,7 @@ impl ServiceTrait for Office {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "collabora/code";
|
let image = "collabora/code";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -27,6 +28,7 @@ impl ServiceTrait for OnlyOffice {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "onlyoffice/documentserver";
|
let image = "onlyoffice/documentserver";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -26,6 +27,7 @@ impl ServiceTrait for NotifyPush {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "icewind1991/notify_push";
|
let image = "icewind1991/notify_push";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -79,10 +81,6 @@ impl ServiceTrait for NotifyPush {
|
||||||
&["notify_push"]
|
&["notify_push"]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -23,6 +24,7 @@ impl ServiceTrait for Sftp {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "atmoz/sftp:alpine";
|
let image = "atmoz/sftp:alpine";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -71,11 +73,6 @@ impl ServiceTrait for Sftp {
|
||||||
&["files_external"]
|
&["files_external"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for dav, as it won't be used until the user logs in
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
|
|
|
||||||
97
src/service/sharded.rs
Normal file
97
src/service/sharded.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
|
use crate::config::HazeConfig;
|
||||||
|
use crate::database::DatabaseFamily;
|
||||||
|
use crate::service::ServiceTrait;
|
||||||
|
use crate::Result;
|
||||||
|
use bollard::Docker;
|
||||||
|
use futures_util::future::try_join_all;
|
||||||
|
use maplit::hashmap;
|
||||||
|
use miette::Report;
|
||||||
|
use serde_json::json;
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::convert::identity;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub struct Sharding;
|
||||||
|
|
||||||
|
const SHARDS: &[&str] = &["-1", "-2"];
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl ServiceTrait for Sharding {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"sharding"
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn spawn(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
network: &str,
|
||||||
|
_config: &HazeConfig,
|
||||||
|
options: &CloudOptions,
|
||||||
|
) -> Result<Vec<String>> {
|
||||||
|
if options.db.family() == DatabaseFamily::Sqlite {
|
||||||
|
return Err(Report::msg("Sharding is not supported with sqlite"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let containers = try_join_all(
|
||||||
|
SHARDS
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|postfix| options.db.spawn(docker, cloud_id, network, postfix)),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(containers.into_iter().flatten().collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn is_healthy(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
options: &CloudOptions,
|
||||||
|
) -> Result<bool> {
|
||||||
|
let running = try_join_all(
|
||||||
|
SHARDS
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|postfix| options.db.is_healthy(docker, cloud_id, postfix)),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(running.iter().copied().all(identity))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config(
|
||||||
|
&self,
|
||||||
|
_docker: &Docker,
|
||||||
|
_cloud_id: &str,
|
||||||
|
_config: &HazeConfig,
|
||||||
|
) -> Result<HashMap<String, Value>> {
|
||||||
|
let shard_config = json!({
|
||||||
|
"filecache": {
|
||||||
|
"table": "filecache",
|
||||||
|
"primary_key": "fileid",
|
||||||
|
"shard_key": "storage",
|
||||||
|
"companion_tables": ["filecache_extended"],
|
||||||
|
"shards": [
|
||||||
|
{
|
||||||
|
"name": "haze",
|
||||||
|
"host": "db-1",
|
||||||
|
"tableprefix": "oc_",
|
||||||
|
"user": "haze",
|
||||||
|
"password": "haze",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "haze",
|
||||||
|
"host": "db-2",
|
||||||
|
"tableprefix": "oc_",
|
||||||
|
"user": "haze",
|
||||||
|
"password": "haze",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(hashmap! {String::from("db.sharding") => shard_config})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -23,6 +24,7 @@ impl ServiceTrait for Smb {
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
network: &str,
|
network: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
let image = "ghcr.io/servercontainers/samba:smbd-only-a3.18.0-s4.18.2-r0";
|
let image = "ghcr.io/servercontainers/samba:smbd-only-a3.18.0-s4.18.2-r0";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
|
|
@ -75,11 +77,6 @@ impl ServiceTrait for Smb {
|
||||||
&["files_external"]
|
&["files_external"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to wait for smb, as it won't be used until the user logs in
|
|
||||||
async fn is_healthy(&self, _docker: &Docker, _cloud_id: &str) -> Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_setup(
|
async fn post_setup(
|
||||||
&self,
|
&self,
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue