|
Elektra
0.8.19
|
Configuration in FLOSS unfortunately is often stored completely without validation. Notable exceptions are sudo (sudoedit), or user accounts (adduser) but in most cases you only get feedback of non-validating configuration when the application fails to start.
Elektra provides a generic way to validate any configuration file before it is written to disc.
Any of Elektra's user interfaces will work with the technique described in this tutorial, e.g.:
1.) kdb qt-gui: graphical user interface
2.) kdb editor: starts up your favourite text editor and allows you to edit configuration in any syntax. (generalization of sudoedit)
3.) kdb set: manipulate or add individual configuration entries. (generalization of adduser)
4.) Any other tool using Elektra to store configuration (e.g. if the application itself has capabilities to modify its configuration)
The most direct way to validate keys is
For all other plugins (except validation) the convenience tool kdb vset is missing. Let us see what kdb vset actually did:
So it only appended some metadata (data describing the data) next to the key, which we also could do by:
The approach is not limited to validation via regular expressions, but any values-validation plugin can be used, e.g. enum. For a full list refer to the section "Value Validation" in the list of all plugins.
Note that it also easy to write your own (value validation) plugin.
The drawbacks of this approach are:
check/validation) needs to be stored next to the key which won't work with most configuration files. This is the reason why we explicitly used dump as storage in kdb mount.vset was used. In the example above we could override the cascading key /tutorial/together/test with the unvalidated key dir/tutorial/together/test.These issues are resolved straightforward by separation of schemata (describing the configuration) and the configuration itself. The purpose of the spec namespace is to hold the schemata, the description of how to validate the keys of all other namespaces.
To make this work, we need a plugin that applies all metadata found in the spec-namespace to all other namespaces. This plugin is called spec and needs to be mounted globally (will be added by default with kdb global-mount):
Then we can write metadata to spec and see it for every cascading key:
But it also supports globbing (_ for any key, ? for any char, [] for character classes):
So let us combine this functionality with validation plugins. So we would specify:
Alternatively, we could mount a plugin that supports metadata, e.g. the ni plugin, and specify the configuration using a text editor (or cat):
```
kdb mount spec.ini spec/tutorial/spec ni cat << HERE >
kdb file spec/tutorial/spec
[test] check/validation = [1-9][0-9]* check/validation/match = LINE check/validation/message = Not a number HERE
kdb lsmeta /tutorial/spec/test
check/validation check/validation/match check/validation/message
kdb setmeta spec/tutorial/spec mountpoint spec-tutorial.dump kdb spec-mount /tutorial/spec kdb set /tutorial/spec/test wrong
Using name user/tutorial/spec/test Error (#42) occurred! Description: Key Value failed to validate Reason: Not a number
kdb setmeta /tutorial/spec/should_not_be_here trigger/error 10 kdb spec-mount /tutorial/spec kdb set /tutorial/spec/should_not_be_here abc
Error (#10) occurred!
kdb get /tutorial/spec/should_not_be_here
Did not find key
cat > $PWD/schema.txt << HERE %: notation TBD ? graph text semi %: tool-support* TBD ? none compiler ide %: applied-to TBD ? none small real-world mountpoint file.txt plugins required HERE
kdb mount $PWD/schema.txt spec/tutorial/schema simplespeclang keyword/enum=%:,keyword/assign=TBD kdb spec-mount /tutorial/schema ```
We configure the plugin simplespeclang so that it conforms to our "weird" syntax. Because in schema.txt we have the line mountpoint file.txt we can also mount the schema using spec-mount.
Now we have enforced that the 3 configuration options notation tool-support* applied-to need to be present (and no other). For example we can import:
Or (afterwards) setting individual values:
Or (in sudoedit fashion):
1.8.11