diff --git a/common/src/query.rs b/common/src/query.rs index e96897f..f107cea 100644 --- a/common/src/query.rs +++ b/common/src/query.rs @@ -48,9 +48,9 @@ impl TryFrom for QueryResult { name: item.name, description: item.description, status: VMStatus::from_str(item.vm_status.as_str()) - .context(format!("While parsing vm_status {}", &item.vm_status))?, + .with_context(|| format!("While parsing vm_status {}", item.vm_status))?, trust_level: TrustLevel::from_str(item.trust_level.as_str()) - .context(format!("While parsing trust_level {}", &item.trust_level))?, + .with_context(|| format!("While parsing trust_level {}", item.trust_level))?, }) } } diff --git a/src/admin/registry.rs b/src/admin/registry.rs index 6cacab9..6b1cba7 100644 --- a/src/admin/registry.rs +++ b/src/admin/registry.rs @@ -81,6 +81,11 @@ impl Registry { } } + pub fn find_map Option>(&self, filter: F) -> Vec { + let state = self.map.lock().unwrap(); + state.values().filter_map(filter).collect() + } + pub fn by_type_many(&self, ty: UnitType) -> Vec { let state = self.map.lock().unwrap(); state.values().filter(|x| x.r#type == ty).cloned().collect() diff --git a/src/admin/server.rs b/src/admin/server.rs index 0a7383b..5faae1b 100644 --- a/src/admin/server.rs +++ b/src/admin/server.rs @@ -104,22 +104,19 @@ impl AdminServiceImpl { vm: VmType::Host, service: ServiceType::Mgr, })?; - let endpoint = host_mgr - .agent() - .with_context(|| "Resolving host agent".to_string())?; - Ok(EndpointConfig { - transport: endpoint, - tls: self.tls_config.clone(), - }) + self.endpoint(host_mgr).context("Resolving host agent") } - pub fn agent_endpoint(&self, name: &str) -> anyhow::Result { - let endpoint = self.registry.by_name(name)?.agent()?; + pub fn endpoint(&self, reentry: RegistryEntry) -> anyhow::Result { Ok(EndpointConfig { - transport: endpoint, + transport: reentry.agent()?, tls: self.tls_config.clone(), }) } + pub fn agent_endpoint(&self, name: &str) -> anyhow::Result { + let reentry = self.registry.by_name(name)?; + self.endpoint(reentry) + } pub fn app_entries(&self, name: String) -> anyhow::Result> { if name.contains('@') { @@ -206,7 +203,7 @@ impl AdminServiceImpl { let name = parse_service_name(&entry.name)?; self.start_vm(name) .await - .with_context(|| format!("handing error, by restart VM {}", &entry.name))?; + .with_context(|| format!("handing error, by restart VM {}", entry.name))?; Ok(()) // FIXME: should use `?` from line above, why it didn't work? } (x, y) => bail!( @@ -245,7 +242,7 @@ impl AdminServiceImpl { if inactive { self.handle_error(entry) .await - .with_context(|| "during handle error")? + .context("during handle error")? } } } @@ -287,7 +284,7 @@ impl AdminServiceImpl { Err(_) => { self.start_vm(&vm_name) .await - .context(format!("Starting vm for {}", &name))?; + .with_context(|| format!("Starting vm for {name}"))?; self.registry .by_name(&systemd_agent) .context("after starting VM")? @@ -505,7 +502,26 @@ impl pb::admin_service_server::AdminService for AdminService { bail!("Invalid locale"); } let _ = tokio::fs::write(LOCALE_CONF, format!("LANG={}", req.locale)).await; + let managers = self.inner.registry.find_map(|re| { + (re.r#type.service == ServiceType::Mgr) + .then_some(()) + .and_then(|_| self.inner.endpoint(re.clone()).ok()) + }); + let locale = req.locale.clone(); + tokio::spawn(async move { + for ec in managers { + if let Ok(conn) = ec.connect().await { + let mut client = + pb::locale::locale_client_client::LocaleClientClient::new(conn); + let localemsg = pb::locale::LocaleMessage { + locale: locale.clone(), + }; + let _ = client.locale_set(localemsg).await; + } + } + }); *self.inner.locale.lock().await = req.locale; + Ok(Empty {}) }) .await @@ -520,6 +536,24 @@ impl pb::admin_service_server::AdminService for AdminService { bail!("Invalid timezone"); } let _ = tokio::fs::write(TIMEZONE_CONF, &req.timezone).await; + let managers = self.inner.registry.find_map(|re| { + (re.r#type.service == ServiceType::Mgr) + .then_some(()) + .and_then(|_| self.inner.endpoint(re.clone()).ok()) + }); + let timezone = req.timezone.clone(); + tokio::spawn(async move { + for ec in managers { + if let Ok(conn) = ec.connect().await { + let mut client = + pb::locale::locale_client_client::LocaleClientClient::new(conn); + let tzmsg = pb::locale::TimezoneMessage { + timezone: timezone.clone(), + }; + let _ = client.timezone_set(tzmsg).await; + } + } + }); *self.inner.timezone.lock().await = req.timezone; Ok(Empty {}) }) diff --git a/src/utils/naming.rs b/src/utils/naming.rs index 6bad690..f884b6e 100644 --- a/src/utils/naming.rs +++ b/src/utils/naming.rs @@ -28,7 +28,7 @@ pub fn parse_application_name(name: &str) -> anyhow::Result<(&str, i32)> { if let Some((left, right)) = name_no_suffix.rsplit_once('@') { let num = right .parse::() - .with_context(|| format!("While parsing number part of {}", name))?; + .with_context(|| format!("While parsing number part of {name}"))?; return Ok((left, num)); } };