bffh/src/api/machine.rs

258 lines
7.9 KiB
Rust
Raw Normal View History

2022-02-26 14:00:00 +01:00
2021-09-21 07:48:19 +02:00
use std::time::Duration;
2020-11-17 14:15:29 +01:00
use capnp::capability::Promise;
2022-02-26 14:00:00 +01:00
2020-11-17 14:15:29 +01:00
use futures::FutureExt;
2022-02-26 14:00:00 +01:00
use crate::db::access::{Perms};
2021-09-18 22:14:47 +02:00
use crate::db::user::UserId;
use crate::db::machine::{Status, MachineState};
2021-09-18 17:01:35 +02:00
use crate::machine::Machine as NwMachine;
2021-09-09 21:50:11 +02:00
use crate::schema::machine_capnp::machine::*;
2021-09-18 22:14:47 +02:00
use crate::schema::machine_capnp::machine::MachineState as APIMState;
2020-11-17 14:15:29 +01:00
2021-09-18 22:14:47 +02:00
#[derive(Clone)]
2021-09-18 17:01:35 +02:00
pub struct Machine {
2021-09-18 22:14:47 +02:00
userid: UserId,
2021-09-18 17:01:35 +02:00
perms: Perms,
machine: NwMachine,
}
2020-11-17 14:28:04 +01:00
2021-09-18 17:01:35 +02:00
impl Machine {
2021-09-18 22:14:47 +02:00
pub fn new(userid: UserId, perms: Perms, machine: NwMachine) -> Self {
Self { userid, perms, machine }
2021-09-18 17:01:35 +02:00
}
2020-11-17 14:15:29 +01:00
}
2021-09-18 17:01:35 +02:00
impl info::Server for Machine {
fn get_machine_info_extended(
&mut self,
_: info::GetMachineInfoExtendedParams,
2021-11-26 00:31:25 +01:00
mut results: info::GetMachineInfoExtendedResults,
2021-09-18 22:14:47 +02:00
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let perms = self.perms.clone();
let f = async move {
if perms.manage {
2022-02-26 14:00:00 +01:00
let builder = results.get();
let mut extinfo = builder.init_machine_info_extended();
let guard = machine.lock().await;
// "previous" user
if let Some(user) = guard.get_previous() {
let mut previous = extinfo.reborrow().init_transfer_user();
previous.set_username(&user.uid);
}
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)
2021-01-20 11:55:15 +00:00
}
2021-09-18 17:01:35 +02:00
fn get_reservation_list(
&mut self,
_: info::GetReservationListParams,
2022-02-26 14:00:00 +01:00
_results: info::GetReservationListResults,
2021-09-18 22:14:47 +02:00
) -> Promise<(), capnp::Error> {
2021-09-18 17:01:35 +02:00
Promise::err(capnp::Error::unimplemented("Reservations are unavailable".to_string()))
2020-11-17 14:15:29 +01:00
}
2021-09-18 17:01:35 +02:00
fn get_property_list(
&mut self,
_: info::GetPropertyListParams,
2022-02-26 14:00:00 +01:00
_results: info::GetPropertyListResults,
2021-09-18 22:14:47 +02:00
) -> Promise<(), capnp::Error> {
2021-09-18 17:01:35 +02:00
Promise::err(capnp::Error::unimplemented("Extended Properties are unavailable".to_string()))
}
2021-09-09 21:50:11 +02:00
}
2021-09-18 17:01:35 +02:00
impl use_::Server for Machine {
fn use_(
&mut self,
_: use_::UseParams,
_: use_::UseResults
2021-09-18 22:14:47 +02:00
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let userid = self.userid.clone();
let f = async move {
let mut guard = machine.lock().await;
2021-09-21 07:48:19 +02:00
let mut ok = false;
{
match { guard.read_state().lock_ref().state.clone() } {
Status::Free => {
ok = true;
},
Status::Reserved(ref whom) => {
// If it's reserved for us or we're allowed to take over
if &userid == whom {
ok = true;
}
},
_ => { }
}
}
if ok {
guard.do_state_change(MachineState::used(Some(userid)));
2021-09-18 22:14:47 +02:00
}
Ok(())
};
2021-09-21 07:48:19 +02:00
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)
}
2020-11-17 14:15:29 +01:00
}
2021-09-18 17:01:35 +02:00
impl in_use::Server for Machine {
2021-09-18 22:14:47 +02:00
fn give_back(
&mut self,
_:in_use::GiveBackParams,
_:in_use::GiveBackResults
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let userid = self.userid.clone();
let f = async move {
let mut guard = machine.lock().await;
2021-09-21 07:48:19 +02:00
let mut ok = false;
{
match { guard.read_state().lock_ref().state.clone() } {
Status::InUse(ref whom) => {
if &Some(userid) == whom {
ok = true;
}
},
_ => { }
}
}
if ok {
guard.reset_state()
2021-09-18 22:14:47 +02:00
}
Ok(())
};
Promise::from_future(f)
}
2021-09-18 17:01:35 +02:00
}
2020-11-17 14:28:04 +01:00
2021-09-18 17:01:35 +02:00
impl transfer::Server for Machine {
2020-11-17 14:15:29 +01:00
}
2021-09-18 17:01:35 +02:00
impl check::Server for Machine {
}
2020-11-17 14:28:04 +01:00
2021-09-18 17:01:35 +02:00
impl manage::Server for Machine {
2021-09-18 22:14:47 +02:00
fn force_free(&mut self,
_: manage::ForceFreeParams,
_: manage::ForceFreeResults
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let f = async move {
let mut guard = machine.lock().await;
guard.do_state_change(MachineState::free());
Ok(())
};
Promise::from_future(f)
}
fn force_use(&mut self,
_: manage::ForceUseParams,
_: manage::ForceUseResults
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let f = async move {
let mut guard = machine.lock().await;
guard.do_state_change(MachineState::used(None));
Ok(())
};
Promise::from_future(f)
}
fn block(&mut self,
_:manage::BlockParams,
_:manage::BlockResults
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let uid = self.userid.clone();
let f = async move {
let mut guard = machine.lock().await;
guard.do_state_change(MachineState::blocked(uid));
Ok(())
};
Promise::from_future(f)
}
fn disabled(&mut self,
_:manage::DisabledParams,
_:manage::DisabledResults
) -> Promise<(), capnp::Error> {
let machine = self.machine.get_inner();
let f = async move {
let mut guard = machine.lock().await;
guard.do_state_change(MachineState::disabled());
Ok(())
};
Promise::from_future(f)
}
2021-09-18 17:01:35 +02:00
}
2020-11-17 14:15:29 +01:00
2021-09-18 17:01:35 +02:00
impl admin::Server for Machine {
2021-09-18 22:14:47 +02:00
fn force_set_state(&mut self,
params: admin::ForceSetStateParams,
_:admin::ForceSetStateResults
) -> Promise<(), capnp::Error> {
let uid = self.userid.clone();
let state = match pry!(pry!(params.get()).get_state()) {
APIMState::Free => MachineState::free(),
APIMState::Blocked => MachineState::blocked(uid),
APIMState::Disabled => MachineState::disabled(),
APIMState::InUse => MachineState::used(Some(uid)),
APIMState::Reserved => MachineState::reserved(uid),
APIMState::ToCheck => MachineState::check(uid),
};
let machine = self.machine.get_inner();
let f = async move {
let mut guard = machine.lock().await;
guard.do_state_change(state);
Ok(())
};
Promise::from_future(f)
}
2020-11-17 14:15:29 +01:00
}