#
# SpecElektra is a specification language that describes content
# of the global key database.
#
# SpecElektra does not have built-in keywords, instead it is
# completely extensible by metadata interpreted by Elektra's plugins.
#
# Any of Elektra's supported configuration formats that are able
# to write metadata can be used for SpecElektra.
#


#
# This document describes all metadata and specification values available
# in SpecElektra.
#
# If your plugin/tool/API uses metadata, please add it here.
#
# Some parts of this file are already used by tools
#
# 1. It can be mounted with the ni and ini plugin, see scripts/mount-info and below
# 2. It is checked for consistency with contracts of plugins, see
#    tests/shell/check_meta.sh
#

#
# METADATA.ini meta-specification (description how to parse/use this file):
#
# [the name of the metakey]
# type= (<CORBA type>|enum <enum>|regex <regular expression>) the type of the metavalue
# status= (implemented|proposed|idea|deprecated|unclear) the current state of this metadata entry
# usedby/api= the API methods which use the metakey (space separated)
# usedby/plugin= the plugins which use the metakey (space separated)
# usedby/tool= the tools which use the metakey (space separated)
# description= explains what the metadata is about
# note= give additional notes for that metakey
# example= give additional examples how the metakey might look like
#
# To mount this file you can use:
#
#  kdb mount-info
#
# To get a metavalue, use:
#
#  kdb get system/info/elektra/#0/metadata/ni version/major
#  kdb getmeta system/info/elektra/#0/metadata/ni version/minor
#  kdb getmeta system/info/elektra/#0/metadata/order type
#

[]
filename=METADATA.ini
version/major=0
version/minor=5


#
# Important metadata often used in configuration files
# (and seldom in specifications)
#

[order]
type= int
status= implemented
usedby/plugin= hosts augeas ini
usedby/api= elektraKeyCmpOrder
description= relative order in the keyset if non-alphabetical order
	is needed. This metadata is only to preserve order as found in
	the file. It is an hint to allow complete reconstruction as it
	was before.
	Keys without order metadata or keys with same order, yield
	implementation-defined ordering.
	When some knowledge about desired ordering exists, e.g. when
	key sets are merged, the keys should to be reordered to avoid
	this.
note= this will rarely used within specifications, but is directly
	derived from configuration files.
	I.e. only storage plugins set and get this property.

[comment]
type= string
status= deprecated
usedby/plugin= keytometa
description= the users comment about the key (mostly its value)
	the first line is the comment after a key-value (in the same line)
	further lines are the lines before a key-value

	This metadata is deprecated because it assumes line-based comments
	and cannot preserve formatting within comments.
note= if used within specifications it refers to the specification, not
	the key. Use `description` to refer to the key.

