-
Notifications
You must be signed in to change notification settings - Fork 1
Configuration system
This document describes the configuration system of the Exosense server and device.
The internal structures and the JSON based API are the main objects described.
TODO: Specify how it controls descriptors, instances groups and devices.
A configuration descriptor contains the configuration specification and erlang code for RPCs and Monitors. Config descriptors are written in YANG. Often configuration descriptors include other descriptors to form an aggregate of many fragments. An example of a fragment is a configuration descriptor is a tty, which is always aggregated into a larger configuration descriptor specifying an entire device.
The descriptor also contains erlang code in the form of RPCs and monitors that can be executed on a device. The erlang code is specified in a "code" section that YANG is extended with. The main application of a device is written as a monitor provided through a specific "application" configuration descriptor.
Below is a configuration descriptor for a tty together with an RPC to send a break.
grouping tty {
leaf port {
type string;
}
rpc send-break {
input {
leaf MSec {
type uint16;
},
code {
fun(Msec) -> serctl:tcsendbreak(Msec).
}
}
}
A Fox20 board descriptor can aggregate a list copies of the tty descriptor. In addition to the serial ports, a list of A/D ports specific for the fox20 board are specified as well.
grouping fox20 {
leaf some_value {
type: uint32;
}
list serial-ports {
key "port";
uses tty;
}
list daq-ports {
key "port_no";
leaf port_no {
type uint16;
}
leaf sample_hz {
type uint16;
}
}
}
Another configuration fragment can describe the configuration for a YAWS web server executing on any device.
grouping yaws {
leaf listen-port {
type uint16;
}
}
The fox20 and yaws configuraiton descriptors can then be used as a template when creating a configuration instance.
A configuration instance is an aggregate of one or more instantiated configuratiopn descriptors. The instance contains the actual configuration data that is to be installed on devices. RPCs and monitors specified by the used configuration descriptors will be available in the devices receiving the configuration data instance.
The configuration instance is created through a JSON call, where the descriptors and the config data values are specified:
{
"jsonrpc": "2.0",
"method": "create-config-instance",
"id": 3,
"params": {
"name": "customer_x_fox20_rev_1.0",
"descriptors": [ "fox20" ]
"values": {
"some_value": 1234;
"serial-ports": [
{ "port": "/dev/ttyS0" },
{ "port": "/dev/ttyS1" }
],
"daq-ports": [
{
"port_no": 0;
"sample_hz": 50;
},
{
"port_no": 1;
"sample_hz": 250;
}
]
}
}
}
Values in the configuration instance can then be modified using JSON RPC calls:
{
// TODO: List edits.
"jsonrpc": "2.0",
"method": "set-config-instance-value",
"id": 3,
"params": {
"config-instance": "customer_x_fox20_rev_1.0",
"values": {
"some_value": 9999;
}
}
}
Devices specify a physical device, each with their own customer-unique device id. Device group memberships can be provisioned at creation time, or at a later point through a special json call. To provision a device, the following call is used:
{
"jsonrpc": "2.0",
"method": "provision-device",
"id": 3
"params": {
"device-id": 4711,
"device-groups": [ "customer_x_fox20_rev_1.0" ]
},
}
At this point, the
A device group is simply a collection of devices. A single device can belong to one or more groups. Device groups have no direct relation to configuration descriptors and instances. Instead, the main purpose of a device group is to act as a conduit between a configuration instance and the group member devices.
{
"jsonrpc": "2.0",
"method": "create-device-group",
"id": 3,
"params": {
"name": "customer_x_devices",
}
}
Once a device group has been provisioned the current values of a configuration instance can be pushed to to all members of the group:
{
"jsonrpc": "2.0",
"method": "push-config",
"id": 3,
"params": {
"config-instance": "customer_x_fox20_rev_1.0",
"device-group": "customer_x_devices"
}
}
The command above will start distributing all the config data and the RPC/Monitor code of "customer_x_fox20_rev_1.0" to the devices that are members of the group "customer_x_devices".
When a config instance is copied to a device group, the data will reach the device through three separate phases: staging, pending and active. These phases are processed on a per-device basis. The initial phase is entered for each device when the push-config JSON RPC is executed.
The staging phase represents the data before it has been transmitted to the target device. The configuration data is available on the server and describes what will eventually be copied to the device. When a data link has been established to the device, the staging data will be copied to the pending area inside the device.
At any time the staging configuration data for a device can be inspected through JSON RPC calls.
The pending phase is entered when the first configuration value is copied from the server to the device. Once all data has been copied from the server staging config data to the device pending config area, the pending data can be activated atomically on the device through a specific JSON request.
At any time, a JSON RPC call can be made to the server to retrieve the pending configuration data in order to inspect what configuration elements have actually been copied to the device. Any elements whose value differs between the staging data and the pending data is yet to be copied.
Once the staging and pending configuration data are identical, indicating that all configuration elements have been copied from the server to the pending area of the device, the pending data can be activated atomitcally through a JSON call. This call will atomically copy all data in the pending set on the device to the running set. The same operation will also be carried out on the active configuration data copy hosted on the server. Once the configuration data has been copied to the active set, the code running on the device will be notified of the updated data.
Each device often carry individual that needs to be modified directly, and not through the configuration data instance. This can be done by directly modifying the staging area configuration data for the given device:
{
// TODO: List edits.
"jsonrpc": "2.0",
"method": "set-device-value",
"id": 3,
"params": {
"device-id": 4711,
"values": {
"some_value": 9999;
}
}
}