Elektra
0.8.19
|
Elektra provides a global key database, that can integrate configuration in various formats.
Conversely configuration managed by Elektra can be integrated into applications. The best way of integrating Elektra into applications is to elektrify them.
A simpler form of integration is to let Elektra directly use configuration files as they are present on the system. Thus applications can read the configuration files and changes in the key database will be picked up by applications.
The heart of the approach is the so called mounting of configuration files into the key database.
Let us start with a motivating example first:
We mount the lookup table with the following command:
``` sudo kdb mount –with-recommends /etc/hosts system/hosts hosts ```
/etc/hosts
is the configuration file we want to mountsystem/hosts
is the path it should have in the key database, also known as mountpointhosts
is the storage plugin that can read and write this configuration format.Consider using mount with the option
--with-recommends
, which loads all plugins recommended by the hosts plugin. You can see the recommended plugins of hosts if you look at the output ofkdb info hosts
. Hosts recommends the glob, network and error plugins. Using--with-recommends
, more validation is done when modifying keys insystem/hosts
.
Now we use kdb file
, to verify that all configuration below system/hosts
is stored in /etc/hosts
:
``` $ kdb file system/hosts /etc/hosts ```
After mounting a file, we can modify keys below system/hosts
. We need to be root, because we modify /etc/hosts
.
$ sudo kdb set system/hosts/ipv4/mylocalhost 127.0.0.33
These changes are reflected in /etc/hosts
instantly:
$ cat /etc/hosts ... mylocalhost 127.0.0.33 localhost ...
Applications will now pick up these changes:
$ ping mylocalhost
We are also safe against wrong changes:
``` kdb set system/hosts/ipv4/mylocalhost ::1
kdb set system/hosts/ipv4/mylocalhost 300.0.0.1
```
We can undo these changes with:
```
sudo kdb rm system/hosts/ipv4/mylocalhost
sudo kdb umount system/hosts ```
Why do you need superuser privileges to mount files?
Elektra manages its mountpoints in configuration below system/elektra/mountpoints. The file that holds this configuration is, in the same way as
/etc/hosts
before, only writable by administrators:$ kdb file system/elektra/mountpoints /etc/kdb/elektra.ecfBecause of that only root can mount files.
The configuration file path you supplied to kdb mount
above is actually not an absolute or relative path in your filesystem, but gets resolved to one by Elektra. The plugin that is responsible for this is the _Resolver_.
When you mount a configuration file the resolver first looks at the namespace of your mountpoint. Based on that namespace and if the supplied path was relative or absolute the resolver then resolves the supplied path to a path in the file system. The resolving happens dynamically for every kdb
invocation.
You can display the mounted configuration files with kdb mount
. Also here you only see the unresolved paths.
If you supplied an absolute path (e.g. /example.ini
) it gets resolved to this:
namespace | resolved path |
---|---|
spec | /example.ini |
dir | ${PWD}/example.ini |
user | ${HOME}/example.ini |
system | /example.ini |
If you supplied a relative path (e.g. example.ini
) it gets resolved to this:
namespace | resolved path |
---|---|
spec | /usr/share/elektra/specification/example.ini |
dir | ${PWD}/.dir/example.ini |
user | ${HOME}/.config/example.ini |
system | /etc/kdb/example.ini |
If this differs on your system, the resolver has a different configuration. Type kdb info resolver
for more information about the resolvers.
There are different resolvers. For instance on non-POSIX systems paths must be resolved differently. In this case one might want to use the wresolver plugin. Another useful resolver is the blockresolver, which integrates only a block of a configuration file into Elektra.
But resolvers are not the only plugins Elektra uses:
Configuration files can have many different formats (ini, json, yaml, xml, csv, ... to name but a few).
One of the goals of Elektra is to provide users with a unified interface to all those formats. Elektra accomplishes this task with storage plugins.
In Elektra Plugins are the units that encapsulate functionality. There are not only plugins that handle storage of data, but also plugins that modify your values (iconv). Furthermore there are plugins that validate your values (validation, enum, boolean, mathcheck, ...), log changes in the key set (logchange) or do things like executing commands on the shell (shell). You can get a complete list of all available plugins with
kdb list
. Although an individual plugin does not provide much functionality, plugins are powerful because they are designed to be used together.
When you mount a file you can tell Elektra which plugins it should use for reading and writing to configuration files.
Let us mount a projects git configuration into the dir namespace:
# create a directory for our demonstration mkdir example && cd $_ # this creates the .git/config file git init # mount gits configuration into Elektra sudo kdb mount /.git/config dir/git ini multiline=0
As git uses the ini format for its configuration we use the ini plugin. You can pass parameters to plugins during the mount process. This is what we did with multiline=0
. Git intends the entries in its configuration files and the default behaviour of the ini plugin is to interpret these indented entries as values that span mutiple lines. The passed parameter disables this behaviour and makes the ini-plugin compatible with git configuration.
Now let us see how smoothly the ini plugin sets and gets the git configuration.
# set a user name ... git config user.name "Rob Banks" # ... and read it with kdb kdb get dir/git/user/name Rob Banks # set a user email with kdb ... kdb set dir/git/user/email "rob.banks@dot.com" # and read it with git git config --get user.email rob.banks@dot.com
Elektra is able to store meta data of keys, provided the format of the file that holds the configuration supports this feature. The ini plugin doesn't support this feature, but the ni and the dump plugin do.
> Actually the ini plugin creates some metadata on its own. This metadata contains information about the ordering of keys or comments, if a key has some. > But unlike the ni and the dump plugin we can't store arbitrary metadata with the ini plugin.
Meta data comes in handy if we use other plugins, than just the ones that store and retrieve data. I chose the ni plugin for this demonstration, because it supports metadata and is human readable. So let us have a look at the enum and mathcheck plugins.
# mount the backend with the plugins ... $ sudo kdb mount example.ni user/example ni enum # ... and set a value for the demonstration $ kdb set user/example/enumtest/fruit apple Create a new key user/example/enumtest/fruit with string apple
By entering kdb info enum
in the commandline, we can find out how to use this plugin. It turns out that this plugin allows us to define a list of valid values for our keys via the meta value check/enum
.
$ kdb setmeta user/example/enumtest/fruit check/enum "'apple', 'banana', 'grape'" $ kdb set user/example/enumtest/fruit tomato # this fails because tomato is not in the list of valid values
You can have a look or even edit the configuration file with kdb editor user/example ni
to see how the value and metadata is stored:
enumtest/fruit = apple [enumtest/fruit] check/enum = 'apple', 'banana', 'grape'
I hope with this examples it became clear how useful plugins can be. But in the example there is one issue: the configuration file is now changed in ways that might not be acceptable for applications. We have at least two ways to avoid that:
spec
namespace, completely separate to the configuration files the application will seeIf you want to find out more about validation I recommend reading this tutorial next.
The plugins together with the configuration file form a backend. The backend determines how Elektra stores data below a mountpoint. You can examine every mountpoints backend by looking at the configuration below system/elektra/mountpoints/<mountpoint>/
.
One drawback of this approach is, that an application can bypass Elektra and change configuration files directly. If for example Elektra is configured to validate new configuration values before updating them, this is something you do not want to happen.
Another drawback is that mounting is static. In a previous example we mounted the /.git/config
file into dir/git
. Now the dir
namespace of every directory stores the configuration below dir/git
in this directories /.git/config
file. And this mountpoint is the same for all users and all directories. So you can't have different configuration files for the same mountpoints in other directories. Because of the same reason you cannot have different configuration file names or syntax for the same mountpoint in the user
namespace.
This is one of the reasons why Elektra promotes this naming convention for keys: > Key names of software-applications should always start with: > /<type>/<org>/<name>/<version>/<profile>
> - type can be sw
(software), hw
(hardware) or elektra
(for internal configuration) > - org is an URL/organisation name. E.g. kde
> - name the name of the component that has this configuration > - version is the major version number. E.g. If you version is 6.3.8 than this would be #6
> - profile is the name of the profile to be used. E.g.: production
, development
, testing
, ...
Furthermore, one cannot simply change the configuration file format, because it must be one the application understands. Thus one loses quite some flexibility (for instance if this file format doesn't support meta keys, as already mentioned).
These limitations are the reasons why elektrifing applications provides even better integration. Go on reading how to elektrify your application.