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-signals = "0.3"
slog = "2.5"
slog = { version = "2.5", features = ["max_level_trace"] }
slog-term = "2.5"
slog-async = "2.4"

View File

@ -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.

View File

@ -86,8 +86,29 @@ impl api::machines::Server for Machines {
let mdb = self.mdb.lock_ref();
if let Some(m) = mdb.get(&uuid) {
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::<Server>();
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<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!
fn uuid_from_api(uuid: api::u_u_i_d::Reader) -> Uuid {
let uuid0 = uuid.get_uuid0() as u128;

View File

@ -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<dyn std::error::Error>> = 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");
}