valis / Reference / API reference

Config - API reference

Exported surface for the config subsystem. Part of the API reference.

Package valis/src/config/apply

Functions

change-node-setting

(change-node-setting path &key value reset)

Set the node key at PATH to VALUE, or return it to its shipped default when RESET is true, and return when the change takes effect as one of change-outcomes, with the key's declaration as a second value and, for committed-rebind-failed, the kind of condition the rebinding signalled as a third. The value is durable before anything running is touched. Outside the serving node every change is committed-on-restart and no rebinding runs. A refused value signals config-value-invalid, and a store that cannot be written signals its own condition; in either case nothing is stored and nothing running changes.

Variables

+change-outcomes+

Every outcome a change to a node key reports. committed-applied: the value is stored and in force. committed-rebind-failed: the value is stored, and the function that sets it in the running code signalled. committed-on-restart: the value is stored and takes effect at the next restart. A reset reports the outcome of its key exactly as a set does.

Package valis/src/config/client

Generic functions

config-backend-converse

(config-backend-converse backend lines)

Send LINES, one verb with one field to a line, to /config/ctl and answer the node's reply text, whose first line is the outcome. Signals config-request-refused when the node refuses the verb, and then nothing was changed.

config-backend-read

(config-backend-read backend path)

The text the file PATH names under /config serves, PATH a list of names such as ("list") or ("modules" SYSTEM "list"). Signals config-request-refused when the node refuses the read or serves no such file.

Functions

call-with-node-config-read-only

(call-with-node-config-read-only data-root thunk)

Call THUNK with the configuration under DATA-ROOT open read-only as the node's store, and close it afterwards. When DATA-ROOT holds no configuration directory, THUNK is called with the store binding left as it was. The binding is dynamic: a thread THUNK starts does not inherit it and reads the environment, or the image's global store if one is installed.

change-setting

(change-setting backend key &key system (value nil value-p))

Set KEY, a key path in dot form, of SYSTEM's module or of the node when SYSTEM is NIL, to the text VALUE, or reset it when no VALUE is given, through BACKEND's node, and answer the node's reply text. Its first line is committed-applied, committed-rebind-failed or committed-on-restart. Signals config-request-refused when the node refuses the change, which then changed nothing, and before asking the node when VALUE holds a line break. A committed change is noted in config-interaction when one is bound.

config-interaction-committed

(config-interaction-committed instance)

Undocumented: this exported symbol needs a docstring.

config-interaction-waiting

(config-interaction-waiting instance)

Undocumented: this exported symbol needs a docstring.

config-menu

(config-menu &optional system)

At the REPL: the settings menu of SYSTEM's module, or of the node when SYSTEM is NIL, over this image's own configuration, read from and written to the standard streams. Answers the changes committed, as run-config-menu does.

config-text-line

(config-text-line backend key &key system)

The line BACKEND's node serves for KEY, a key path in dot form, of SYSTEM's module or of the node when SYSTEM is NIL, exactly as served. Signals config-request-refused naming the key when there is none.

install-node-config-read-only

(install-node-config-read-only data-root)

Open the configuration under DATA-ROOT read-only, install it as this image's node store, and return it. When DATA-ROOT holds no configuration directory, nothing is installed and NIL is returned.

interview-rows

(interview-rows backend system)

The questions SYSTEM's module asks, in its order, each a list of fields: path, type, origin, value and prompt. Signals config-request-refused when no module of that system is loaded on BACKEND's node.

make-config-interaction

(make-config-interaction)

Undocumented: this exported symbol needs a docstring.

make-image-config-backend

(make-image-config-backend &key store data-root)

A backend over this image's own /config door. Over STORE when one is given. Over DATA-ROOT when one is given: each read opens its configuration read-only, which makes nothing, and each change opens it for writing, holding its lock only while that change is made, so a node starting meanwhile is never kept waiting on someone typing. Otherwise over the store the image has open, as at the REPL.

make-session-config-backend

(make-session-config-backend session root)

A backend over the /config door of the node SESSION, an owner session, reaches, ROOT being the owner frame's root handle as call-with-owner-session gives it.

module-rows

(module-rows backend system)

