-
Notifications
You must be signed in to change notification settings - Fork 1
Server Design
So a big question is how to structure the client/server relationship between the devices and the central controlling server. Below are some ideas (note that client refers to the individual cmdr devices, and server to the central server):
We use the ruby [dnssd library] (http://dnssd.rubyforge.org) and [Avahi] (http://avahi.org) in our zeroconf setup. Using these, we have each cmdr client broadcast itself via Multicast DNS when it comes online, and when it leaves. cmdr-serverr is constantly browsing for _cmdr_tcp zeroconf devices and notices when the device (the actual Ubuntu box in the classroom) broadcasts itself and the cmdr-server code does the following:
-
Resolves the device to a specific ip address and port.
-
Establishes two SSH port forwards with Net::SSH:Service::Forward
- one forwards from a port on the server to couchdb on the client (port 5984)
- the other forwards from a port on the server to the cmdr-daemon on the client (port 1412)
-
A document is created in the servers couchdb which contains the room name, port used for forwarding and the last time the room was interacted with. This document is a metaroom in a sense,
-
Once port forwarding is established, CouchDB replication is setup from client to server.
The server gets updates on everything that happens on the clients by means of CouchDB's continuous replication feature, from the clients to the server. That way, the server is constantly up to date and the info we show users is good. Since continuous replication isn't remembered over restarts of the couchdb daemon, we'll need a script that runs on couchdb start (upstart lets us do this) that starts replication.
We need a secure way to send commands from the server to the devices. I see two options: either establish ssh connections with the clients and tunnel all traffic over those (we could also do this for replicating couch, which is nice) or use private key authentication in cmdrHTTP itself (i.e., the server's public key is installed on all the clients and it has to send a message signed with its private key in order to communicate). The former is probably simpler because the OpenSSH people have done the hard work already, but the latter might be more reliable.
This is a little bit tricky, because obviously in order for configuration to do any good it has to be in the client's couchdb database. However, I'm not sure if we want to do replication from the server to the clients, because then every client will get everybody else's data which it has no use for. Maybe we should send the commands directly to the client's couchdb which will then get replicated by to the server automatically.
EDIT: Actually, it turns out that in CouchDB 0.11 "replication filters" were added. This will let us use replication to do what we need, because we can specify that only the documents belonging to that client will get synced back. In other news, CouchDB is still incredibly awesome.
An eigenroom should act exactly like a device for the server's cmdr instance. However, each eigenroom couchdb document will also have additional information for the how to contact the eigenroom including:
- room_id - which is the couchdb _id value of the represented room. So, all sources for a given room should have belongs_to equal to the room_id for that room's eigenroom.
- room_name - the hostname of the device in the room.
- ip_address - the ip_address of the room
- daemon_forward_port - a ssh forward should exist from server:daemon_forward_port to ip_address:1412. Note: this should be somewhat equivalent to doing a manual
ssh cmdr@cmdr-dev2.class.wesleyan.edu -L 9001:cmdr-dev2.class.wesleyan.edu:5984 -Ncommand. - couch_forward_port - a ssh forward should exist from server:couch_forward_port to ip_address:5984.