$darkmode
Elektra 0.11.0
|
From the beginning of the Elektra Initiative, Elektra aimed at avoiding hard coded information in the application and to make the application's configuration more transparent. While avoiding any paths to files was reality from the first released Elektra version, now also hard coding default values, fallback mechanisms and even Elektra’s paths to keys can be avoided.
Elektra 0.8.11 introduces a so-called specification for the application's configuration. It is located below its own namespace spec
(next to user and system).
Once the base path is known, the user can find out all Elektra paths used by an application, using:
Keys in spec
allow us to specify which keys are read by the application, which fallback it might have and which is the default value using metadata. The implementation of these features happened in ksLookup
. When cascading keys (those starting with /
) are used following features are now available (in the metadata of respective spec
-keys):
override/#
: use these keys in favor of the key itself (note that #
is the syntax for arrays, e.g. #0
for the first element, #_10
for the 11th and so on)namespace/#
: instead of using all namespaces in the predefined order, one can specify which namespaces should be searched in which orderfallback/#
: when no key was found in any of the (specified) namespaces the fallback
-keys will be searcheddefault
: this value will be used if nothing else was foundThis technique does not only give you the obvious advantages, but also provides complete transparency how a program will fetch a configuration value. In practice that means that:
will give you the exact same value as the application uses when it lookups the key promise
. Many if
s and hard coded values are avoided, we simply fetch and lookup the configuration by following code:
We see in that example that only Elektra paths are hard coded in the application. But those can be found out easily, completely without looking in the source code. The technique is simple: append a logger plugin and the KDB base path is printed to:
What we do not see in the program above are the default values and fallbacks. They are only present in the so specification (namespace spec
). Luckily, the specification are key-value pairs, too. So we do not have to learn something new, e.g. using the ni plugin we can specify:
spec/sw/app/#0
we specify, that for the key /sw/app/#0/promise
only the namespace user
should be used./somewhere/else
is present, we will use this key instead. The fallback
technique is very powerful: it allows us to have (recursive) links between applications. In the example above, the application is tricked in receiving e.g. the key user/somewhere/else
when promise
was not available.20
will be used as default, even if no configuration file is found.Note that the fallback, override and cascading works on key level, and not like most other systems have implemented, on configuration file level.
The specification gives the namespaces clearer semantics and purpose. Key names starting with a namespace are connected to a configuration source. E.g. keys starting with:
user
are keys from the home directory of the current usersystem
are keys from the /etc
directory of the current systemspec
are keys from the specification directory (configurable with KDB_DB_SPEC
, typically /usr/share/elektra/specification
)When a key name starts with an /
it means that it is looked up by specification. Such a cascading key is not really present in the keyset (except when a default value was found). They are neither received nor stored by kdbGet
and kdbSet
.
Applications shall only lookup using cascading keys (starting with /
). If no specification is present, cascading of all namespaces is used as before.
Elektra will (always) continue to work for applications that do not have a specification. We strongly encourage you, however, to write such a specification, because:
For a tutorial how to actually elektrify an application and for more background to Elektra, read this document.
For a full list of proposed and implemented metadata, read this document.
As it turned out the concept of very granular merge strategies was hard to understand for users of the three-way merging framework that emerged in the last year's GSoC. While this granularity is desirable for flexibility, we additionally wanted something easy to use. For that reason merge configurations were introduced. These are simply preconfigured configurations for a merger that arrange required strategies for the most common merging scenarios. Especially they make sure that meta merging is handled correctly.
Have a look at the changes in the example /src/libs/tools/examples/merging.cpp for an glimpse of the simplifications.
A big thanks to Felix Berlakovich!
The header files will be installed to /usr/include/elektra/merging, but they are subject to be changed in the future (e.g. as they did in this release).
From the merging improvements some minor incompatibility happened in kdb import
. Not all merging strategies that worked in 0.8.10 work anymore. Luckily, now its much simpler to choose the strategies.
The main API kdb.h has two added lines. First a new method was added:
This method is already used heavily in many parts. Contrary to keySetBaseName
and keyAddBaseName
it allows us to extend the path with more than one Element at once, i.e. /
are not escaped.
The other new line is the new enum value KEY_FLAGS
. This feature allows bindings to use any flags in keyNew without actually building up variable argument lists. (Thanks to Manuel Mausz)
As always, API+ABI is stable and compatible.
Many new functions are proposed and can be found in the doxygen documentation and in kdbproposal.h.
Noteworthy is the method keyGetNamespace
which allows us to query all namespaces. Since this release we changed every occurrence of namespaces (except documentation) with switch-statements around keyGetNamespace
. This allows us to add new more namespaces more easily. (Although its currently not planned to add further namespaces.)
Finally, a bunch of new lookup options were added, which might not be useful for the public API (they allow us to disable the specification-aware features mentioned in the beginning).
The concept that backends have a name (other than their mountpoint) is now gone. Backends will simply be named with their escaped mountpath below system/elektra/mountpoints without any confusing additional name.
Unmounting still works with the mountpath.
Removing this concept makes Elektra easier to understand and it also removes some bugs. E.g. having mountpoints which do not differ except having a _
instead of a /
would have caused problems with the automatic name generation of Elektra 0.8.10.
Old mountpoints need to be removed with their 0.8.10 name (_
instead of /
).
Additionally, the so-called directory keys were also removed. Elektra was and still is completely key-value based. The /
separator is only used for mountpoints.
The plugin fstab is also improved: Slashes in mountpoints are escaped properly with the internal escaping engine of keyAddBaseName() (i.e. without any problematic /
replacements).
getDirName() was removed from C++, gi-lua, gi-python2, gi-python3, swig-lua, swig-python2 and swig-python3. It was never present in C and did not fit well with keyBaseName() (which returns an unescaped name, which is not possible for the dirname). (Thanks to Manuel Mausz)
While empty (=invalid) names are still accepted as parentName to kdbGet
and kdbSet
for compatibility reasons, but the parentKey
should be used instead (if you want to get or store everything). They have identical behavior, except that invalid names (that cannot be distinguished from empty names) will produce a warning. In the next major version invalid parentNames will produce an error.
It is now enforced that before a kdbSet() on a specific path a kdbGet() on that path needs to be done. This was always documented that way and is the only way to correctly detect conflicts, updates and missing configuration files. Error #107 will be reported on violations.
Additionally, the handling with missing files was improved. Empty keysets for a mountpoint now will remove a file. Such an empty file is always up-to-date. Removing files has the same atomicity guarantees as other operations.
The concurrency behavior is at a very high level: as expected many processes with many threads can each concurrently write to the key database, without any inconsistent states: This is noted here because Elektra works on standard configuration files without any guarding processes.
Filesystem problems, e.g. permission, now always lead to the same errors (#9, #75, #109, #110), regardless of the storage plugin.
Raffael Pancheri was very busy and did a lot of stabilizing work:
The gui is already used and the remaining small bugs (see github) are going to be fixed soon. One of the highlights is undo for nearly every action, so nothing prevents you from trying it out!
A huge thanks to Raffael Pancheri for his contributions. His thesis can be found at here.
kdb getmeta
reports errorcode if key, but no meta was foundksLookup
now will also work if a key of the keyset is used as search-key (aliasing problem fixed by dup() on namelock)$RANDOM
)CMAKE_DL_LIBS
(thanks to Manuel Mausz)add_plugin
(thanks to Ian Donnelly for most of the work)keyName
methodssystem/elektra/mountpoints
itself was always created and a left-over on a freshly installed system after the unit tests run the first time. The physical presence of the key is now irrelevant and it won't be created automatically.kdb list-tools
is now advertised in kdb --help
With 471 files changed, 27978 insertions(+), 11512 deletions(-) this release is huge. With 773 commits over four month much more changes happened which did not find their place in these release notes, even though the notes are much less detailed than usual.
Thanks for all contributions that are not enlisted here!
For any questions and comments, please contact the Mailing List or elekt. ra@m arkus -raa b.org
You can download the release from here
This release tarball now is also available signed by me using gpg
already built API documentation can be found here
Subscribe to the new RSS feed to always get the release notifications.
For more information, see https://www.libelektra.org
Best regards, Markus