One row for each key of SYSTEM's module that BACKEND's node serves, as node-rows answers them, with the reason as a sixth field for a key the module takes only at restart. A second value lists what versions of the module set aside: path, version it came from and why.

node-rows

(node-rows backend)

One row for each node key BACKEND's node serves, each a list of fields: path, origin, type, change class and value.

node-setting-text

(node-setting-text backend key)

The value BACKEND's node holds for KEY, a node key path in dot form, as the text the node renders it, or NIL when it holds none, the key is secret, or the node serves no such key.

node-setting-texts

(node-setting-texts backend)

Each node key BACKEND's node holds a value for, as (KEY . TEXT), KEY in dot form and TEXT as the node renders it. A key with no value, a secret key, and a key this image does not declare are left out, so what comes back is only ever a value a client may act on and print.

parse-config-line

(parse-config-line line)

The fields of LINE, a line /config serves: separated by tabs, where inside a field a backslash followed by t, n or r reads back as a tab, newline or carriage return, and a backslash followed by any other character, a second backslash included, reads back as that character.

purge-settings

(purge-settings backend system)

Purge the settings kept for SYSTEM's module through BACKEND's node and answer the node's reply text, whose first line is purged or nothing-to-purge.

reply-token

(reply-token reply)

The outcome a reply from /config/ctl names: its first line.

run-config-interview

(run-config-interview backend system &key (input *standard-input*) (output *standard-output*))

Ask the questions SYSTEM's module declares, in its order, through BACKEND's node, showing each key's value now, a secret only as set or unset. Each answer goes to the node as a change, which the node checks; a refused answer is asked for again, a blank one keeps the value. The end of INPUT stops the interview. A module that declares no questions gets its settings menu instead, as run-config-menu offers it, and the operator is told so. A value that may be a secret is read without echo when INPUT is this process's standard input at a terminal, and as it comes otherwise; an answer is never printed back. Reports and answers the changes committed, each (path . outcome).

run-config-menu

(run-config-menu backend &key system (input *standard-input*) (output *standard-output*))

Offer the settings of SYSTEM's module, or of the node when SYSTEM is NIL, as a numbered list through BACKEND's node: each with its value, a secret only as set or unset, its origin and when a change applies. Choosing a number shows that setting and asks for a value, which the node checks; a refused value is asked for again, a blank one keeps the setting. A blank line, or the end of INPUT, leaves. A value that may be a secret is read without echo when INPUT is this process's standard input at a terminal, and as it comes otherwise; an answer is never printed back. Reports and answers the changes committed, each (path . outcome).

run-module-interview

(run-module-interview system)

At the REPL: the interview SYSTEM's module declares, over this image's own configuration, read from and written to the standard streams. Answers the changes committed, as run-config-interview does.

session-node-setting-text

(session-node-setting-text session root key)

The value the node SESSION reaches holds for KEY, as node-setting-text answers it, ROOT being the owner frame's root handle as call-with-owner-session gives it.

Macros

with-node-config-read-only

(with-node-config-read-only (data-root) &body body)

Run BODY with the configuration under DATA-ROOT open read-only as the node's store, as call-with-node-config-read-only does.

Variables

*config-interaction*

The record of the configuration client running now, or NIL. Its committed slot lists each change committed, newest first, as (key . outcome); its waiting slot is true while the client waits for the operator to type.

Package valis/src/config/conditions

Conditions

config-data-root-not-made

Signalled before anything is made when root would change a node's configuration directly under a data root that does not exist yet. PATH is the data root.

config-declaration-invalid

Signalled when a key is declared in a way the configuration cannot honour, such as an unknown type or a default its type refuses. Nothing is declared.

config-error

The root of every refusal the node configuration signals.

config-file-name-invalid

Signalled when a configuration file is asked for by a name that could reach outside the configuration directory.

config-function-missing

Signalled when a function a key's declaration names, its validator, reader or rebinding function, is not defined in the running image: its package is not loaded, or the name is not a function.

config-key-unknown

Signalled when a key is asked for that nothing declared.

config-node-unreachable

Signalled to a client of a running node's configuration surface when the node could not be reached, or the session to it failed before a reply came. CAUSE is what failed.

config-rebind-incomplete

