mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
feat: Add in the ability to get configs
config hooks
This commit is contained in:
@@ -1,22 +1,81 @@
|
||||
use color_eyre::{eyre::eyre, Report};
|
||||
use color_eyre::{
|
||||
eyre::{bail, eyre},
|
||||
Report,
|
||||
};
|
||||
use helpers::{AddressSchemaLocal, AddressSchemaOnion, Callback, OsApi};
|
||||
use itertools::Itertools;
|
||||
use jsonpath_lib::Compiled;
|
||||
use models::{InterfaceId, PackageId};
|
||||
use serde_json::Value;
|
||||
use sqlx::Acquire;
|
||||
|
||||
use crate::{manager::Manager, net::keys::Key};
|
||||
use crate::{
|
||||
config::hook::ConfigHook,
|
||||
manager::{start_stop::StartStop, Manager},
|
||||
net::keys::Key,
|
||||
};
|
||||
|
||||
use super::try_get_running_ip;
|
||||
|
||||
const NULL_VALUE: &Value = &Value::Null;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl OsApi for Manager {
|
||||
async fn get_service_config(
|
||||
&self,
|
||||
id: PackageId,
|
||||
path: &str,
|
||||
callback: Callback,
|
||||
) -> Result<serde_json::Value, Report> {
|
||||
todo!("BLUJ")
|
||||
callback: Option<Callback>,
|
||||
) -> Result<Vec<serde_json::Value>, Report> {
|
||||
let found = match self
|
||||
.seed
|
||||
.manifest
|
||||
.dependencies
|
||||
.0
|
||||
.iter()
|
||||
.find(|x| x.0 == &id)
|
||||
{
|
||||
None => bail!("Cannot get a service that is not part of the dependencies"),
|
||||
Some(a) => a,
|
||||
};
|
||||
|
||||
let config = match crate::config::get(self.seed.ctx.clone(), id.clone(), None)
|
||||
.await
|
||||
.map(|x| x.config)
|
||||
{
|
||||
Ok(Some(a)) => a,
|
||||
Ok(None) => bail!("No current config for the service"),
|
||||
Err(err) => bail!("Could not fetch the config. {err}"),
|
||||
};
|
||||
|
||||
let path = Compiled::compile(path).map_err(|e| eyre!("{e}"))?;
|
||||
|
||||
let filtered_values = path
|
||||
.select(&Value::Object(config))?
|
||||
.into_iter()
|
||||
.cloned()
|
||||
.collect_vec();
|
||||
|
||||
if let Some(callback) = callback {
|
||||
self.seed
|
||||
.ctx
|
||||
.add_config_hook(
|
||||
id,
|
||||
ConfigHook {
|
||||
path,
|
||||
prev: filtered_values.clone(),
|
||||
callback,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Ok(filtered_values)
|
||||
}
|
||||
// Get tor key - base 32
|
||||
|
||||
// Certificate + Certificate key for interface
|
||||
|
||||
async fn bind_local(
|
||||
&self,
|
||||
internal_port: u16,
|
||||
@@ -77,24 +136,6 @@ impl OsApi for Manager {
|
||||
tx.commit().await?;
|
||||
Ok(helpers::Address(key))
|
||||
}
|
||||
async fn unbind_onion(&self, id: InterfaceId, external: u16) -> Result<(), Report> {
|
||||
let ip = try_get_running_ip(&self.seed)
|
||||
.await?
|
||||
.ok_or_else(|| eyre!("No ip available"))?;
|
||||
let mut svc = self
|
||||
.seed
|
||||
.ctx
|
||||
.net_controller
|
||||
.create_service(self.seed.manifest.id.clone(), ip)
|
||||
.await
|
||||
.map_err(|e| eyre!("Could not get to net controller: {e:?}"))?;
|
||||
let mut secrets = self.seed.ctx.secret_store.acquire().await?;
|
||||
|
||||
svc.remove_tor(id, external)
|
||||
.await
|
||||
.map_err(|e| eyre!("Could not add to tor: {e:?}"))?;
|
||||
Ok(())
|
||||
}
|
||||
async fn unbind_local(&self, id: InterfaceId, external: u16) -> Result<(), Report> {
|
||||
let ip = try_get_running_ip(&self.seed)
|
||||
.await?
|
||||
@@ -113,4 +154,49 @@ impl OsApi for Manager {
|
||||
.map_err(|e| eyre!("Could not add to local: {e:?}"))?;
|
||||
Ok(())
|
||||
}
|
||||
async fn unbind_onion(&self, id: InterfaceId, external: u16) -> Result<(), Report> {
|
||||
let ip = try_get_running_ip(&self.seed)
|
||||
.await?
|
||||
.ok_or_else(|| eyre!("No ip available"))?;
|
||||
let mut svc = self
|
||||
.seed
|
||||
.ctx
|
||||
.net_controller
|
||||
.create_service(self.seed.manifest.id.clone(), ip)
|
||||
.await
|
||||
.map_err(|e| eyre!("Could not get to net controller: {e:?}"))?;
|
||||
let mut secrets = self.seed.ctx.secret_store.acquire().await?;
|
||||
|
||||
svc.remove_tor(id, external)
|
||||
.await
|
||||
.map_err(|e| eyre!("Could not add to tor: {e:?}"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_started(&self) -> Result<(), Report> {
|
||||
self.manage_container
|
||||
.current_state
|
||||
.send(StartStop::Start)
|
||||
.unwrap_or_default();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn restart(&self) -> Result<(), Report> {
|
||||
self.perform_restart().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn start(&self) -> Result<(), Report> {
|
||||
self.manage_container
|
||||
.wait_for_desired(StartStop::Start)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn stop(&self) -> Result<(), Report> {
|
||||
self.manage_container
|
||||
.wait_for_desired(StartStop::Stop)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,15 @@ impl ManageContainer {
|
||||
}
|
||||
|
||||
pub fn to_desired(&self, new_state: StartStop) {
|
||||
self.desired_state.send(new_state);
|
||||
self.desired_state.send(new_state).unwrap_or_default();
|
||||
}
|
||||
|
||||
pub async fn wait_for_desired(&self, new_state: StartStop) {
|
||||
let mut current_state = self.current_state();
|
||||
self.to_desired(new_state);
|
||||
while *current_state.borrow() != new_state {
|
||||
current_state.changed().await.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_state(&self) -> watch::Receiver<StartStop> {
|
||||
|
||||
@@ -420,6 +420,9 @@ fn configure(
|
||||
.set(ctx, id, &version, &dependencies, &volumes, &config)
|
||||
.await?;
|
||||
|
||||
ctx.call_config_hooks(id.clone(), &serde_json::Value::Object(config.clone()))
|
||||
.await;
|
||||
|
||||
// track dependencies with no pointers
|
||||
for (package_id, health_checks) in res.depends_on.into_iter() {
|
||||
if let Some(current_dependency) = current_dependencies.0.get_mut(&package_id) {
|
||||
|
||||
Reference in New Issue
Block a user