References
A reference is a marker in the value of a configuration keyword, replaced during evaluation.
A reference is formatted as {<expression>}.
References can be used to:
-
Abstract changing parts of a configuration, so this configuration can be used as a template Example: The object name, object id, the devices that hosts the data
-
Factorize information, so changing it is easier and safer Example: A project name used to format the name of different resources (volume group, filesystem path, …)
-
Contextualize part of a configuration with information known to the agent Example: The cluster nodes, cluster dns ip addresses, …
Intra-Configuration References
The reference format is {[<section>.]<option>}, where
<section>is a configuration file section name<option>is the option name in the pointed section.
If <section> is omitted, the referencing keyword’s section is implicitly used if the reference can be found locally, or the DEFAULT section is implicitly used.
Intra-Section References
These references can be used inside a configuration section, and their evaluated value depends on the section.
| Reference | Description | Node Configuration File | Service Configuration File |
|---|---|---|---|
{rid} | The name of the section the reference is under | No | Yes |
{rindex} | The part after the dash of the name of the section the reference is under | No | Yes |
{<keyword>} | Reference to another keyword’s value inside the same section | Yes | Yes |
Hard Coded References
| Reference | Description | Node Configuration File | Service Configuration File |
|---|---|---|---|
{nodename} | The running node fqdn | Yes | Yes |
{short_nodename} | The running node base name (without domain) | Yes | Yes |
{#nodes} | Number of nodes | No | Yes |
{namespace} | The name of the hosting namespace | No | Yes |
{kind} | The object kind, ie “svc”, “vol”, “sec”, “cfg”, “ccfg” | No | Yes |
{name} | The object name | No | Yes |
{path} | The object path, ie <namespace>/<kind>/<name> | No | Yes |
{short_name} | The object base name (name with domain suffix stripped) | No | Yes |
{fqdn} | The object fully qualified name, as registered in the cluster DNS, ie <name>.<namespace>.<kind>.<clustername> | No | Yes |
{scaler_name} | The scaler name (because {name} resolves to the slice name) | No | Yes |
{scaler_short_name} | The scaler base name (name with domain suffix stripped) | No | Yes |
{id} | The object id | No | Yes |
{safe://<id>} | Substitute the reference with the content of the safe file identified by <id>. Usually passwords or private keys. The content is cached locally so the collector dependency is loose. | Yes | Yes |
{clustername} | The cluster.name node keyword value | Yes | Yes |
{clusterid} | The cluster.id node keyword value | Yes | Yes |
{clusternodes} | The cluster.nodes node keyword value | Yes | Yes |
{clusterdrpnodes} | The cluster.drpnodes node keyword value | Yes | Yes |
{dns} | The cluster.dns node keyword value (ip adressses) | Yes | Yes |
{dnsnodes} | The cluster.dns node keyword value (resolved names) | Yes | Yes |
{dnsuxsock} | The path to the dns thread unix socket | Yes | Yes |
{dnsuxsockd} | The path to the directory hosting the dns thread unix socket | Yes | Yes |
{collector_api} | The uri of the collector Rest API | Yes | Yes |
{nodemgr} | The om node command, ie /usr/bin/om node | Yes | Yes |
{svcmgr} | The om svc command, ie /usr/bin/om svc | Yes | Yes |
{etc} | The agent etc/ directory path: /etc/opensvc/ for agents installed through the packages, /opt/opensvc/etc/ for an agent installed via git pull in /opt | Yes | Yes |
{var} | The agent var/ directory path /var/lib/opensvc/ for agents installed through the packages, /opt/opensvc/var/ for an agent installed via git pull in /opt | Yes | Yes |
{initd} | The object init directory path. ex: /etc/opensvc/etc/<name>.d | Yes | Yes |
{private_var} | The object private directory under {var} | Yes | Yes |
{<rid>.exposed_devs} | The whitespace-separated list of devpaths exposed by <rid> | No | Yes |
{<rid>.exposed_devs[<n>]} | The <n>-th element of the list of devpaths exposed by <rid> | No | Yes |
{<rid>.exposed_devs[#]} | The length of the list of devpaths exposed by <rid> | No | Yes |
{<rid>.capacity} | How big <rid> is now, in bytes, asked of the resource itself | No | Yes |
Deprecated references:
| Reference | Description | Node Configuration File | Service Configuration File |
|---|---|---|---|
{svcname} | Deprecated by {name} | No | Yes |
{svcpath} | Deprecated by {path} | No | Yes |
{short_svcname} | Deprecated by {short_name} | No | Yes |
Capacity
{<rid>.capacity} is how big a resource is, asked of the resource. It is not
that resource’s size keyword: the keyword says what the resource was asked
to be, and the capacity says what it holds now. The two differ wherever a
driver rounds, keeps metadata of its own, or has been grown since.
A resource answers it if it can say how big it is: volume groups, zpools, md arrays, logical volumes, zvols, loop and rados disks, and the filesystems that hold their own size.
It is resolved when the resource exists. A reference to a resource of the same object that is configured but not built yet waits for it to be built, which is what lets a configuration naming one validate before anything is provisioned.
Arithmetic
A reference can be computed on. An expression is written $(...), and what it
computes replaces it:
[disk#1]
type = lv
vg = {disk#vg.name}
size = $(50% * {disk#vg.capacity})
The references are resolved first, so what the arithmetic reads is numbers.
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ - | sum and difference | $(10g - 1g) | 9663676416 |
* | product | $(2 * 512m) | 1073741824 |
/ | division | $(10g / 2) | 5368709120 |
// | division, whole part | $(5 // 2) | 2 |
% | what a division leaves | $(5 % 2) | 1 |
<n>% | a share of something | $(50% * 10g) | 5368709120 |
Numbers are written the way every other size in a configuration is written, so
10g, 10GB and 1ki are numbers here. Parentheses group, and a leading -
negates.
A percent sign means one of two things, told apart by what follows it. A
number follows a remainder, and an operator or the end of the expression
follows a share, so 9 % 4 is 1 and 50% * 10g is half of ten gibibytes.
The spaces around the sign make no difference.
The result is a whole number: a half of an odd number of bytes is one of them or the other, not an error. The drivers round it again to what their storage takes, so a filesystem asked for a third of a volume group lands on the nearest extent below it.
Arithmetic is computed only on keywords that convert to a number — a size,
an integer. $(...) is also how a shell substitutes a command, and keywords
hold shell commands, so a trigger or the start of an app keeps what it was
written with:
[app#1]
type = forking
start = /bin/echo $(date +%s) # a command, left alone
[disk#0]
type = loop
size = $(2 * 512m) # a size, computed
References and env Section
The env section can be used to store arbitrary factorized information to make available as references in other parts of the configuration.
Example:
[disk#0]
name = {id}
pvs = {env.devs}
[env]
devs = /dev/vdb
These values can be overridden when creating a new object from this configuration file or template.
om <path> create --config <template> --env devs=/dev/vdc