|
From: kris m <kr...@ev...> - 2002-02-19 13:46:40
|
> I suggested before that I think the config file modifying program > should be a separate program[1] which can be invoked from the > command-line instead. If we have this, then rsh and ssh would be plenty > good enough for connecting to a remote host to run commands. This makes > things much more simple and easy and secure. It works well for CVS. And > we don't have to reinvent half of ssh and link against SSL, PAM etc. It > is sticking to the UNIX philosophy of doing one thing only but doing it > well. I totally agree that we should only do one thing, and obviously do it well. At the bottom of this message, I've inlined [2] a basic spec for the communications library, as it is currently proposed. Doing it in this manner reduces our need to reinvent the wheel - we can easily tunnel through SSH; if a module wants to link with SSL or PAM, it's more than welcome to. To summarize: the daemons and clients are completely shelterd from the actual details of communications by 'commlib'; commlib generalizes i/o to the point that the modules can handle the actual hard details. For starters, there is of course, a (non-blocking [1]) sockets module planned. > If you imagine an action such as changing a user (such as with > usermod), it would be useful to bring up on screen the user's current > details when prompting the user for new details. Also, for some of the > fields such as group membership, we would want to provide a list of all > possible groups. When making a change across multiple hosts, you would > have to contend with this information being different on different > machines. It'd make things simpler to just take the information from a > single machine (by default the local one). If applying the change on a > remote host produces an error, then we have to display the error (shell > scripts should be run with the -e (exit on error) option). Of course, modules could be flagged as 'safe' for master/slave execution. In the case of a user manager, it's simply not sensical to allow this ability. (Personally, I can't think of a case where it's possible usefullness outweighs it's possible security risk. If you can, *post to the list*. :grin: ) > [1] as an initial rough design for this program, it could have modules > for various generic config file styles (such as .ini (e.g smb.conf), > .xml, fixed character separated lists (e.g. /etc/passwd), assignment > lists (e.g. wgetrc)). The modules would provide an abstract interface > to the config file format mapping them into an XML like structure. We > could then use something like XSLT matching syntax to specify the > changes. So for smb.conf, you might match the [global] section, select > the workgroup key and change it's value. Everything else gets copied > as-is. For programs with simple config files, we'll perhaps be able to > use sed or awk instead of the new command. Initially, it might be > better to stick to existing UNIX commands and come to this when we need > it. We're having a 'nomenclature-clash'; laugh; when I say modules, I mean loadable units of code. While I admire the the layout you envision.. For example, the actual configuration tool then needs to handle parsing, reading and writing of these files /etc/passwd, and it becomes very platform dependent on the format of them. (i.e. RedHat 7.2 using /etc/X11/... and BSD 4.5 using /etc/XF86Config... no, it's *not* just the X versioning issue.) Also, if the modules were just .xml files, they couldn't handle advanced creation of configurations; imagine a module that configures XFree86. > To outline my ideas for the main config tool: There would be a > directory structure containing .xml files. So this directory might > contain a Networking directory which might include dns.xml routing.xml > ppp.xml bind.xml. The directory structure could be more than one level > deep. Individual directories and files here could be removed or added. > Symbolic links could be used so that for example, NFS configuration > might be under both networking and file systems. And as I suggested > before an environment variable would list directories to search for > these files. I like and agree with the directory layout; it could be done similarly for loadable modules. > Individual .xml files would look a bit like an HTML form but more > complex. An input field might specify a shell script which if run would > generate a list of possible values. So if you want to delete a print > queue, it could generate a list of print queues to prompt you with. > When you submit changes, it would again have a shell script to run. m4 > preprocessing this shell script would make it possible to make the > script minimal and to insert the user-entered values into the script. See Bill's mod_api initial spec also inlined [3] below. > You may have already decided on this but I would suggest that > everything supports unicode from day one. Unfortunately, I don't know > much about it. Since we're starting a clean code base, and *you* suggested it, .. grin, I have no problem with it, and it's a really good idea. Who wants figure it out? I'll play with it if I get time later today. > I'm not too sure that I like the program's name. I tend to prefer > natural language words (not necessarily English) to vowel-less > acronyms. Another suggestion is that the project is moved from > Sourceforge to GNU's Savannah. I'm not 100% happy with the new > Sourceforge terms. It'd give us a higher profile with the FSF and > improve chances of becoming official GNU. Being officially part of GNU > would help a lot in making the project successful (plenty of GNU > projects do better than superior alternatives). As for the name, we were short on time. :-) I'll check out Savannah today, any thing other than sf.net I'm likely to be happy with. ;-) (Ask bill, i've been bitching about it since day one :wink:) [1] non blocking because it just doesn't make sense to block; other communications means might not block (imagine reading from a script file as a communication means...); in the proposed spec, the command structure would report a value similar to "no data ready" [2] COMMUNICATIONS API <kr...@ev...> ------------------------------------------- - Things that need the ability to communicate - client & server - server::master & server::slave - Provides C and C++ interfaces. "Transport"* layers are provided by loadable modules. - Commlib will initially include transport layers for sockets, sockets tunneled via SSH, and IPC. More to come later, including SSL. - commlib will read it's configuration (in the server context that is) and allow/disallow connections at that level; it takes the responsbility away from the server/client, and disables an errant client/server from accidentally getting permission. - commlib will ABSOLUTELY NEVER BLOCK. * In this context, meaning such as sockets, ssh tunnelling, serial line, ... API: // general int comm_query_transport_types((void* callback_fnc)(char *name, struct_describe)); // struct_describe contains detailed information // on that transport layer; presentation name, // version, ... etc // client side int comm_open_connection("hostname"); comm_read_command(con,&cmd); // command structure - will not block comm_send_command(con,&cmd); // has an int specifiying the type of command comm_close_connection(int con); // server side int comm_server_startup("hostname"); // interface to accept connections on; NULL for lo int comm_accept_connection(); // accepts the current incoming connection // never blocks; int comm_close_connection(int conn); // [3] mod_api spec: Hrmm... well the basic idea is this: -Each module gets "registered" with the server. -Each function that you will want to be able to execute from the client also gets "regitered". That way, when you need to kick off a function on the server from the client, it sends the module name, function name, and function arguments over the wire. A service in the server will take this information, look up the correct function, and kick it off with the arguments. For now, the "arguments" will be a null terminated char*, and the function will need to "decode" this into individual arguments. Here's some ideas for solutions to this: 1. Each registered function will have a "helper" function which decodes the arguments and passes back the proper data types. 2. The client passes the data in xml format, which the server decodes, thus passing the function the proper arguments... here's an example: ---Begin data coming in from the client--- <execute mod="user_config" function="add_user"> <uint32>502</uint32> <char_ptr>bill</char_ptr> <char_ptr>/home/bill</char_ptr> <uint32>502</uint32> <uint32>100</uint32> </execute> ---End data coming in from the client--- The server would get this, cast the various types, lookup the module and function, and then call the function something like this: t_module *module; t_function *function; uint32 arg1, arg4, arg5; char *arg2, *arg3; module=module_lookup(master_mod_list, "user_config"); function=function_lookup(module, "add_user"); arg1=cast_uint32(args, 1); arg2=cast_char_ptr(args, 2); arg3=cast_char_ptr(args, 3); arg4=cast_uint32(args, 4); arg5=cast_uint32(args, 5); *(function)(arg1, arg2, arg3, arg4, arg5); |