At 04:14 PM 7/5/2004 -0700, Chad Carr wrote:
All,

I started to draw this out, but I just simply do not have skills in that area. Some would question my verbal skills as well, \

Not me. At least, not based on this message ... it is exactly what I was asking for youi to clarify. I'm going to walk through the steps below, choosing to focus on a concrete example: using a Web interface to enter a static IP address, and related information, for the external interface. It's a fairly common need, one that users will often have to do as a first thing.


If this exercise works ... I'm actually doing it as I write this reply ... you'll see the point by the end.

but here goes:

Each of the tools (cdb, trig and tmpl) represents a data store.

cdb -> abstract configuration variables
trig -> abstract actions tied to those variables, with package-specific handlers
tmpl -> package-specific data allowing the creation of operational configuration files from abstract configuration data.


The idea is that an interface (of arbitrary complexity) needs only to know the abstract values (configuration parameters and trigger actions), and the packages can make themselves work.

It would go something like this:

1) The user chooses to configure his or her LEAF router via an interface (web, ncurses, etc.) backed by leaf-tools.

OK. He or she connects via a browser to a Weblet-like server. It displays some sort of top-level menu. One choice is something like "Configure Connection to ISP". User chooses that.


2) The interface makes one or more calls to cdb to obtain the current canonical values for a handful of (hopefully related) configuration parameters.

OK. In practice, this sort of setup would have to get the following variables. (Actually, since this is a first configuration, it doesn't really have to get anything, except perhaps the identity of the external interface.) The choice in [] is the default/current setting.


identity of external interface: [eth0]/eth1
MAC address of interface: [aa:bb:cc:dd:ee:ff]
(might use this for cases where the system needs to do MAC-address
spoofing to deal with ISP authentication baloney)
address assignment method: [static]/dhcp/pppoe
IP address: [0.0.0.0]
Netmask: [0.0.0.0] (or maybe /0)
Broadcast: [255.255.255.255]
Gateway: [0.0.0.0]
DNS Server 1: [0.0.0.0]
DNS Server 2: [0.0.0.0]
(could be more DNS servers, but ISPs typically provide 2)
Userid: []
Password: []
(rarely needed with static connections; often needed with PPPoE)
(these next few might not be part of this page)
SMTP server: [] (this would be an FQN, not an IP address)
NTP Server 1:[] (should take an FQN or an IP address)
NTP Server 2:[] (should take an FQN or an IP address)


How does the list of available interfaces (the first item above) get generated? My guess is that for hardware-level issues, LEAF, and any UI for it, should NOT rely on the database. So in this instance, it actually checks for the physical interfaces (eth*) present, makes them available for selection, and in the absence of a prior configuration, queries cdb for a default choice (eth0 for external, eth1 for internal, eth2 if a DMZ option is available). For PPPoE, the system still wants to know the physical interface to use; the ppp0 interface can be invisible to the UI. Only if the system supports dial-up should a ppp0 be an explicit choice for users.

3) Cdb returns these values to the interface as "name=value" pairs that may be sourced via the usual shell script methods.

This part would look roughly like this (from my memory of how LRP did it in the old days):


        $IF_EXT=eth0
        $MAC_EXT=aa:bb:cc:dd:ee:ff
        $IP_EXT_STATIC=true
        $IP_EXT_PPPOE=false
        $IP_EXT_DHCP=false
        $IP_EXT_ADDRESS=0.0.0.0
        $IP_EXT_NETMASK=0.0.0.0
        $IP_EXT_BROADCAST=255.255.255.255
        $IP_EXT_GW=0.0.0.0
        $IP_EXT_DNS1=0.0.0.0
        $IP_EXT_DNS2=0.0.0.0
        $IP_EXT_USERID=
        $IP_EXT_PASSWD=
        $IP_EXT_SMTP=
        $IP_EXT_NTP1=
        $IP_EXT_NTP2=

4) The interface draws some sort of user-friendly input device (probably a form of some kind) to display those values and allow the user to alter them.

Right. I assume the Web system would at a minimum support CGI scripts. Javascript is nice for this sort of stuff, but probably beyond LEAF's limited Web-server capacity.


Remember that altering the values might require additional calls to cdb. In the example, the obvious candidate is "identity of external interface" -- if the user changes it from eth0 to eth1, the rest of the $IF_* values might need to be replaced with the cdb values for eth1. (Or maybe not - swapping interfaces is kind of tricky from a UI perspective.)

