From 660fe5ed9e91129d841b2bcc8d13dc81f5ed1bdd Mon Sep 17 00:00:00 2001 From: Nadja Reitzenstein Date: Sat, 18 Sep 2021 22:14:47 +0200 Subject: [PATCH] Most of Machine implemented --- src/api/machine.rs | 138 +++++++++++++++++++++++++++++++++++++++++--- src/api/machines.rs | 16 ++--- src/db/machine.rs | 20 +++++++ 3 files changed, 158 insertions(+), 16 deletions(-) diff --git a/src/api/machine.rs b/src/api/machine.rs index 393593a..bfd85d6 100644 --- a/src/api/machine.rs +++ b/src/api/machine.rs @@ -6,10 +6,11 @@ use capnp::Error; use futures::FutureExt; use crate::db::access::{PrivilegesBuf, PermRule}; - -use crate::db::machine::Status; +use crate::db::user::UserId; +use crate::db::machine::{Status, MachineState}; use crate::machine::Machine as NwMachine; use crate::schema::machine_capnp::machine::*; +use crate::schema::machine_capnp::machine::MachineState as APIMState; #[derive(Clone, Copy)] pub struct Perms { @@ -44,14 +45,16 @@ impl Perms { } } +#[derive(Clone)] pub struct Machine { + userid: UserId, perms: Perms, machine: NwMachine, } impl Machine { - pub fn new(perms: Perms, machine: NwMachine) -> Self { - Self { perms, machine } + pub fn new(userid: UserId, perms: Perms, machine: NwMachine) -> Self { + Self { userid, perms, machine } } } @@ -60,7 +63,7 @@ impl info::Server for Machine { &mut self, _: info::GetMachineInfoExtendedParams, _results: info::GetMachineInfoExtendedResults, - ) -> capnp::capability::Promise<(), capnp::Error> { + ) -> Promise<(), capnp::Error> { /*if self.perms.manage { let mut builder = results.get(); let mut extinfo = builder.init_machine_info_extended(); @@ -76,7 +79,7 @@ impl info::Server for Machine { &mut self, _: info::GetReservationListParams, mut results: info::GetReservationListResults, - ) -> capnp::capability::Promise<(), capnp::Error> { + ) -> Promise<(), capnp::Error> { Promise::err(capnp::Error::unimplemented("Reservations are unavailable".to_string())) } @@ -84,7 +87,7 @@ impl info::Server for Machine { &mut self, _: info::GetPropertyListParams, mut results: info::GetPropertyListResults, - ) -> capnp::capability::Promise<(), capnp::Error> { + ) -> Promise<(), capnp::Error> { Promise::err(capnp::Error::unimplemented("Extended Properties are unavailable".to_string())) } } @@ -94,12 +97,55 @@ impl use_::Server for Machine { &mut self, _: use_::UseParams, _: use_::UseResults - ) -> capnp::capability::Promise<(), capnp::Error> { - Promise::ok(()) + ) -> Promise<(), capnp::Error> { + let machine = self.machine.get_inner(); + let userid = self.userid.clone(); + let f = async move { + let mut guard = machine.lock().await; + match guard.read_state().lock_ref().state { + Status::Free => { + guard.do_state_change(MachineState::used(Some(userid))); + }, + Status::Reserved(ref whom) => { + // If it's reserved for us or we're allowed to take over + if &userid == whom { + guard.do_state_change(MachineState::used(Some(userid))); + } + }, + _ => { } + } + + Ok(()) + }; + + Promise::from_future(f) } } impl in_use::Server for Machine { + 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; + match guard.read_state().lock_ref().state { + Status::InUse(ref whom) => { + if &Some(userid) == whom { + guard.reset_state() + } + }, + _ => {} + } + + Ok(()) + }; + + Promise::from_future(f) + } } impl transfer::Server for Machine { @@ -109,7 +155,81 @@ impl check::Server for Machine { } impl manage::Server for Machine { + 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) + } } impl admin::Server for Machine { + 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) + } + } diff --git a/src/api/machines.rs b/src/api/machines.rs index 25bf646..1ea8726 100644 --- a/src/api/machines.rs +++ b/src/api/machines.rs @@ -59,6 +59,7 @@ impl machines::Server for Machines { .collect(); let permissions = self.permissions.clone(); + let user = self.user.clone(); let f = async move { let mut machines = results.get().init_machine_list(v.len() as u32); @@ -81,20 +82,21 @@ impl machines::Server for Machines { }; builder.set_state(s); + let machineapi = Machine::new(user.clone(), perms, machine.clone()); if perms.write { - builder.set_use(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); - builder.set_inuse(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); + builder.set_use(capnp_rpc::new_client(machineapi.clone())); + builder.set_inuse(capnp_rpc::new_client(machineapi.clone())); } if perms.manage { - builder.set_transfer(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); - builder.set_check(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); - builder.set_manage(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); + builder.set_transfer(capnp_rpc::new_client(machineapi.clone())); + builder.set_check(capnp_rpc::new_client(machineapi.clone())); + builder.set_manage(capnp_rpc::new_client(machineapi.clone())); } if permissions.iter().any(|r| r.match_perm(&admin_perm())) { - builder.set_admin(capnp_rpc::new_client(Machine::new(perms, machine.clone()))); + builder.set_admin(capnp_rpc::new_client(machineapi.clone())); } - builder.set_info(capnp_rpc::new_client(Machine::new(perms, machine))); + builder.set_info(capnp_rpc::new_client(machineapi)); } Ok(()) diff --git a/src/db/machine.rs b/src/db/machine.rs index 807a5b3..01b8002 100644 --- a/src/db/machine.rs +++ b/src/db/machine.rs @@ -44,6 +44,10 @@ impl MachineState { Self { state: Status::Free } } + pub fn from(state: Status) -> Self { + Self { state } + } + pub fn free() -> Self { Self { state: Status::Free } } @@ -51,6 +55,22 @@ impl MachineState { pub fn used(uid: Option) -> Self { Self { state: Status::InUse(uid) } } + + pub fn blocked(uid: UserId) -> Self { + Self { state: Status::Blocked(uid) } + } + + pub fn disabled() -> Self { + Self { state: Status::Disabled } + } + + pub fn reserved(uid: UserId) -> Self { + Self { state: Status::Reserved(uid) } + } + + pub fn check(uid: UserId) -> Self { + Self { state: Status::ToCheck(uid) } + } } pub fn init(log: Logger, _config: &Config, env: Arc) -> Result {