mirror of
https://codeberg.org/icewind/haze.git
synced 2026-10-01 08:44:09 +02:00
130 lines
3.9 KiB
Rust
130 lines
3.9 KiB
Rust
use crate::Result;
|
|
use crate::cloud::{Cloud, CloudOptions};
|
|
use crate::config::{HazeConfig, ProxyConfig};
|
|
use crate::service::lookup_server::GSS_JWT_KEY;
|
|
use crate::service::{LookupServer, ServiceTrait};
|
|
use bollard::Docker;
|
|
use bollard::query_parameters::ListContainersOptions;
|
|
use maplit::hashmap;
|
|
use miette::{IntoDiagnostic, Report};
|
|
use serde_json::Value;
|
|
use std::collections::HashMap;
|
|
|
|
/// Cloud id of the most recently started lookup server.
|
|
async fn master_cloud_id(docker: &Docker) -> Result<String> {
|
|
let mut lookup_servers: Vec<_> = docker
|
|
.list_containers(Some(ListContainersOptions {
|
|
all: true,
|
|
..Default::default()
|
|
}))
|
|
.await
|
|
.into_diagnostic()?
|
|
.iter()
|
|
.filter_map(|container| {
|
|
let labels = container.labels.as_ref()?;
|
|
if labels.get("haze-type").map(String::as_str) != Some(LookupServer.name()) {
|
|
return None;
|
|
}
|
|
let cloud_id = labels.get("haze-cloud-id")?.clone();
|
|
Some((container.created.unwrap_or_default(), cloud_id))
|
|
})
|
|
.collect();
|
|
|
|
lookup_servers.sort_by(|a, b| a.0.cmp(&b.0).reverse());
|
|
|
|
lookup_servers.into_iter().map(|(_created, id)| id).next().ok_or_else(|| {
|
|
Report::msg("No haze instance with a lookup server is running, start one with `haze start lookup`")
|
|
})
|
|
}
|
|
|
|
/// Latest cloud started with a lookup server.
|
|
async fn master_instance(docker: &Docker, config: &HazeConfig) -> Result<Cloud> {
|
|
let id = master_cloud_id(docker).await?;
|
|
Cloud::list(docker, Some(id.clone()), config)
|
|
.await?
|
|
.into_iter()
|
|
.find(|cloud| cloud.id == id)
|
|
.ok_or_else(|| Report::msg(format!("Failed to get the address of master instance {id}")))
|
|
}
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
pub struct GlobalScaleSlave;
|
|
|
|
#[async_trait::async_trait]
|
|
impl ServiceTrait for GlobalScaleSlave {
|
|
fn name(&self) -> &str {
|
|
"slave"
|
|
}
|
|
|
|
async fn spawn(
|
|
&self,
|
|
docker: &Docker,
|
|
_cloud_id: &str,
|
|
_network: &str,
|
|
config: &HazeConfig,
|
|
_options: &CloudOptions,
|
|
) -> Result<Vec<String>> {
|
|
master_instance(docker, config).await?;
|
|
|
|
Ok(Vec::new())
|
|
}
|
|
|
|
fn apps(&self) -> &'static [&'static str] {
|
|
&["globalsiteselector"]
|
|
}
|
|
|
|
fn config(
|
|
&self,
|
|
_docker: &Docker,
|
|
_cloud_id: &str,
|
|
_config: &HazeConfig,
|
|
) -> Result<HashMap<String, Value>> {
|
|
Ok(hashmap! {
|
|
"gs.enabled".into() => Value::Bool(true),
|
|
"gss.mode".into() => Value::String("slave".into()),
|
|
"gss.jwt.key".into() => Value::String(GSS_JWT_KEY.into()),
|
|
})
|
|
}
|
|
|
|
async fn post_setup(
|
|
&self,
|
|
docker: &Docker,
|
|
_cloud_id: &str,
|
|
config: &HazeConfig,
|
|
) -> Result<Vec<Vec<String>>> {
|
|
let master = master_instance(docker, config).await?;
|
|
let lookup_server = LookupServer
|
|
.container_name(&master.id)
|
|
.expect("lookup server has a container name");
|
|
|
|
Ok(vec![
|
|
vec![
|
|
"occ".into(),
|
|
"config:system:set".into(),
|
|
"--silent".into(),
|
|
"lookup_server".into(),
|
|
"--value".into(),
|
|
format!("http://{lookup_server}"),
|
|
],
|
|
vec![
|
|
"occ".into(),
|
|
"config:system:set".into(),
|
|
"--silent".into(),
|
|
"gss.master.url".into(),
|
|
"--value".into(),
|
|
master.address.clone(),
|
|
],
|
|
vec!["occ".into(), "globalsiteselector:users:update".into()],
|
|
])
|
|
}
|
|
|
|
async fn start_message(
|
|
&self,
|
|
docker: &Docker,
|
|
_cloud_id: &str,
|
|
_proxy: &ProxyConfig,
|
|
) -> Result<Option<String>> {
|
|
let master = master_cloud_id(docker).await?;
|
|
Ok(Some(format!("Nextcloud was setup as slave of {master}.")))
|
|
}
|
|
}
|