5) The interface accepts the user input, then makes one or more calls to cdb to update the configuration data.

Where does input validation happen? Does the interface confirm that the entries that are supposed to be IP addresses, for example, have the right form? That the IP address, netmask, broadcast address (if entered separaely and not calculated), and gateway values are mutually consistent? Or does the database backend handle any of that?


6) This data is inserted into cdb's backing store (whatever that happens to be!)

What does the qualifier mean here? Are you contemplating storing the config file off system, accessed via NFS, SMB, or something? For now, I'll simply assume that (a) the database is located on the system in a well-known place and (b) it is its own package, so a package backup can be done at this step (assuming a proper floppy is in the drive).


7) The interface "triggers" one or more system events by calling trig with the name of the event and optional parameters.

A plausible set of events for this example is probably: update_interface_config update_dns_config update_routing_table_config update_smtp_config update_ntp_config update_firewall_config

Or am I being too granular at this stage? Possibly you have in mind something more like:

        update_interface_config
                update the interface table and reconfigure the interface
                (if DHCP or PPPoE) update and restart the needed daemon
                update the routing table
                restart the firewall so it uses the new external values
        update_dns_config
                update /etc/resolv.conf
                update dnscache configuration (and re-HUP?)
        update_ntp_config
                update the servers list used by ntpdate and re-HUP the app

where the entries under each event are rough sketches of the scripts that event would run.

8) Trig runs the scripts that have "registered" for that event (by dropping themselves into the proper directory). The sequencing of this execution is controlled via leading index numbers (think SysV init scripts).

I assume the events themselves also run in a controlled order. In the first version above, update_interface_config has to run before update_firewall_config (for example). In the second version, it is probably not important what order the events themselves run in.


9) Each script decides for itself what needs to be done on each system event. Generally, this will involve reading the new values from cdb, rewriting its configuration files using the new values, then restarting or otherwise re-initializing itself

OK. Now the only way to read values from cdb is as "name=value" pairs, same as in step 3. Right?


10) If any trigger fails, the cdb is rolled back to a sane state and the trigger is fired again, restoring the system to its previous state.

Here I'm lost. Passive voice is the weakness here. Something has to do the "roll back to a sane state" part, and it's not clear from context what part of the system makes the decision to do so and initiates the action. We have at this point the individual scripts, the trig glue app, and the UI itself all running.


What constitutes "fails" isn't as obvious as it might sound like. Nor is "sane state". I see why you were vague; this is messy and needs serious thinking.

11) The interface displays either an error or success message. On success, the user is presented with a page offering to back up the system to the boot media thus preserving the state of the system across reboots.

My preference would be always to back up the system (or at least the cdb package) as part of a commit. Both approaches have their strengths and their defects ... probably ovbious to anyone interested in this thread ... so just listing the strengths of one and the defects of the other doesn't help much. On balance, I think prompt backup is more familiar to users, especially inexperienced ones, so that's why I favor it.


If the required backup medium is not present, the interface should alert the user to the omission. Other than that, the interface should probably say something like "Change Complete" or "Change Failed", with some provision for providing extra information in the failure case.

Now, that is what is in my head, but as you can see, there are several points of contention that need to be discussed thoroughly. But, none of the points of contention have anything to do with the design of the backing store model.

Well ... let me raise one. It appears that cdb accepts input in the form name=value, and it delivers output in the form name=value. What benefit is there from it having a different internal storage method?


The natural reply (natural in any object-oriented context, anyway) is, in part, what harm is there? In the context of LEAF, the possible harm is added space requirements. The 3 scripts plus a typical cdb data file are small, but with LEAF, every byte counts, so it's reasonable to ask if the proposed approach takes up unneeded space.

Frankly, it is a very small part of the overall design and, while cdb may not be perfect, it does work, quite well in fact, and it is done. I say we all take a look at it, stamp it with approval or disapproval, and move on to more pressing questions, like when to back up changes and how the hell to write a full-featured templating system in the 92k stripped down /bin/sh from Oxygen!

Despite the aside above, I actually agree with Chad. Aside from the bugfix level, let's move on. That's why I interpolated an extended example above, to help me (and possibly others) think about these interface and higher-level design issues.






-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com


_______________________________________________
leaf-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/leaf-devel

Reply via email to