diff --git a/Cargo.toml b/Cargo.toml index b15bd3b..4d50c95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ futures = "0.3" futures-util = "0.3" futures-signals = "0.3" -slog = "2.5" +slog = { version = "2.5", features = ["max_level_trace"] } slog-term = "2.5" slog-async = "2.4" diff --git a/schema/api.capnp b/schema/api.capnp index 6f64c24..ed09a14 100644 --- a/schema/api.capnp +++ b/schema/api.capnp @@ -49,10 +49,11 @@ struct UUID { # paramount that you are consistent when encoding and decoding this type. # # 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: - # uint64_t uuid0 = (uint64_t num); - # uint64_t uuid1 = (uint64_t (num >> 64)); + # uint64_t uuid0 = (uint64_t) num; + # uint64_t uuid1 = (uint64_t) (num >> 64); uuid0 @0 :UInt64; uuid1 @1 :UInt64; @@ -63,19 +64,19 @@ interface Machines { setBlocked @0 ( blocked :Bool ) -> (); # 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. } - interface Return { + interface GiveBack { # 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) - return @0 () -> (); + giveback @0 () -> (); } 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 # 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. diff --git a/src/machine.rs b/src/machine.rs index edd6d90..2782adf 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -86,8 +86,29 @@ impl api::machines::Server for Machines { let mdb = self.mdb.lock_ref(); if let Some(m) = mdb.get(&uuid) { - trace!(self.log, "Granted use on machine {}", uuid); - Promise::ok(()) + match m.status { + Status::Free => { + 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::(); + + b.set_giveback(gb); + + 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 { info!(self.log, "Attempted use on invalid machine {}", uuid); 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, + uuid: Uuid, +} +impl GiveBack { + pub fn new(log: Logger, uuid: Uuid, mdb: Mutable) -> 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! fn uuid_from_api(uuid: api::u_u_i_d::Reader) -> Uuid { let uuid0 = uuid.get_uuid0() as u128; diff --git a/src/main.rs b/src/main.rs index 81c4246..58a104d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,16 +58,22 @@ fn main() { let permlog = log.new(o!()); let machlog = log.new(o!()); + machine::save(&c2, &m2.lock_ref()).expect("MachineDB save"); + let spawner = exec.spawner(); let result: Result<(), Box> = exec.run_until(async move { let listener = async_std::net::TcpListener::bind(&addr).await?; let mut incoming = listener.incoming(); while let Some(socket) = incoming.next().await { let socket = socket?; + trace!(log, "New connection from {:?}", socket.peer_addr()); // TODO: Prettify session handling let auth = auth::Authentication::new(authp.clone()); + trace!(log, "Init auth"); 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()); + trace!(log, "Init mach"); let rpc_system = api::process_socket(auth, perm, mach, socket); spawner.spawn_local_obj( @@ -77,5 +83,4 @@ fn main() { }); result.expect("main"); - machine::save(&c2, &m2.lock_ref()).expect("MachineDB save"); }