mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-22 14:57:56 +01:00
Make machine correctly load state and set previous/current use in API
This commit is contained in:
parent
9fcb7664aa
commit
47781b445e
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "diflouroborane"
|
name = "diflouroborane"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
authors = [ "dequbed <me@dequbed.space>"
|
authors = [ "dequbed <me@dequbed.space>"
|
||||||
, "Kai Jan Kriegel <kai@kjkriegel.de>"
|
, "Kai Jan Kriegel <kai@kjkriegel.de>"
|
||||||
, "Joseph Langosch <thejoklla@gmail.com>"
|
, "Joseph Langosch <thejoklla@gmail.com>"
|
||||||
|
@ -65,13 +65,52 @@ impl info::Server for Machine {
|
|||||||
_: info::GetMachineInfoExtendedParams,
|
_: info::GetMachineInfoExtendedParams,
|
||||||
mut results: info::GetMachineInfoExtendedResults,
|
mut results: info::GetMachineInfoExtendedResults,
|
||||||
) -> Promise<(), capnp::Error> {
|
) -> Promise<(), capnp::Error> {
|
||||||
if self.perms.manage {
|
let machine = self.machine.get_inner();
|
||||||
|
let perms = self.perms.clone();
|
||||||
|
let f = async move {
|
||||||
|
if perms.manage {
|
||||||
let mut builder = results.get();
|
let mut builder = results.get();
|
||||||
let mut extinfo = builder.init_machine_info_extended();
|
let mut extinfo = builder.init_machine_info_extended();
|
||||||
let mut current = extinfo.init_current_user();
|
let guard = machine.lock().await;
|
||||||
current.set_username(&self.userid.uid);
|
|
||||||
|
// "previous" user
|
||||||
|
if let Some(user) = guard.get_previous() {
|
||||||
|
let mut previous = extinfo.reborrow().init_transfer_user();
|
||||||
|
previous.set_username(&user.uid);
|
||||||
}
|
}
|
||||||
Promise::ok(())
|
|
||||||
|
let state = guard.read_state();
|
||||||
|
let state_lock = state.lock_ref();
|
||||||
|
match state_lock.state {
|
||||||
|
Status::Free => {}
|
||||||
|
Status::InUse(ref user) => if user.is_some() {
|
||||||
|
let user = user.as_ref().unwrap();
|
||||||
|
let mut current = extinfo.init_current_user();
|
||||||
|
current.set_username(&user.uid);
|
||||||
|
}
|
||||||
|
Status::ToCheck(ref user) => {
|
||||||
|
let mut current = extinfo.init_current_user();
|
||||||
|
current.set_username(&user.uid);
|
||||||
|
}
|
||||||
|
Status::Blocked(ref user) => {
|
||||||
|
let mut current = extinfo.init_current_user();
|
||||||
|
current.set_username(&user.uid);
|
||||||
|
}
|
||||||
|
Status::Disabled => {}
|
||||||
|
Status::Reserved(ref user) => {
|
||||||
|
let mut current = extinfo.init_current_user();
|
||||||
|
current.set_username(&user.uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
|
let g = smol::future::race(f, smol::Timer::after(Duration::from_secs(4))
|
||||||
|
.map(|_| Err(capnp::Error::failed("Waiting for machine lock timed out!".to_string()))));
|
||||||
|
|
||||||
|
Promise::from_future(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_reservation_list(
|
fn get_reservation_list(
|
||||||
|
@ -24,10 +24,12 @@ pub mod access;
|
|||||||
/// Stores&Retrieves Machines
|
/// Stores&Retrieves Machines
|
||||||
pub mod machine;
|
pub mod machine;
|
||||||
|
|
||||||
|
pub type MachineDB = machine::internal::Internal;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Databases {
|
pub struct Databases {
|
||||||
pub access: Arc<access::AccessControl>,
|
pub access: Arc<access::AccessControl>,
|
||||||
pub machine: Arc<machine::internal::Internal>,
|
pub machine: Arc<MachineDB>,
|
||||||
pub userdb: Arc<user::Internal>,
|
pub userdb: Arc<user::Internal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl MachineState {
|
|||||||
|
|
||||||
pub fn init(log: Logger, _config: &Config, env: Arc<lmdb::Environment>) -> Result<Internal> {
|
pub fn init(log: Logger, _config: &Config, env: Arc<lmdb::Environment>) -> Result<Internal> {
|
||||||
let mut flags = lmdb::DatabaseFlags::empty();
|
let mut flags = lmdb::DatabaseFlags::empty();
|
||||||
flags.set(lmdb::DatabaseFlags::INTEGER_KEY, true);
|
//flags.set(lmdb::DatabaseFlags::INTEGER_KEY, true);
|
||||||
let machdb = env.create_db(Some("machines"), flags)?;
|
let machdb = env.create_db(Some("machines"), flags)?;
|
||||||
debug!(&log, "Opened machine db successfully.");
|
debug!(&log, "Opened machine db successfully.");
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
use lmdb::{Environment, Transaction, RwTransaction, Cursor};
|
use lmdb::{Environment, Transaction, RwTransaction, Cursor, RoTransaction};
|
||||||
|
|
||||||
use super::{MachineIdentifier, MachineState};
|
use super::{MachineIdentifier, MachineState};
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
@ -37,11 +37,11 @@ impl Internal {
|
|||||||
self.get_with_txn(&txn, id)
|
self.get_with_txn(&txn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_with_txn(&self, txn: &mut RwTransaction, uuid: &String, status: &MachineState)
|
pub fn put_with_txn(&self, txn: &mut RwTransaction, id: &String, status: &MachineState)
|
||||||
-> Result<()>
|
-> Result<()>
|
||||||
{
|
{
|
||||||
let bytes = flexbuffers::to_vec(status)?;
|
let bytes = flexbuffers::to_vec(status)?;
|
||||||
txn.put(self.db, &uuid.as_bytes(), &bytes, lmdb::WriteFlags::empty())?;
|
txn.put(self.db, &id.as_bytes(), &bytes, lmdb::WriteFlags::empty())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -52,11 +52,20 @@ impl Internal {
|
|||||||
txn.commit().map_err(Into::into)
|
txn.commit().map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter<T: Transaction>(&self, txn: &T) -> Result<impl Iterator<Item=MachineState>> {
|
pub fn iter<'txn, T: Transaction>(&self, txn: &'txn T)
|
||||||
|
-> Result<impl Iterator<Item=(&'txn str, MachineState)>>
|
||||||
|
{
|
||||||
let mut cursor = txn.open_ro_cursor(self.db)?;
|
let mut cursor = txn.open_ro_cursor(self.db)?;
|
||||||
Ok(cursor.iter_start().map(|buf| {
|
Ok(cursor.iter_start().map(|buf| {
|
||||||
let (_kbuf, vbuf) = buf.unwrap();
|
let (kbuf, vbuf) = buf.unwrap();
|
||||||
flexbuffers::from_slice(vbuf).unwrap()
|
let id = unsafe { std::str::from_utf8_unchecked(kbuf) };
|
||||||
|
let state = flexbuffers::from_slice(vbuf).unwrap();
|
||||||
|
(id, state)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn txn(&self) -> Result<RoTransaction> {
|
||||||
|
let txn = self.env.begin_ro_txn()?;
|
||||||
|
Ok(txn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,13 @@ use futures::channel::{mpsc, oneshot};
|
|||||||
use futures_signals::signal::Signal;
|
use futures_signals::signal::Signal;
|
||||||
use futures_signals::signal::SignalExt;
|
use futures_signals::signal::SignalExt;
|
||||||
use futures_signals::signal::{Mutable, ReadOnlyMutable};
|
use futures_signals::signal::{Mutable, ReadOnlyMutable};
|
||||||
|
use slog::Logger;
|
||||||
|
|
||||||
use crate::error::{Result, Error};
|
use crate::error::{Result, Error};
|
||||||
|
|
||||||
use crate::db::access;
|
use crate::db::{access, Databases, MachineDB};
|
||||||
use crate::db::machine::{MachineIdentifier, MachineState, Status};
|
use crate::db::machine::{MachineIdentifier, MachineState, Status};
|
||||||
use crate::db::user::{User, UserData};
|
use crate::db::user::{User, UserData, UserId};
|
||||||
|
|
||||||
use crate::network::MachineMap;
|
use crate::network::MachineMap;
|
||||||
use crate::space;
|
use crate::space;
|
||||||
@ -73,13 +74,14 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct
|
pub fn construct(
|
||||||
( id: MachineIdentifier
|
id: MachineIdentifier,
|
||||||
, desc: MachineDescription
|
desc: MachineDescription,
|
||||||
, state: MachineState
|
state: MachineState,
|
||||||
|
db: Arc<MachineDB>,
|
||||||
) -> Machine
|
) -> Machine
|
||||||
{
|
{
|
||||||
Self::new(Inner::new(id, state), desc)
|
Self::new(Inner::new(id, state, db), desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_state_change(&self, new_state: MachineState)
|
pub fn do_state_change(&self, new_state: MachineState)
|
||||||
@ -136,17 +138,20 @@ pub struct Inner {
|
|||||||
/// case of an actor it should then make sure that the real world matches up with the set state
|
/// case of an actor it should then make sure that the real world matches up with the set state
|
||||||
state: Mutable<MachineState>,
|
state: Mutable<MachineState>,
|
||||||
reset: Option<MachineState>,
|
reset: Option<MachineState>,
|
||||||
|
|
||||||
|
previous: Option<UserId>,
|
||||||
|
|
||||||
|
db: Arc<MachineDB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
pub fn new ( id: MachineIdentifier
|
pub fn new(id: MachineIdentifier, state: MachineState, db: Arc<MachineDB>) -> Inner {
|
||||||
, state: MachineState
|
|
||||||
) -> Inner
|
|
||||||
{
|
|
||||||
Inner {
|
Inner {
|
||||||
id,
|
id,
|
||||||
state: Mutable::new(state),
|
state: Mutable::new(state),
|
||||||
reset: None,
|
reset: None,
|
||||||
|
previous: None,
|
||||||
|
db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +167,13 @@ impl Inner {
|
|||||||
Box::pin(self.state.signal_cloned().dedupe_cloned())
|
Box::pin(self.state.signal_cloned().dedupe_cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn replace_state(&mut self, new_state: MachineState) -> MachineState {
|
||||||
|
self.db.put(&self.id, &new_state);
|
||||||
|
self.state.replace(new_state)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn do_state_change(&mut self, new_state: MachineState) {
|
pub fn do_state_change(&mut self, new_state: MachineState) {
|
||||||
let old_state = self.state.replace(new_state);
|
let old_state = self.replace_state(new_state);
|
||||||
self.reset.replace(old_state);
|
self.reset.replace(old_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +186,30 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_state(&mut self) {
|
pub fn reset_state(&mut self) {
|
||||||
if let Some(state) = self.reset.take() {
|
let previous_state = self.read_state();
|
||||||
self.state.replace(state);
|
let state_lock = previous_state.lock_ref();
|
||||||
|
// Only update previous user if state changed from InUse or ToCheck to whatever.
|
||||||
|
match state_lock.state {
|
||||||
|
Status::InUse(ref user) => {
|
||||||
|
self.previous = user.clone();
|
||||||
|
},
|
||||||
|
Status::ToCheck(ref user) => {
|
||||||
|
self.previous = Some(user.clone());
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
|
drop(state_lock);
|
||||||
|
|
||||||
|
if let Some(state) = self.reset.take() {
|
||||||
|
self.replace_state(state);
|
||||||
|
} else {
|
||||||
|
// Default to Free
|
||||||
|
self.replace_state(MachineState::free());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_previous(&self) -> &Option<UserId> {
|
||||||
|
&self.previous
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,15 +273,22 @@ impl MachineDescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(config: &crate::config::Config)
|
pub fn load(config: &crate::config::Config, db: Databases, log: &Logger)
|
||||||
-> Result<MachineMap>
|
-> Result<MachineMap>
|
||||||
{
|
{
|
||||||
let mut map = config.machines.clone();
|
let mut map = config.machines.clone();
|
||||||
|
let db = db.machine;
|
||||||
|
|
||||||
let it = map.drain()
|
let it = map.drain()
|
||||||
.map(|(k,v)| {
|
.map(|(k,v)| {
|
||||||
// TODO: Read state from the state db
|
// TODO: Read state from the state db
|
||||||
(v.name.clone(), Machine::construct(k, v, MachineState::new()))
|
if let Some(state) = db.get(&k).unwrap() {
|
||||||
|
debug!(log, "Loading old state from db for {}: {:?}", &k, &state);
|
||||||
|
(v.name.clone(), Machine::construct(k, v, state, db.clone()))
|
||||||
|
} else {
|
||||||
|
debug!(log, "No old state found in db for {}, creating new.", &k);
|
||||||
|
(v.name.clone(), Machine::construct(k, v, MachineState::new(), db.clone()))
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
11
src/main.rs
11
src/main.rs
@ -167,7 +167,16 @@ fn maybe(matches: clap::ArgMatches, log: Arc<Logger>) -> Result<(), Error> {
|
|||||||
let ex = Executor::new();
|
let ex = Executor::new();
|
||||||
let db = db::Databases::new(&log, &config)?;
|
let db = db::Databases::new(&log, &config)?;
|
||||||
|
|
||||||
let machines = machine::load(&config)?;
|
{
|
||||||
|
info!(log, "Loaded DB state:");
|
||||||
|
let txn = db.machine.txn()?;
|
||||||
|
for (id, state) in db.machine.iter(&txn)? {
|
||||||
|
info!(log, "- {}: {:?}", id, state);
|
||||||
|
}
|
||||||
|
info!(log, "Loaded DB state END.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let machines = machine::load(&config, db.clone(), &log)?;
|
||||||
let (actor_map, actors) = actor::load(&log, &config)?;
|
let (actor_map, actors) = actor::load(&log, &config)?;
|
||||||
let (init_map, initiators) = initiator::load(&log, &config)?;
|
let (init_map, initiators) = initiator::load(&log, &config)?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user