Signalled by a rebinding function when what it rebuilt from the new value is missing something the running node holds now, because a store it reads could not be read or kept changing while it was read. The running node keeps what it has, and the stored value takes effect at the next restart. REASON says which read fell short and never carries a value.

config-request-refused

Signalled to a client of the node's configuration surface when the node refused what it was asked and changed nothing. ENAME is the refusal as the node named it: a prefix, a colon and what was wrong, never a value offered.

config-run-as-another-account

Signalled before anything is made when a node's configuration would be changed directly by an account other than the one owning the node's data root, or the nearest directory above it that exists. PATH is the directory judged.

config-store-error

A refusal about a configuration file or directory, named by PATH.

config-store-held

Signalled when the configuration cannot be opened for writing because another process holds it open: a running node, or an offline edit.

config-store-not-open

Signalled when a node setting is read or changed in an image that has opened no configuration store. A running node opens its store at boot, before anything reads a setting.

config-store-read-only

Signalled when a change is asked of a store opened read-only.

config-store-unreadable

Signalled when a configuration file does not hold what valis writes: syntax that would evaluate or build an object, a header naming another package, a format newer than this code, or a value that is not plain data. KEY-PATH, when known, names where in the file the refused value sits. Nothing in the file is used.

config-store-unsafe

Signalled when the configuration directory, or a file in it the store opens, is not private to the account running the node: owned by another account, open to others, or a symbolic link. Nothing in it is read or written.

config-store-unwritable

Signalled when a change could not be written to its file. The file and the table published to readers are as they were before the change.

config-value-invalid

Signalled when a value offered for a key is not one its type accepts. TYPE is the key's type and REASON is what is wrong with the value; neither repeats it.

module-settings-error

A refusal about one module's settings, named by SYSTEM, the ASDF system name they are kept under.

module-settings-outside-admitted-system

Signalled while a module is admitted when settings are declared by code that is not part of the admitted system, such as a dependency it loads. The load fails and nothing is registered.

module-settings-pending

Signalled when a module's settings are changed while the module's load has not completed, such as by a top-level form in its own file, or when the module was removed while the change waited for another to finish. Nothing is written, so a load that then fails leaves no settings file behind.

module-settings-system-mismatch

Signalled while a module loads when its :settings option names a system other than the one being admitted. The module's load fails and nothing is registered.

module-settings-system-taken

Signalled while a module loads when its settings would be kept under a system name whose settings already belong to a different module that is still loaded, or when a second module declares settings during one admission. The load fails and the settings already kept are left as they were.

not-a-settings-module

Signalled when module settings are asked for from a package that belongs to no module, or to a module that declares no settings.

unknown-settings-module

Signalled when a module's settings are to be changed, listed or asked about by system name and no module loaded in this image declares them, so there are no declarations to check a value against.

Generic functions

config-declaration-invalid-reason

(config-declaration-invalid-reason condition)

Undocumented: this exported symbol needs a docstring.

config-function-missing-designator

(config-function-missing-designator condition)

Undocumented: this exported symbol needs a docstring.

config-key-path

(config-key-path condition)

Undocumented: this exported symbol needs a docstring.

config-node-unreachable-cause

(config-node-unreachable-cause condition)

Undocumented: this exported symbol needs a docstring.

config-rebind-incomplete-reason

(config-rebind-incomplete-reason condition)

Undocumented: this exported symbol needs a docstring.

config-request-refused-ename

(config-request-refused-ename condition)

Undocumented: this exported symbol needs a docstring.

config-store-held-reason

(config-store-held-reason condition)

Undocumented: this exported symbol needs a docstring.

config-store-path

(config-store-path condition)

Undocumented: this exported symbol needs a docstring.

config-store-unreadable-reason

(config-store-unreadable-reason condition)

Undocumented: this exported symbol needs a docstring.

config-store-unsafe-reason

(config-store-unsafe-reason condition)

Undocumented: this exported symbol needs a docstring.

config-store-unwritable-cause

(config-store-unwritable-cause condition)

Undocumented: this exported symbol needs a docstring.

config-value-invalid-reason

(config-value-invalid-reason condition)

Undocumented: this exported symbol needs a docstring.

config-value-invalid-type

(config-value-invalid-type condition)

