config system thoughts




Any comments on this? It's a bit of a work in progress. Not sure if I'm
going to code it or not yet.


GConf design notes
==================

Data Types
===

Must be able to store int, float, string. Also need a "record" or
"struct" type, to store something like a printer; record has a fixed
set of names and fixed types for the value at each name.  There are
four list types, containing each of the four basic types.

Should lists of lists be allowed? Probably so, since you can do this
via a record type anyway (a record containing a list) so it may as
well be allowed in a non-ugly way.

Namespace
===

Is a fully hierarchical namespace (filesystem-style) really required?

I think no. If you have simply two levels, a per-vendor and
per-application namespace, plus lists/records, I think that's
fine. And it reduces the complexity of backend implementations and the
API quite a bit.

So every actual key-value pair would be stored under
/vendor/appname/key. Remember that values can be "records," giving you the
equivalent of a "section" in gnome-config.

Most existing applications with roll-your-own config solutions have a
basically flat namespace like this. gnome-config does too.
So there's little evidence that the hierarchical space is useful IMO.

Config Sources
===

A config source is something like a URL. It has two parts: a "protocol"
(backend), such as Berkeley DB, flat text file, Oracle, LDAP; and an
"address", which is a backend-specific string sufficient to locate the
particular config source. Could be a hostname, filename, directory
name, whatever makes sense.

Each config source can respond to queries for any /vendor/appname/key
values, if only with "no value set."

Sources can be read-only or read-write with respect to a given user. 
If a config value is taken from a read-only source, then applications
will need to desensitize the widgets used to modify that value.

On the implementation side, backends will probably be implemented as
loadable modules.

Source Layering
===

Config sources can be layered in a search path. For example, you might
configure your GConf to first check your user settings stored in flat
files in ~/.gconf, then the systemwide Berkeley DB in /etc/gconf, then
the network-wide LDAP configuration.

System or network administrators can place a read-only config source
at the beginning of your source search path. If the read-only source
sets a value, then users can't modify it. (This is not intended to be
a security measure, just a way to keep users from shooting themselves
in the foot; you might lock IP addresses in place, for example, if
users shouldn't be changing them.)

Layering can be for the entire namespace or you can "mount" a
particular source only for a particular application.

There will be a master repository that stores metadata and information
about the layers. Most likely this will be concealed by the API.

Packages (debs/rpms) can also install a layer of defaults if they
like, and uninstall the layer when the package is uninstalled.

Notifier/Listener architecture
===

Apps should be able to register themselves as listeners for a given
section of the namespace, to be notified whenever a config value in
that namespace changes.

A simple way to structure applications would listen for config
changes; then when the app saves its own config, it gets a change
notification back and updates itself. The app's internal config
updating works as if an external tool or another instance of the app
had changed the config; external changes are treated exactly the same
as internal ones.

This is the hardest thing to implement, it will require some kind of
daemon and there are serious security issues to work out. This is the
main problem I'm not sure how to approach.

We should have a nice GtkObject convenience layer to make it easy to
implement this.

Locking
===

Obviously the backends should have locking so multiple apps can edit
the same key if needed.

Key Metadata
===

Each key must be explicitly registered with the GConf system; on
registration, a short and long description of the key's purpose should
be stored. Also the key's type. It will then be an error to store the
wrong type in that key. The description can be used in generic config
tree browser/editor applications.

Metadata will also include the time of the last change, and an
arbitrary string identifying the software or person who made the
change. Packages (deb/rpm) can use this to decide whether a key has
been modified since the package was installed. (Is this necessary? We
could simply say that the source layer installed by the package is
never modified, instead administrators would add an additional layer
overriding it.)

Record Metadata
===

Record types are similarly pre-registered, along with descriptive
metadata. Record types are referred to by name.

Record types are stored in the namespace; unlike keys, they can be
under a vendor name only, instead of a vendor-appname pair. But they
can also be under the appname if they are application-specific.

Global record types are also allowed, but normally should not be created.

Conventional Types
===

This is why global record types are allowed.

In addition to the primitive types, customary record types will be
specified. For example, a record with four integers for an IP address.
Some standard document will list the conventional types defined so
far. The purpose of conventional types is compatibility, and so
generic browser/editor apps can impose nice constraints on the value
of the record members (such as 0-255 for each int in the IP address) -
a Windows-style IP address entry box could be used.

Conventional types will be ever-present and defined as global record
types, since they aren't "owned" by any vendor or application.

Iterators
===

You have to be able to iterate over everything: keys, appnames,
vendors, record types, etc. in order to implement generic
browser/editor applications

Data Size Limit
===

An arbitrary limit on the size of stored strings, lists, etc. should
be enforced; the config engine is not meant to be used as a file
format, and won't be efficient enough to shovel lots of data around.

Command line tool
===

A nice command line tool will be written to allow shell scripts to
access config information. This is important for postinstalls and the
like.

So you'd say:

gconf --set key value

gconf --get key

gconf --clear /vendor/appname/key

gconf --list-sources

etc., something like that

The command line tool is also useful for writing a test suite.

What to do with gnome-config
===

gnome-config should remain unchanged for backward compatibility and
stability; apps would gradually migrate to the new GConf API. I don't
think it's feasible to implement gnome-config in terms of this more
powerful system without breaking the more powerful system.

Convenience stuff that we might have
===

Enumeration handling; load/save enumeration values as strings in a
robust way.

ChangeSet with commit/undo capability: you should be able to assemble
a set of changes and save them as a whole, then "revert" that set of
changes. GConf should handle all this automatically. Combined with the
notifier/listener application structure, this means apps will get
"revert" capabilities for free; this allows us to move from
GnomePropertyBox to a more powerful config model.

Magic widgets associated with a GConf key and a ChangeSet; the widgets
would automatically be insensitive if a read-only source was before
all writable sources in the search list, and they would register as a
listener to automatically update if the conf value changed.


Issues
===

The source layers, multiple sources, and notifier/listener setup
create all kinds of implementation complexity and security issues. 
I'm not sure all of them are even possible to address. 

However the functionality gain is genuine, so it's worth considering
at least.








[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]