Resources lookup impl

This commit is contained in:
Nadja Reitzenstein 2022-03-13 20:33:26 +01:00
parent d5833f30c4
commit 07a7cbe42b
4 changed files with 49 additions and 16 deletions

View File

@ -6,6 +6,7 @@ use api::machinesystem_capnp::machine_system::{
use capnp::capability::Promise; use capnp::capability::Promise;
use capnp_rpc::pry; use capnp_rpc::pry;
use crate::capnp::machine::Machine; use crate::capnp::machine::Machine;
use crate::RESOURCES;
use crate::resources::Resource; use crate::resources::Resource;
use crate::resources::search::ResourcesHandle; use crate::resources::search::ResourcesHandle;
@ -17,8 +18,8 @@ pub struct Machines {
impl Machines { impl Machines {
pub fn new(session: SessionHandle) -> Self { pub fn new(session: SessionHandle) -> Self {
let resources = ResourcesHandle::new(); // FIXME no unwrap bad
Self { session, resources } Self { session, resources: RESOURCES.get().unwrap().clone() }
} }
} }

View File

@ -46,6 +46,7 @@ use std::sync::Arc;
use anyhow::Context; use anyhow::Context;
use futures_rustls::TlsAcceptor; use futures_rustls::TlsAcceptor;
use futures_util::StreamExt; use futures_util::StreamExt;
use once_cell::sync::OnceCell;
use rustls::{Certificate, KeyLogFile, PrivateKey, ServerConfig}; use rustls::{Certificate, KeyLogFile, PrivateKey, ServerConfig};
use rustls::server::NoClientAuth; use rustls::server::NoClientAuth;
use signal_hook::consts::signal::*; use signal_hook::consts::signal::*;
@ -54,6 +55,9 @@ use crate::authentication::AuthenticationHandle;
use crate::capnp::APIServer; use crate::capnp::APIServer;
use crate::config::{Config, TlsListen}; use crate::config::{Config, TlsListen};
use crate::resources::modules::fabaccess::MachineState; use crate::resources::modules::fabaccess::MachineState;
use crate::resources::Resource;
use crate::resources::search::ResourcesHandle;
use crate::resources::state::db::StateDB;
use crate::session::SessionManager; use crate::session::SessionManager;
use crate::tls::TlsConfig; use crate::tls::TlsConfig;
@ -63,6 +67,8 @@ pub struct Diflouroborane {
executor: Executor<'static>, executor: Executor<'static>,
} }
pub static RESOURCES: OnceCell<ResourcesHandle> = OnceCell::new();
impl Diflouroborane { impl Diflouroborane {
pub fn new() -> Self { pub fn new() -> Self {
let executor = Executor::new(); let executor = Executor::new();
@ -88,8 +94,12 @@ impl Diflouroborane {
SIGTERM, SIGTERM,
]).context("Failed to construct signal handler")?; ]).context("Failed to construct signal handler")?;
// - Load Machines from config let statedb = StateDB::create(&config.db_path).context("Failed to open state DB")?;
// - Load states from DB let statedb = Arc::new(statedb);
let resources = ResourcesHandle::new(config.machines.iter().map(|(id, desc)| {
Resource::new(Arc::new(resources::Inner::new(id.to_string(), statedb.clone(), desc.clone())))
}));
RESOURCES.set(resources);
// - Connect modules to machines // - Connect modules to machines
let tlsconfig = TlsConfig::new(config.tlskeylog.as_ref(), !config.is_quiet())?; let tlsconfig = TlsConfig::new(config.tlskeylog.as_ref(), !config.is_quiet())?;

View File

@ -3,6 +3,7 @@ use std::sync::Arc;
use futures_signals::signal::{Mutable, Signal, SignalExt}; use futures_signals::signal::{Mutable, Signal, SignalExt};
use lmdb::RoTransaction; use lmdb::RoTransaction;
use rkyv::Archived; use rkyv::Archived;
use crate::config::MachineDescription;
use crate::db::LMDBorrow; use crate::db::LMDBorrow;
use crate::resources::modules::fabaccess::{MachineState, Status}; use crate::resources::modules::fabaccess::{MachineState, Status};
use crate::resources::state::db::StateDB; use crate::resources::state::db::StateDB;
@ -22,11 +23,12 @@ pub struct PermissionDenied;
pub(crate) struct Inner { pub(crate) struct Inner {
id: String, id: String,
db: StateDB, db: Arc<StateDB>,
signal: Mutable<MachineState>, signal: Mutable<MachineState>,
desc: MachineDescription,
} }
impl Inner { impl Inner {
pub fn new(id: String, db: StateDB) -> Self { pub fn new(id: String, db: Arc<StateDB>, desc: MachineDescription) -> Self {
let state = if let Some(previous) = db.get_output(id.as_bytes()).unwrap() { let state = if let Some(previous) = db.get_output(id.as_bytes()).unwrap() {
let state = MachineState::from(&previous); let state = MachineState::from(&previous);
tracing::info!(%id, ?state, "Found previous state"); tracing::info!(%id, ?state, "Found previous state");
@ -37,7 +39,7 @@ impl Inner {
}; };
let signal = Mutable::new(state); let signal = Mutable::new(state);
Self { id, db, signal } Self { id, db, signal, desc }
} }
pub fn signal(&self) -> impl Signal<Item=MachineState> { pub fn signal(&self) -> impl Signal<Item=MachineState> {

View File

@ -1,13 +1,21 @@
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::resources::Resource; use crate::resources::Resource;
struct Inner { struct Inner {
id: HashMap<String, Resource>,
} }
impl Inner { impl Inner {
pub fn new() -> Self { pub fn new(resources: impl IntoIterator<Item=Resource>) -> Self {
Self { } let mut id = HashMap::new();
for resource in resources {
let old = id.insert(resource.inner.id.clone(), resource);
assert!(old.is_none());
}
Self { id }
} }
} }
@ -17,22 +25,34 @@ pub struct ResourcesHandle {
} }
impl ResourcesHandle { impl ResourcesHandle {
pub fn new() -> Self { pub fn new(resources: impl IntoIterator<Item=Resource>) -> Self {
Self { Self {
inner: Arc::new(Inner::new()), inner: Arc::new(Inner::new(resources)),
} }
} }
pub fn list_all(&self) -> impl IntoIterator<Item=&Resource> { pub fn list_all(&self) -> impl IntoIterator<Item=&Resource> {
unimplemented!(); self.inner.id.values()
&[]
} }
pub fn get_by_id(&self, id: &str) -> Option<&Resource> { pub fn get_by_id(&self, id: &str) -> Option<&Resource> {
unimplemented!() self.inner.id.get(id)
} }
pub fn get_by_urn(&self, urn: &str) -> Option<&Resource> { pub fn get_by_urn(&self, urn: &str) -> Option<&Resource> {
unimplemented!() if let Some(id) = {
let mut parts = urn.split_terminator(':');
let part_urn = parts.next().map(|u| u == "urn").unwrap_or(false);
let part_fabaccess = parts.next().map(|f| f == "fabaccess").unwrap_or(false);
let part_resource = parts.next().map(|r| r == "resource").unwrap_or(false);
if !(part_urn && part_fabaccess && part_resource) {
return None;
}
parts.next().map(|s| s.to_string())
} {
self.get_by_id(&id)
} else {
None
}
} }
} }