Additional functionality

This commit is contained in:
Gregor Reitzenstein 2020-02-17 21:07:50 +01:00
parent e135d7c8bd
commit f5b37f2006
4 changed files with 68 additions and 11 deletions

View File

@ -15,7 +15,7 @@ futures = "0.3"
futures-util = "0.3" futures-util = "0.3"
futures-signals = "0.3" futures-signals = "0.3"
slog = "2.5" slog = { version = "2.5", features = ["max_level_trace"] }
slog-term = "2.5" slog-term = "2.5"
slog-async = "2.4" slog-async = "2.4"

View File

@ -49,10 +49,11 @@ struct UUID {
# paramount that you are consistent when encoding and decoding this type. # paramount that you are consistent when encoding and decoding this type.
# #
# Consider using this algorithm for assembling the 128-bit integer: # Consider using this algorithm for assembling the 128-bit integer:
# uint128_t uuid = (uuid1 << 64) + uuid0; # (assuming ISO9899:2018 shifting & casting rules)
# uint128_t num = (uuid1 << 64) + uuid0;
# And then respectively this code for deconstructing it: # And then respectively this code for deconstructing it:
# uint64_t uuid0 = (uint64_t num); # uint64_t uuid0 = (uint64_t) num;
# uint64_t uuid1 = (uint64_t (num >> 64)); # uint64_t uuid1 = (uint64_t) (num >> 64);
uuid0 @0 :UInt64; uuid0 @0 :UInt64;
uuid1 @1 :UInt64; uuid1 @1 :UInt64;
@ -63,19 +64,19 @@ interface Machines {
setBlocked @0 ( blocked :Bool ) -> (); setBlocked @0 ( blocked :Bool ) -> ();
# Block or Unblock the machine. A blocked machine can not be used. # Block or Unblock the machine. A blocked machine can not be used.
return @1 () -> (); forceReturn @1 () -> ();
# Forcefully marking a machine as `returned` — i.e. not used. # Forcefully marking a machine as `returned` — i.e. not used.
} }
interface Return { interface GiveBack {
# The only way of getting a `return` interface is by successfully calling `use`. This means # The only way of getting a `return` interface is by successfully calling `use`. This means
# only the user that marked a machine as `used` can return it again. (Baring force override) # only the user that marked a machine as `used` can return it again. (Baring force override)
return @0 () -> (); giveback @0 () -> ();
} }
manage @0 ( uuid :UUID ) -> ( manage :Manage ); manage @0 ( uuid :UUID ) -> ( manage :Manage );
use @1 ( uuid :UUID ) -> ( return :Return ); use @1 ( uuid :UUID ) -> ( giveback :GiveBack );
# Use a machine, identified by its UUID. If the caller is allowed to and the machine is # Use a machine, identified by its UUID. If the caller is allowed to and the machine is
# available to being used a `return` Capability will be returned — the person using a machine is # available to being used a `return` Capability will be returned — the person using a machine is
# after all the only person that can return the machine after use. # after all the only person that can return the machine after use.

View File

@ -86,8 +86,29 @@ impl api::machines::Server for Machines {
let mdb = self.mdb.lock_ref(); let mdb = self.mdb.lock_ref();
if let Some(m) = mdb.get(&uuid) { if let Some(m) = mdb.get(&uuid) {
match m.status {
Status::Free => {
trace!(self.log, "Granted use on machine {}", uuid); trace!(self.log, "Granted use on machine {}", uuid);
let mut b = results.get();
let gb = api::machines::give_back::ToClient::new(
GiveBack::new(self.log.new(o!()), uuid, self.mdb.clone())
).into_client::<Server>();
b.set_giveback(gb);
Promise::ok(()) Promise::ok(())
},
Status::Occupied => {
info!(self.log, "Attempted use on an occupied machine {}", uuid);
Promise::err(Error::failed("Machine is occupied".to_string()))
},
Status::Blocked => {
info!(self.log, "Attempted use on a blocked machine {}", uuid);
Promise::err(Error::failed("Machine is blocked".to_string()))
}
}
} else { } else {
info!(self.log, "Attempted use on invalid machine {}", uuid); info!(self.log, "Attempted use on invalid machine {}", uuid);
Promise::err(Error::failed("No such machine".to_string())) Promise::err(Error::failed("No such machine".to_string()))
@ -95,6 +116,36 @@ impl api::machines::Server for Machines {
} }
} }
pub struct GiveBack {
log: Logger,
mdb: Mutable<MachineDB>,
uuid: Uuid,
}
impl GiveBack {
pub fn new(log: Logger, uuid: Uuid, mdb: Mutable<MachineDB>) -> Self {
trace!(log, "Giveback initialized for {}", uuid);
Self { log, mdb, uuid }
}
}
impl api::machines::give_back::Server for GiveBack {
fn giveback(&mut self,
_params: api::machines::give_back::GivebackParams,
_results: api::machines::give_back::GivebackResults)
-> Promise<(), Error>
{
trace!(log, "Returning {}...", uuid);
let mut mdb = self.mdb.lock_mut();
if let Some(m) = mdb.get_mut(&self.uuid) {
m.status = Status::Free;
} else {
warn!(self.log, "A giveback was issued for a unknown machine {}", self.uuid);
}
Promise::ok(())
}
}
// FIXME: Test this exhaustively! // FIXME: Test this exhaustively!
fn uuid_from_api(uuid: api::u_u_i_d::Reader) -> Uuid { fn uuid_from_api(uuid: api::u_u_i_d::Reader) -> Uuid {
let uuid0 = uuid.get_uuid0() as u128; let uuid0 = uuid.get_uuid0() as u128;

View File

@ -58,16 +58,22 @@ fn main() {
let permlog = log.new(o!()); let permlog = log.new(o!());
let machlog = log.new(o!()); let machlog = log.new(o!());
machine::save(&c2, &m2.lock_ref()).expect("MachineDB save");
let spawner = exec.spawner(); let spawner = exec.spawner();
let result: Result<(), Box<dyn std::error::Error>> = exec.run_until(async move { let result: Result<(), Box<dyn std::error::Error>> = exec.run_until(async move {
let listener = async_std::net::TcpListener::bind(&addr).await?; let listener = async_std::net::TcpListener::bind(&addr).await?;
let mut incoming = listener.incoming(); let mut incoming = listener.incoming();
while let Some(socket) = incoming.next().await { while let Some(socket) = incoming.next().await {
let socket = socket?; let socket = socket?;
trace!(log, "New connection from {:?}", socket.peer_addr());
// TODO: Prettify session handling // TODO: Prettify session handling
let auth = auth::Authentication::new(authp.clone()); let auth = auth::Authentication::new(authp.clone());
trace!(log, "Init auth");
let perm = access::Permissions::new(permlog.clone(), enf.clone(), auth.clone()); let perm = access::Permissions::new(permlog.clone(), enf.clone(), auth.clone());
trace!(log, "Init perm");
let mach = machine::Machines::new(machlog.clone(), m.clone(), perm.clone()); let mach = machine::Machines::new(machlog.clone(), m.clone(), perm.clone());
trace!(log, "Init mach");
let rpc_system = api::process_socket(auth, perm, mach, socket); let rpc_system = api::process_socket(auth, perm, mach, socket);
spawner.spawn_local_obj( spawner.spawn_local_obj(
@ -77,5 +83,4 @@ fn main() {
}); });
result.expect("main"); result.expect("main");
machine::save(&c2, &m2.lock_ref()).expect("MachineDB save");
} }