Undocumented: this exported symbol needs a docstring.

module-settings-outside-admitted-system-file

(module-settings-outside-admitted-system-file condition)

Undocumented: this exported symbol needs a docstring.

module-settings-system

(module-settings-system condition)

Undocumented: this exported symbol needs a docstring.

module-settings-system-mismatch-declared

(module-settings-system-mismatch-declared condition)

Undocumented: this exported symbol needs a docstring.

module-settings-system-taken-holder

(module-settings-system-taken-holder condition)

Undocumented: this exported symbol needs a docstring.

not-a-settings-module-designator

(not-a-settings-module-designator condition)

Undocumented: this exported symbol needs a docstring.

Package valis/src/config/declare

Classes

declaration-table

The declared keys of one configuration file, by path, each with the order it was first declared in.

setting-declaration

Undocumented: this exported symbol needs a docstring.

Functions

check-setting-value

(check-setting-value declaration value)

Return VALUE when it is a value DECLARATION's key can hold; otherwise signal config-value-invalid naming the key and its type.

declarations-in-order

(declarations-in-order table)

Every declaration in TABLE, in the order its key was first declared.

declare-setting

(declare-setting table &rest initargs)

Declare a key in TABLE from INITARGS, as make-setting-declaration takes them, and return the declaration. Declaring a key again exactly as before changes nothing, so a file loaded twice declares nothing twice. Declaring it differently replaces the earlier declaration in its place, and the replacement is logged by key path so a change of shape is visible.

find-declaration

(find-declaration table path)

The declaration of the key at PATH in TABLE. Signals config-key-unknown, naming the path, when nothing declared it.

make-declaration-table

(make-declaration-table)

Undocumented: this exported symbol needs a docstring.

make-setting-declaration

(make-setting-declaration &key path type (default nil default-p) env-variable sensitivity (apply-mode :restart) rebind validate reader doc environment-when-secret)

Declare a key at PATH, a list of keywords, of TYPE, one of the setting types. With a DEFAULT, even NIL, the key may go unset and reads as that default; with none it is required, and reads as unset until a value is stored. ENV-VARIABLE names the environment variable that seeds it, SENSITIVITY is NIL, :personal or :secret, and APPLY-MODE is when a change takes effect: :live at the next read, :rebind once the function REBIND names has run, or :restart. VALIDATE names a function called with a value its type accepts, which may refuse it further. READER names the function that consumes the key. REBIND and READER are a symbol, or text of the form package::name, which names a function in code the configuration layer does not load and is found when it is called. ENVIRONMENT-WHEN-SECRET true marks a key whose environment value stays in the environment, unstored, while it carries a secret; only a key whose type defines a test for a text holding a secret may be so marked. A declaration the configuration cannot honour signals config-declaration-invalid and nothing is declared.

normalize-key-path

(normalize-key-path path)

PATH as a list of keywords: a single keyword stands for a path of one. Anything else is refused as an unknown key.

parse-setting-text

(parse-setting-text declaration text)

Parse TEXT as a value of DECLARATION's key and return the value. TEXT is in the one form shared by environment seeding, the command line and the owner's door. When the key's type refuses the text, config-value-invalid is signalled, naming the key and its type but never the text.

plain-setting-value-p

(plain-setting-value-p value)

True when VALUE is a string, an integer, a keyword, T, NIL, or a proper list of such values. Nothing else is ever a setting value, so nothing else is ever written to or accepted from a configuration file.

refuse-setting-text

(refuse-setting-text reason)

Refuse the value a type is reading or checking, for REASON. REASON must not repeat the value.

render-setting-value

(render-setting-value declaration value)

VALUE as the text DECLARATION's key is written in. NIL, which stands for no value, is the empty text for every type but a boolean.

resolve-setting-function

(resolve-setting-function designator &optional key-path)

The function DESIGNATOR names, a symbol or package::name text. Signals config-function-missing, naming KEY-PATH, the key whose declaration names it, when its package is not loaded or the name is not a function. Resolving it interns nothing.

setting-declaration-apply-mode