[comment/#]
status= implemented
usedby/plugin= hosts
type= string
description= A comment preceding or in-line with a key.

	- #0 is the inline comment (in the same line).
	- The comment numbering starts from top (#1) to bottom (#n).
	- The comment directly above the key is the last entry in the array (#n).
	- The topmost comment belonging to the key is (#1).

	Comment keys that are not above any key (comments in the last
	lines of files) are added to the parentkey.

	The array of comments allows:

	- to structure comments, which are not line-based
	- to restore formatting, including:
	 - inline comments
	 - spaces before comments
	 - empty lines
	- to distinguish between different kinds of comments
	- to tag every comment, which increases extensibility

	The plugin need to take care that only valid characters are
	present in the comment.
	E.g. on line-based comments, no newlines must be present.
note= if used within specifications it refers to the specification, not
	the key. Use `description` to refer to the key.

[comment/#/start]
status= implemented
usedby/plugin= hosts
type= string
description= Determines the character(s) used to start this comment.

	This metakey is empty if its an empty line/comment.

	The default on absence of this key is plugin-specific.
	Some comment start character should be assumed then.

	The plugin needs to make sure that every comment is actually
	commented out. An error needs to be emitted if there is no
	start symbol that will be recognized as comment.
example= ;

[comment/#/space]
status= implemented
usedby/plugin= hosts
type= string
description= The spaces/tabs used between a comment and the beginning of the
	line or after end of payload data (for inline comments).

	If no start key is present, only space and no comment is present.

	The plugin needs to make sure that all spaces present are allowed.
	An error needs to be emitted if non-ignored spaces are present.
example= 	




[line]
type= int
status= proposal
description= contains the line number from which a key was read.
note= is useful for validation problems when someone directly
	edits files



#
# Needed for specification of key access (ksLookup by spec)
#

[fallback/#]
type=key name
status=implemented
usedby/api= ksLookup
description=When a key was looked up unsuccessfully, keys in this
	array will be tried instead.

[override/#]
type=key name
usedby/api= ksLookup
status=implemented
description=Keys in this array will be preferred over the key
	itself

[namespace/#]
type=namespace
status=implemented
usedby/api= ksLookup
description=Typically all namespaces are cascaded one after the other
	in the built-in order.
	Using this metadata you can avoid that some namespaces are used or
	can change the order.

[default]
usedby/tool = web
status=implemented
usedby/api= ksLookup
description=The default value will be used if no other value could
	be found successfully.




[context]
status=implemented
usedby/api=getenv
description=use /env/layer and internal information to facilitate
	a context-aware lookup


[callback/_]
status=reserved
usedby/tool=kdb
usedby/api=getenv
description=reserved meta information that will be preserved during the whole
	chain of ksLookup() callback calls


#
# Basic information about keys
#

[type]
type= enum
	short
	unsigned_short
	long
	unsigned_long
	long_long
	unsigned_long_long
	float
	double
	long_double
	char
	boolean
	octet
	any
	empty
	string
status= implemented
usedby/plugin= type range
description= defines the type of the value, as specified in CORBA
	Unlike check/type, type is also used for code generation and within the APIs
example= any

[binary]
type= empty
status= implemented
usedby/api= keyNew keyVNew keyIsBinary keyIsString keyValue keyGetValueSize keyString keyGetString keySetString keyGetBinary keySetBinary
usedby/plugin= null
description= For this metadata only the presence is significant, not its value.
	It is used to tag binary keys. Binary keys are keys that either have no value (null keys, keyValue returns null).


[array]
type= array-index
status= proposed
description= Such keys have only keys conforming to Elektra’s arrays convention as subkeys.
	If the metavalue is empty, the array is empty (no subkeys).
	Otherwise the metavalue contains the last element.
example = #5





#
# Needed for mounting by specification
#

[mountpoint]
type=string
status= implemented
usedby/tool= mount-spec
description=indicates that the key represents a mountpoint

	the value is the filename that should be used for the configuration file
	defined by the specification
example=default.ecf


[infos]
type= string
status= implemented
usedby/tool= mount-spec
description= infos about the mountpoint

	See CONTRACT.ini for individual infos (usedby is tagged with spec).

	hint of application developer that the key actually needs
	a specific plugin (that cannot be derived by other metadata)
	"needs" means that it is semantically absolutely necessary and
	required that such an plugin exists.

	Without the plugin the application might break.
	If the plugin is optional and only nice to have, use recommends
	instead.
note=  It is generally preferred that other metadata will be used to
	deduce the needs of the specification, e.g. use check/validation
	metadata instead of as given above.

[config]
type= string
status= proposed
description= indicate that the mountpoint needs some
	configuration for plugins in order to work.

	See CONTRACT.ini for details.





#
# Needed for specification of code generation
#

[opt]
status= implemented
usedby/tool= gen

[opt/long]
status= implemented
usedby/tool= gen

[env]
status= proposed



#
# Needed for documentation
#

[see/#]
status= implemented
description = Pointer to other configuration settings which should also
	be considered to be changed if this configuration setting is changed.
usedby/tool= gen

[rationale]
status= idea
description= Information why this configuration setting exists
	and in which scenarios it should be considered to be removed

[requirement]
status= idea
description= Information based on which requirement the configuration
	setting exists. Gives hints when to reevaluate the configuration
	setting.

[description]
usedby/tool = web
description = this is information provided from the developer/maintainer
	for administrators.
	It is not written directly in the configuration files but is instead
	part of the spec-namespace.
note= For information in other namespaces, use `comment/#` instead.

[example]
usedby/tool = web
description = it is always good to have an example.
	The example is only for documentation unlike the default
	which will be used if nothing else is given.











#
# Implementations via plugins
#




#
# Information about the key's name
#

[rename/toupper]
type = string
status = implemented
usedby/plugin = rename
description = rename key name to uppercase

[rename/tolower]
type= string
status= implemented
usedby/plugin= rename
description=rename key name to lowercase

[rename/cut]
type= string
status= implemented
usedby/plugin= rename
description=cut out a common name

[rename/to]
type= string
status= implemented
usedby/plugin= rename
description=use a different name instead of the cut out name

[origname]
type= string
status= implemented
usedby/plugin= rename
description= stores the original name of the key as it was before the
	rename operation



#
# Spec Plugin
#

[conflict/_]
type = string
status = proposed
description = reports which metadata had a conflict because another
	metadata was already present before.
	Idea: use only one log, also for conflicts.

[array/range]
type = range
status = proposed
description = checks if the subkeys form a valid array and are not smaller/larger
	than as given.
example = 4-20

[require]
type = boolean
status = unclear
description = See spec plugin

[required]
type = range
usedby/plugin = required
status = unclear
description = See spec plugin
	for _ as basename as array. Otherwise the presence determines
	if a key is required.
	In process of being replaced in favor of require.

[mandatory]
type = boolean
usedby/plugin = required
status = unclear
description = In process of being replaced in favor of require.

#
# Error and Warnings
#

[error]
status = implemented
description = an error, see src/error/specification

[warnings/#]
status = implemented
description = a number of warnings, see src/error/specification




#
# Struct validation
#


[struct]
type = vector <string>
status = proposed
description = checks if the subkeys form a valid struct with the given
	names.
	The validator makes sure that there are no keys for the struct missing.
example = device mpoint type options [dumpfreq] [passno]


#
# Validation/Checks about the key's value
#

[check/type]
type= enum
	short
	unsigned_short
	long
	unsigned_long
	long_long
	unsigned_long_long
	float
	double
	long_double
	char
	boolean
	octet
	any
	empty
	FSType
	string
status= implemented
usedby/plugin= type range
usedby/tool = web
description= defines the type of the value, as specified in CORBA
	(except of 2: wchar, wstring; and 4 additions: any, empty, FSType, string).
	enum is implemented by check/enum/#
	FSType is deprecated
	
	Unlike type, check/type is *only* used for validation.
	
	Tools with support for `check/type`, should also always check for `type`.
	The type plugin prefers `check/type` if it is present.
example = any

[check/type/min]
type= int
status= deprecated
usedby/plugin= type
description= defines the min value type of the integer value
	use check/range instead

[check/type/max]
type= int
status= deprecated
usedby/plugin= type
description= defines the max value type of the integer value
	use check/range instead

[check/range]
status= implemented
usedby/plugin= range regexdispatcher
usedby/tool = web
description= range checks, from-to, multiple ranges are separated by a comma
example= 1-10 or -1-4,6-10

[check/math]
type= string
status = implemented
usedby/plugin= mathcheck
description= check if value conforms to mathematical expression

[check/ipaddr]
type= enum

	ipv4
	ipv6
status = implemented
usedby/plugin= network ipaddr
description= check if value resolves correctly to an ipaddr
	empty value uses either ipv4 or ipv6

[check/format]
type= string
status= idea
description= defines the format of the value

[check/path]
status= implemented
usedby/plugin= path
description= defines which file (path) the value refers to

[check/validation]
status= implemented
usedby/plugin= validation regexdispatcher
usedby/tool = web
type= regular expression
description= a regular expression to check against

[check/validation/message]
status= implemented
usedby/plugin= validation
usedby/tool = web
description= the message added to the error if validation fails

[check/validation/match]
status= implemented
usedby/plugin= validation
description= if it should be matched against LINE or WORD

[check/validation/ignorecase]
status= implemented
usedby/plugin= validation
description= to ignore case when matching

[check/validation/invert]
status= implemented
usedby/plugin= validation
description= to invert match

[check/validation/type]
type=enum
	ERE
	BRE
status= deprecated
usedby/plugin= validation
description= type of match, to toggle REG_EXTENDED
	TODO: strange syntax, needs improvements

[check/enum]
status=deprecated
usedby/plugin= enum
description= List of apostrophe enclosed values separated by
	commas to check against.
	Please use check/enum/# instead.

[check/enum/#]
status= implemented
usedby/plugin= enum regexdispatcher
usedby/tool = web
description= An array with different enum values to be used
	instead of check/enum

[check/enum/multi]
status= implemented
usedby/plugin= enum regexdispatcher
type= char
description= Specifies if multiple, but different, strings are allowed
	within an value. The character given within this metavalue
	is the separator.
example= _


[check/calculate]
status= implemented
usedby/plugin= calculate
type= string
description= A string starting with a logical comparator symbol
	followed by a Polish prefix notation to calculate a value
	to check against

[check/condition]
status= implemented
usedby/plugin= conditionals
type= string
description= A ternary conditional style operator to define
	relations between keys

[condition/validsuffix]
status= proposal
usedby/plugin= conditionals
type= string
description= A unit of measure style prefix

[check/condition/any/#]
status= implemented
usedby/plugin= conditionals
type= string
description= An array of multiple condition statements

[check/condition/all/#]
status= implemented
usedby/plugin= conditionals
type= string
description= An array of multiple condition statements

[check/condition/none/#]
status= implemented
usedby/plugin= conditionals
type= string
description= An array of multiple condition statements

[assign/condition]
status= implemented
usedby/plugin= conditionals
type= string
description= A ternary conditional style operator to assign
	a value depending on a condition

[assign/condition/#]
status= implemented
usedby/plugin = conditionals
type= string
descriptions= Array of assign/condition metadata

[check/date]
status= implemented
usedby/plugin= date
type= enum
	POSIX
	ISO8601
	RFC2822
description= Support of some standards for a date specification.

[check/date/format]
status= implemented
usedby/plugin= date
type= string
description= A format for a date specification.
	(If required by standard selected by check/date.)

[trigger/warnings]
usedby/plugin= error
type= long
status= implemented
description= Trigger a warning with given warning number from src/error/specifications

[trigger/error]
usedby/plugin= error
type= long
status= implemented
description= Trigger an error with given error number from src/error/specifications

[trigger/error/nofail]
usedby/plugin= error
type= long
status= proposal
description= Add the error but do not fail (to test robustness of framework).

#
# Other information about keys
#

[deprecated]
status= idea
description= Flag keys that will be removed in further versions
note= thanks to Config::Model for that idea

[internal/<plugin>/*]
status= implemented
usedby/plugin= (ini)
description= Internal metadata to be ignored by other plugins.
example=internal/ini/parent could be the name for internal parent
	information of the ini plugin.

[source]
status= idea
description= states where a key comes from if it is not from an ordinary
	persistent configuration. E.g. hardware (queries)
	e.g. system/sw/xorg/current/monitor might have "source" metadata if it
	is queried from hardware and not from configuration file.

[dependency/control]
status= idea
description= control keys which enable/disable parameters

[dependency/value]
status= idea
description= specific values of the dependency key have impact on that key

[application/name]
status= idea
description= links a key to a application, so that it can be easily purged
	when the application is no longer installed.
	Note that this is only needed together with another option below like version.
	Typically purged keys can be found easily when no schema for it exists anymore.

[application/version]
status= idea
description= links a key to a specific set of version(s). Can be used to control
	purging even more specific

[fixed]
status= idea
description= The key will return the given value in any case.

[restrict/write]
status= idea
usedby/tool = web
description= avoid writing on the value of the key, it still can be removed

[restrict/null]
status= idea
usedby/tool = web
description= null keys are not allowed

[restrict/binary]
status= idea
usedby/tool = web
description= binary keys are not allowed

[restrict/remove]
status= idea
usedby/tool = web
description= avoid removal of key (needs schema-checker to read key)

[evaluate/<language>]
type= program code
status= idea
description= evaluate expression to check if key should be included, program should
	abort or however evaluate plugin is configured


[accessibility]
status= idea
description= who is allowed to edit this configuration setting?


[visibility]
status= implemented
usedby/tool = web
type= enum
	critical
	important
	user
	advanced
	developer
	internal
description= who should see this configuration setting?
	This is the equivalent of priority in debconf.
	If no visibility is given, "user" is assumed.

	The meaning is:
	- critical: setting must be changed, otherwise the system/application will fail. (e.g. boot device, hostname)
	- important: setting has no reasonable default and most likely will fail, should be set so that application is (more) useful. (e.g. website URL to serve, relay host for mail relay)
	- user: often has reasonable default but most users would like to see it
	- advanced: settings most users do not want to see (e.g. related to resource usage) or to enable experimental features or where defaults usually work
	- developer: settings only relevant for developers of the application
	- internal: settings which should not be seen by anyone. (e.g. intermediate steps for calculations)



#
# Old stuff inherited from filesys plugin
#

[uid]
status= currently obsolete
type= time
usedby/api= keyNew kdbextension.h
description= The owner of the key.

[gid]
status= currently obsolete
type= time
usedby/api= keyNew kdbextension.h
description= The group of the key.

[mode]
status= currently obsolete
type= int
usedby/api= keyNew kdbextension.h
description= The access mode of the key.

[atime]
type= time
status= currently obsolete
usedby/api= keyNew kdbextension.h
description= The time when the key was last accessed.

[mtime]
type= time
status= currently obsolete
usedby/api= keyNew kdbextension.h
description= The time when the value of a key were last modified.

[ctime]
type= time
status= currently obsolete
usedby/api= keyNew kdbextension.h
description= The time when the metadata of a key were last modified.






#
# Reserved names, not to be used by metadata
#

[spec]
description= to not avoid metakeys with standard spec keys, no metakey name must begin with spec

[proc]
description= to not avoid metakeys with standard proc keys, no metakey name must begin with proc

[dir]
description= to not avoid metakeys with standard dir keys, no metakey name must begin with dir

[user]
description= to not avoid metakeys with standard user keys, no metakey name must begin with user

[system]
description= to not avoid metakeys with standard system keys, no metakey name must begin with system




#
# Plugin specific Metadata
#

[crypto/encrypt]
status= implemented
usedby/plugins= crypto
type= string
description= used to mark a key for encryption. The crypto plugin is supposed to encrypt the key. After the encryption the type of the key will be set to "binary". Its original type will be restored after decryption.

[crypto/salt]
status= implemented
usedby/plugins= crypto
type= string
description= used to store the salt that seeds the Key Derivation Function, which is used for deriving the cryptographic key and the initialization vector (IV).
	The salt is re-generated on every encryption call (called by kdb set) so no key and IV combination is ever used twice.
	No special protection is required for the salt. It can be persisted as plain text.

[xerces/rootname]
status= implemented
usedby/plugins= xerces
type= string
description= used to store the name of the xml file's original root element when mounting to a mountpoint which name doesn't correspond to the xml root element.
	This metadata will be stored in the mountpoint key. When writing or exporting again, the stored name will be used for the root element of the corresponding xml document.

[unit/base]
type = dec hex
default = dec
usedby/plugins = hexnumber
description = used to specify the base of an integer value. Currently only the hexnumber plugin supports this metadata. It converts any value marked as "hex" from
    hexadecimal into decimal when the configuration is read, and back when it is written. The hexnumber plugin also ensures that a value marked as "hex" starts with "0x" or "0X".