(setting-declaration-apply-mode instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-default

(setting-declaration-default instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-doc

(setting-declaration-doc instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-env-variable

(setting-declaration-env-variable instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-environment-when-secret

(setting-declaration-environment-when-secret instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-path

(setting-declaration-path instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-reader

(setting-declaration-reader instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-rebind

(setting-declaration-rebind instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-required-p

(setting-declaration-required-p instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-sensitivity

(setting-declaration-sensitivity instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-type

(setting-declaration-type instance)

Undocumented: this exported symbol needs a docstring.

setting-declaration-validate

(setting-declaration-validate instance)

Undocumented: this exported symbol needs a docstring.

setting-text-carries-secret-p

(setting-text-carries-secret-p declaration text)

True when TEXT, offered for DECLARATION's key, holds a secret its type never lets the store keep. False for every type that holds no secret.

setting-type-names

(setting-type-names)

The names of every setting type.

Macros

define-setting-type

(define-setting-type name &key parse render check carries-secret)

Define the setting type NAME, a keyword. PARSE turns text into a value, RENDER turns a value back into that text, and CHECK is true of every value the type holds. PARSE and CHECK may call refuse-setting-text with the reason a value is refused. CARRIES-SECRET, when given, is true of a text that holds a secret the store never keeps, such as a database address with a password in it.

Package valis/src/config/lookup

Functions

config-lookup

(config-lookup variable)

The text of the node setting the environment variable VARIABLE seeds, or NIL when it has none, in the form the environment has always written it.

With no store open, as in a unit test or a development image before a boot, the value is the environment's.

With a store open, the value is the one stored for the key VARIABLE seeds. When nothing is stored and seeding has not yet settled the key, the value is the environment's, because the next boot still seeds the key from it. When nothing is stored and the key is settled, the value is the key's shipped default. Every node key ships with NIL as its default.

A variable no node key declares is read from the environment.

The database address is the one exception to the store coming first. The store refuses an address carrying a password, so no secret reaches it or a backup of it, and such an address can live only in the environment. While the environment's address carries a password it is the value, even with a store open; a password-free address in the environment follows the ordinary rule.

Package valis/src/config/module

Macros

defaulted-module-setting

(defaulted-module-setting &rest path)

The value the module whose code this is runs on for the key at PATH: the owner's stored value, else the key's shipped default. It never writes a value back, unlike Radiance's accessor of the same name, so a default changed in a later version of the module reaches every node whose owner left the key alone.

module-setting

(module-setting &rest path)

The value the owner stored for the key at PATH of the module whose code this is, and true; or NIL and NIL when nobody customized it, as ubiquitous's value answers. Use defaulted-module-setting for the value to run on. Use setf on it to store a value: the value is checked against the key's type and its validator, a value equal to the default removes the customization, and the module's on-change function runs when it declared one. Signals not-a-settings-module when compiled outside a module that declares settings, config-key-unknown for a key the module did not declare, and config-value-invalid for a refused value, in which case nothing changes.

module-settings

(module-settings)

One row for each key the module whose code this is declared, in declaration order, as list-settings gives them: :path, :type, :value as text, :origin, :apply-mode, :sensitivity and :doc, and :reason for a key that applies only at restart.

reset-module-setting

(reset-module-setting &rest path)

Return the key at PATH of the module whose code this is to its shipped default, removing the owner's value, and run the module's on-change function when it declared one.

Package valis/src/config/module-admin

Functions

change-module-setting

(change-module-setting system path &key value reset)

Set the key at PATH of the module whose system is SYSTEM to VALUE, or return it to its shipped default when RESET is true, and answer when the change takes effect as one of the change outcomes: committed-applied for a live key, after the module's on-change function ran when it declared one; committed-on-restart only for a key the module declared :apply :restart; committed-rebind-failed when the on-change function signalled, the value then kept. The key's declaration is a second value, and for committed-rebind-failed the kind of condition the on-change function signalled is a third. The module reads the new value next. A value the key's type or its own validator refuses signals config-value-invalid and changes nothing; a system no loaded module declares settings for signals unknown-settings-module.

module-interview-for-system

(module-interview-for-system system)

The interview the module whose system is SYSTEM declared, in its order: for each question a property list of :path, :prompt, :type, :value as the module's settings list shows it, so a secret's is set or unset, and :origin. Signals unknown-settings-module when no loaded module declares settings for SYSTEM.

module-kept-aside-for-system

(module-kept-aside-for-system system)

The values kept aside for the module whose system is SYSTEM, which a version of the module could not carry, as its file holds them: for each a property list of :path, :from-version, the settings version it came from, :reason, why it was kept aside, and :value as text, or set for a key the module last declared secret. A loaded module's file is brought to its version first. A system with no file has none.

module-setting-declaration

(module-setting-declaration system path)

The declaration of the key at PATH of the module whose system is SYSTEM, which a surface taking a value as text parses the text against. Signals unknown-settings-module when no loaded module declares settings for SYSTEM, and config-key-unknown when the module declares no key at PATH.

module-settings-for-system

(module-settings-for-system system)

The settings of the module whose system is SYSTEM, one row per key. For a loaded module these are the rows list-settings gives a node's own keys, with :reason on a key that applies only at restart. For a module no longer loaded they are what its file kept, so the owner can see what removing it left: :path, :value as text, or set for a key the module last declared secret and for every key of a file that never recorded which were, :origin, and :undeclared true. A system with neither has no rows.

purge-module-settings

(purge-module-settings system)

Remove the settings file of the module whose system is SYSTEM, with every value kept aside in it, and answer purged, or nothing-to-purge when SYSTEM has no file. This is the one act that removes a module's settings: removing the module leaves them for a reinstall. A file the node refuses to read goes too, since the owner has no other way to be rid of it. When the module is loaded its keys read their defaults from then on, its on-change function runs when it declared one, after the purge has let go of the configuration, and a second value answers when that takes effect, as one of the change outcomes: committed-on-restart when a value removed was of a key the module takes only at restart, or might have been, for a file that could not be read; committed-rebind-failed when the on-change function signalled; and committed-applied otherwise. A store opened read-only signals config-store-read-only and nothing is removed.

settings-modules

(settings-modules)

One entry for each system that has settings: every loaded module that declared them, and every settings file a module no longer loaded left behind. Each entry is a property list of :system, :loaded-p, :keys, the number of keys declared or NIL when the module is not loaded, and :customized, the number of values its file holds. Ordered by system name.

Variables

+purge-outcomes+

What purge-module-settings answers: purged when it removed a module's settings file, nothing-to-purge when there was none.

Package valis/src/config/node

Functions

node-setting

(node-setting path)

The value of the node key at PATH and its origin, :operator, :seeded, :default or :unset, read from the node's open store. Signals config-store-not-open when the image has opened none.

node-setting-declaration-for-variable

(node-setting-declaration-for-variable name)

The declaration of the node key the environment variable NAME seeds, or NIL when NAME seeds none.

node-settings

(node-settings)

One row for every node key, in declaration order, as list-settings gives them.

parse-setting-path

(parse-setting-path text)

The key path TEXT names, written as its parts joined by dots, such as acme.store-path. Upper and lower case read alike. Text with an empty part, or a part that names no keyword in this image, signals config-key-unknown. Parsing it interns nothing.

render-setting-path

(render-setting-path path)

PATH, a list of keywords, as text: its parts in lower case joined by dots.

reset-node-setting

(reset-node-setting path)

Return the node key at PATH to its shipped default, and return when the change takes effect.

set-node-setting

(set-node-setting path value)

Set the node key at PATH to VALUE as the operator's choice, and return when the change takes effect: :live, :rebind or :restart.

Variables

*node-declarations*

Every key the node takes. A defparameter, so reloading this file rebuilds the table and a key removed from the source is gone from it too.

Package valis/src/config/seed

Functions

close-node-config-for-boot

(close-node-config-for-boot store)

Close STORE, releasing its lock, and when it is the node's store put back the store installed before it. Closing twice is harmless.

node-key-settled-p

(node-key-settled-p store path)

True when seeding has settled the node key at PATH in STORE's node file. A key never settled is still seeded from the environment at the next boot, so until then the environment is its value.

open-node-config-for-boot

(open-node-config-for-boot data-root &key (lookup (function getenv)) (wait-seconds *boot-config-lock-wait-seconds*))

Open the configuration under DATA-ROOT for writing, seed it from LOOKUP, install it as the node's store and return it. The open waits up to WAIT-SECONDS for another holder to release the lock; if the lock is still held when the wait ends, the boot is refused with config-store-held, and the refusal names DATA-ROOT. The store holds its lock until close-node-config-for-boot, or until the process exits and the kernel releases the lock. If seeding fails, the store is closed, the store installed earlier stays installed, and the failure is passed on.

seed-node-config

(seed-node-config store &key (lookup (function getenv)) (declarations *node-declarations*))

Seed STORE's node file from the environment for every key in DECLARATIONS that is not yet settled, then log, by key alone, every key whose environment value the store supersedes. LOOKUP reads a variable and defaults to this process's environment. A key the store already holds a value for is settled and left as it is; a set variable is stored with the origin :seeded, even when it equals the default; an unset one is settled with nothing stored. A value its key's type refuses is neither stored nor settled, and is logged by key and type. On every call, settled or not, each key whose environment value carries a secret is logged as held in the environment. Returns the paths seeded and the paths superseded.

serving-node-store-p

(serving-node-store-p &optional (store *node-config-store*))

True when STORE is the store a node's boot opened and installed, so a change to it reaches a running node. A store opened any other way, such as by an offline edit or read-only by a command-line verb, is not.

Variables

*boot-config-lock-wait-seconds*

How long a boot waits for another holder of the configuration lock to release it before the boot is refused. An offline `valis config` holds the lock for as long as it runs, so a node started during a short edit is delayed rather than refused.

*seeding-binary*

The binary seeding the store, as a list of its version and the commit it was built from, recorded beside each key it settles. The boot binds it; when nothing has, NIL is recorded for both.

Package valis/src/config/settings

Functions

list-settings

(list-settings store table name &key snapshot)

One row for each key declared in TABLE, in declaration order, as a property list: :path, :type, :value as text, :origin, :apply-mode, :sensitivity and :doc. A secret key's :value is the word set or unset and never the value. A personal key's value is shown, for the owner who asked; it must never be logged. The values are read from SNAPSHOT when it is given, a table of STORE's file NAME as a caller holds it, and otherwise from the table the file holds now.

reset-setting

(reset-setting store table name path)

Remove the stored value of the key at PATH, declared in TABLE, and its origin from STORE's file NAME, so the key reads as its shipped default again. The record of which keys environment seeding has settled is left as it is, and a key with nothing stored is left with nothing written. Returns when the change takes effect.

setting-value

(setting-value store table name path)

Return the value of the key at PATH, declared in TABLE and kept in STORE's file NAME, and its origin: :operator or :seeded for a stored value, :default for the shipped default of a key nobody has set, and :unset, with NIL, for a required key nobody has set. Reading never writes. Signals config-key-unknown for an undeclared key, and config-store-unreadable for a stored value its type refuses.

setting-value-in-snapshot

(setting-value-in-snapshot store table name snapshot path)

As setting-value, read from SNAPSHOT, a table STORE's file NAME published, rather than from the one it holds now. A caller that keeps the table it was last given reads through this.

store-setting

(store-setting store table name path value &key (origin :operator))

Set the key at PATH, declared in TABLE, to VALUE in STORE's file NAME, recording ORIGIN, :operator or :seeded. VALUE is checked against the key's type and then its own validator before anything changes, and a refused value signals config-value-invalid with nothing changed. A value equal to the shipped default removes the key instead, since only customizations are kept. A change that leaves the file as it was writes nothing. Returns when the change takes effect: :live, :rebind or :restart.

Package valis/src/config/store

Classes

config-store

Undocumented: this exported symbol needs a docstring.

Functions

call-with-config-files-read-locked

(call-with-config-files-read-locked data-root thunk)

Call THUNK, to read the configuration files under DATA-ROOT as one set, and return its values. When this image has the configuration under DATA-ROOT open, however the root is spelled, THUNK runs holding the configuration write lock, so no change lands while it reads. Otherwise THUNK just runs: every file it opens is whole, since a change is renamed into place.

call-with-config-write-lock

(call-with-config-write-lock store thunk)

Call THUNK holding the image's configuration write lock and return its values, so no other change lands between what a caller reads and the change it makes from that. Changes made inside THUNK take the same lock again without waiting.

change-config-file

(change-config-file store name function)

Change STORE's file NAME by calling FUNCTION on a private copy of its table, with ubiquitous's storage bound to that copy and nothing committed by ubiquitous itself, then write the copy and make it the table readers are given. Returns FUNCTION's value. Changes in this image are made one at a time, and a change that leaves the table as it was writes nothing. A change made from inside another change to the same file joins it: it alters the same copy, and the outer change writes both. When FUNCTION signals, or the copy cannot be written, the file and the table readers are given are left as they were. A store opened read-only signals config-store-read-only, and a closed one config-store-unwritable.

change-config-snapshot

(change-config-snapshot store name function)

Change what readers of STORE's file NAME are given in this image by calling FUNCTION on a private copy of its table, with ubiquitous's storage bound to the copy, and write nothing. Only a store opened read-only is changed this way: a process that checks an install opens the store read-only and works out in memory what the node would hold, and on a store opened for writing what readers are given must always be what the file holds. Returns FUNCTION's value.

close-config-store

(close-config-store store)

Let go of STORE's lock, when it holds one, once no change in this image is in progress. Closing a store twice is harmless.

config-directory

(config-directory data-root)

The configuration directory under DATA-ROOT.

config-file-pathname

(config-file-pathname store relative-name)

The file RELATIVE-NAME names inside STORE's configuration directory, such as node.conf.lisp or modules/<system>.conf.lisp. A name that could reach outside the directory signals config-file-name-invalid.

config-file-snapshot

(config-file-snapshot store name)

The table STORE's file NAME holds, as last written, read from disk the first time it is asked for. Never takes the write lock. The table is shared with every other reader and must not be changed; a change goes through change-config-file.

config-store-held-p

(config-store-held-p data-root)

True when another process holds the lock on the configuration under DATA-ROOT. Checks without holding the lock past the check, and makes nothing. NIL when there is no lock file or this account cannot open it.

config-store-mode

(config-store-mode instance)

Undocumented: this exported symbol needs a docstring.

config-store-over-octets

(config-store-over-octets data-root files)

A read-only store over the configuration under DATA-ROOT in which each file FILES names, as a list of (relative-name . octets), reads as those octets and not as anything on disk. Each is judged by the same reader a file on disk is, so one that is too large, not UTF-8, or holds anything valis does not write signals config-store-unreadable. It takes no lock, and nothing is read from or written to disk for a file FILES names.

config-store-root

(config-store-root instance)

Undocumented: this exported symbol needs a docstring.

copy-config-table

(copy-config-table table)

A private copy of TABLE, a configuration file's table, that can be changed without changing what any reader is given.

delete-config-file

(delete-config-file store name)

Remove STORE's file NAME, durably, and give its readers an empty table from then on. Answers true when a file was removed and NIL when there was none. It is a change like any other: made holding the configuration write lock, so no other change in this image interleaves with it. A store opened read-only signals config-store-read-only, and a closed one config-store-unwritable; a file that cannot be removed signals config-store-unwritable and is left as it was.

open-config-store

(open-config-store data-root &key (mode :read-write) (wait-seconds 0))

Open the configuration kept under DATA-ROOT. MODE :read-write makes the configuration directory, at 0700, when it is absent and holds the configuration's lock until close-config-store, waiting up to WAIT-SECONDS for another holder to let go and then signalling config-store-held; a boot passes a wait so a brief offline edit delays it rather than failing it. MODE :read-only takes no lock and creates nothing. :read-write signals config-store-unsafe when an existing configuration directory is not private to the running account; :read-only signals config-store-unsafe for a directory another account owns, or one that is a symbolic link, not a directory, or writable by others; it accepts one others may read.

Macros

with-config-store

(with-config-store (var data-root &key (mode :read-write) (wait-seconds 0)) &body body)

Open the configuration under DATA-ROOT as VAR, bind node-config-store to it while BODY runs, then close it.

Variables

*config-file-format*

The layout of the configuration files this code writes and the newest it reads.

*node-config-file*

The name, within the configuration directory, of the node's own settings.

*node-config-store*

The configuration store this image has open, or NIL when it has none.