Represents a context for interacting with uci configuration files.
Operations on uci configurations are performed through a uci cursor object which operates on in-memory representations of loaded configuration files.
Any changes made to configuration values are local to the cursor object and held in memory only until they're written out to the filesystem using the save()
and commit()
methods.
Changes performed in one cursor instance are not reflected in another, unless the first instance writes those changes to the filesystem and the other instance explicitly (re)loads the affected configuration files.
const ctx = cursor(…);
// Enumerate configuration files
ctx.configs();
// Load configuration files
ctx.load(…);
ctx.unload(…);
// Query values
ctx.get(…);
ctx.get_all(…);
ctx.get_first(…);
ctx.foreach(…);
// Modify values
ctx.add(…);
ctx.set(…);
ctx.rename(…);
ctx.reorder(…);
ctx.delete(…);
// Stage, revert, save changes
ctx.changes(…);
ctx.save(…);
ctx.revert(…);
ctx.commit(…);
- See
Methods
add(config, type) → {string}nullable
Add anonymous section to given configuration.
Adds a new anonymous (unnamed) section of the specified type to the given configuration. In order to add a named section, the three argument form of set()
should be used instead.
In contrast to other query functions, add()
will not implicitly load the configuration into the cursor. The configuration either needs to be loaded explicitly through load()
beforehand, or implicitly by querying it through one of the get()
, get_all()
, get_first()
or foreach()
functions.
Returns the autogenerated, ephemeral name of the added unnamed section on success.
Returns null
on error, e.g. if the targeted configuration was not loaded or if an invalid section type value was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to add the section to, e.g. |
type | string | The type value to use for the added section. |
const ctx = cursor(…);
// Load firewall configuration
ctx.load('firewall');
// Add unnamed `config rule` section
const sid = ctx.add('firewall', 'rule');
// Set values on the newly added section
ctx.set('firewall', sid, 'name', 'A test');
ctx.set('firewall', sid, 'target', 'ACCEPT');
…
changes(configopt) → {Object<string: ChangeRecord[]>}nullable
Enumerate pending changes.
The changes()
function returns a list of change records for currently loaded configuration files, originating both from the cursors associated delta directory and yet unsaved cursor changes.
When the optional "config" parameter is specified, the requested configuration is implicitly loaded if it is not already loaded into the cursor.
Returns a dictionary of change record arrays, keyed by configuration name.
Returns null
on error, e.g. if the requested configuration could not be loaded.
Name | Type | Description |
---|---|---|
config | string | (optional) The name of the configuration file to enumerate changes for, e.g. |
const ctx = cursor(…);
// Enumerate changes for all currently loaded configurations
const deltas = ctx.changes();
// Explicitly load and enumerate changes for the "system" configuration
const deltas = ctx.changes('system');
commit(configopt) → {boolean}nullable
Update configuration files with accumulated cursor changes.
The commit()
function merges changes made to in-memory copies of loaded configuration files as well as existing delta records in the cursors configured delta directory and writes them back into the underlying configuration files, persistently committing changes to the file system.
When the optional "config" parameter is omitted, all currently loaded configuration files with either present delta records or yet unsaved cursor changes are updated.
Returns the true
if operation completed successfully.
Returns null
on error, e.g. if the requested configuration was not loaded or when a file system error occurred.
Name | Type | Description |
---|---|---|
config | string | (optional) The name of the configuration file to commit, e.g. |
const ctx = cursor(…);
ctx.set('system', '@system[0]', 'hostname', 'example.org');
ctx.commit('system');
configs() → {string[]}nullable
Enumerate existing configurations.
The configs()
function yields an array of configuration files present in the cursors associated configuration directory, /etc/config/
by default.
Returns an array of configuration names on success.
Returns null
on error, e.g. due to filesystem errors.
const ctx = cursor(…);
// Enumerate all present configuration file names
const configurations = ctx.configs();
delete(config, section, optionopt) → {boolean}nullable
Delete an option or section from given configuration.
When invoked with three arguments, the function deletes the given option within the specified section of the given configuration.
When invoked with two arguments, the function deletes the entire specified section within the given configuration.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the true
if specified option or section has been deleted.
Returns null
on error, e.g. if the targeted configuration was not found or if an invalid value was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to delete values in, e.g. |
section | string | The section name to remove the specified option in or, when the subsequent argument is omitted, the section to remove entirely. |
option | string | (optional) The option name to remove within the section. |
const ctx = cursor(…);
// Delete 'disabled' option in first wifi-iface section
ctx.delete('wireless', '@wifi-iface[0]', 'disabled');
// Delete 'wan' interface
ctx.delete('network', 'lan');
// Delete last firewall rule
ctx.delete('firewall', '@rule[-1]');
error() → {string}nullable
Query error information.
Returns a string containing a description of the last occurred error or null
if there is no error information.
// Trigger error
const ctx = cursor();
ctx.set("not_existing_config", "test", "1");
// Print error (should yield "Entry not found")
print(ctx.error(), "\n");
foreach(config, typenullable, callback) → {boolean}nullable
Iterate configuration sections.
The foreach()
function iterates all sections of the given configuration, optionally filtered by type, and invokes the given callback function for each encountered section.
When the optional "type" parameter is specified, the callback is only invoked for sections of the given type, otherwise it is invoked for all sections.
The requested configuration is implicitly loaded into the cursor.
Returns true
if the callback was executed successfully at least once.
Returns false
if the callback was never invoked, e.g. when the configuration is empty or contains no sections of the given type.
Returns null
on error, e.g. when an invalid callback was passed or the requested configuration not found.
Name | Type | Description |
---|---|---|
config | string | The configuration to iterate sections for, e.g. |
type | string | (nullable) Invoke the callback only for sections of the specified type. |
callback | SectionCallback | The callback to invoke for each section, will receive a section dictionary as sole argument. |
const ctx = cursor(…);
// Iterate all network interfaces
ctx.foreach('network', 'interface',
section => print(`Have interface ${section[".name"]}\n`));
get(config, section, optionopt) → {string|string[]}nullable
Query a single option value or section type.
When invoked with three arguments, the function returns the value of the given option, within the specified section of the given configuration.
When invoked with just a config and section argument, the function returns the type of the specified section.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the configuration value or section type on success.
Returns null
on error, e.g. if the requested configuration does not exist or if an invalid argument was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to query, e.g. |
section | string | The name of the section to query within the configuration. |
option | string | (optional) The name of the option to query within the section. If omitted, the type of the section is returned instead. |
const ctx = cursor(…);
// Query an option, extended section notation is supported
ctx.get('system', '@system[0]', 'hostname');
// Query a section type (should yield 'interface')
ctx.get('network', 'lan');
get_all(config, sectionopt) → {Object<string: SectionObject>|SectionObject}nullable
Query a complete section or configuration.
When invoked with two arguments, the function returns all values of the specified section within the given configuration as dictionary.
When invoked with just a config argument, the function returns a nested dictionary of all sections present within the given configuration.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the section or configuration dictionary on success.
Returns null
on error, e.g. if the requested configuration does not exist or if an invalid argument was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to query, e.g. |
section | string | (optional) The name of the section to query within the configuration. If omitted a nested dictionary containing all section values is returned. |
const ctx = cursor(…);
// Query all lan interface details
ctx.get_all('network', 'lan');
// Dump the entire dhcp configuration
ctx.get_all('dhcp');
get_first(config, type, optionopt) → {string|string[]}nullable
Query option value or name of first section of given type.
When invoked with three arguments, the function returns the value of the given option within the first found section of the specified type in the given configuration.
When invoked with just a config and section type argument, the function returns the name of the first found section of the given type.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the configuration value or section name on success.
Returns null
on error, e.g. if the requested configuration does not exist or if an invalid argument was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to query, e.g. |
type | string | The section type to find the first section for within the configuration. |
option | string | (optional) The name of the option to query within the section. If omitted, the name of the section is returned instead. |
const ctx = cursor(…);
// Query hostname in first anonymous "system" section of /etc/config/system
ctx.get_first('system', 'system', 'hostname');
// Figure out name of first network interface section (usually "loopback")
ctx.get_first('network', 'interface');
load(config) → {boolean}nullable
Explicitly reload configuration file.
Usually, any attempt to query or modify a value within a given configuration will implicitly load the underlying file into memory. By invoking load()
explicitly, a potentially loaded stale configuration is discarded and reloaded from the file system, ensuring that the latest state is reflected in the cursor.
Returns true
if the configuration was successfully loaded.
Returns null
on error, e.g. if the requested configuration does not exist.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to load, e.g. |
rename(config, section, option_or_name, nameopt) → {boolean}nullable
Rename an option or section in given configuration.
When invoked with four arguments, the function renames the given option within the specified section of the given configuration to the provided value.
When invoked with three arguments, the function renames the entire specified section to the provided value.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the true
if specified option or section has been renamed.
Returns null
on error, e.g. if the targeted configuration was not found or if an invalid value was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to rename values in, e.g. |
section | string | The section name to rename or to rename an option in. |
option_or_name | string | The option name to rename within the section or, when the subsequent name argument is omitted, the new name of the renamed section within the configuration. |
name | string | (optional) The new name of the option to rename. |
const ctx = cursor(…);
// Assign explicit name to last anonymous firewall rule section
ctx.rename('firewall', '@rule[-1]', 'my_block_rule');
// Rename 'server' to 'orig_server_list' in ntp section of system config
ctx.rename('system', 'ntp', 'server', 'orig_server_list');
// Rename 'wan' interface to 'external'
ctx.rename('network', 'wan', 'external');
reorder(config, section, index) → {boolean}nullable
Reorder sections in given configuration.
The reorder()
function moves a single section by repositioning it to the given index within the configurations section list.
The given configuration is implicitly loaded into the cursor if not already present.
Returns the true
if specified section has been moved.
Returns null
on error, e.g. if the targeted configuration was not found or if an invalid value was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to move the section in, e.g. |
section | string | The section name to move. |
index | number | The target index to move the section to, starting from |
const ctx = cursor(…);
// Query whole firewall config and reorder resulting dict by type and name
const type_order = ['defaults', 'zone', 'forwarding', 'redirect', 'rule'];
const values = ctx.get_all('firewall');
sort(values, (k1, k2, s1, s2) => {
// Get weight from type_order array
let w1 = index(type_order, s1['.type']);
let w2 = index(type_order, s2['.type']);
// For unknown type orders, use type value itself as weight
if (w1 == -1) w1 = s1['.type'];
if (w2 == -1) w2 = s2['.type'];
// Get name from name option, fallback to section name
let n1 = s1.name ?? k1;
let n2 = s2.name ?? k2;
// Order by weight
if (w1 < w2) return -1;
if (w1 > w2) return 1;
// For same weight order by name
if (n1 < n2) return -1;
if (n1 > n2) return 1;
return 0;
});
// Sequentially reorder sorted sections in firewall configuration
let position = 0;
for (let sid in values)
ctx.reorder('firewall', sid, position++);
revert(configopt) → {boolean}nullable
Revert accumulated cursor changes and associated delta records.
The revert()
function discards any changes made to in-memory copies of loaded configuration files and discards any related existing delta records in the cursors configured delta directory.
When the optional "config" parameter is omitted, all currently loaded configuration files with either present delta records or yet unsaved cursor changes are reverted.
Returns the true
if operation completed successfully.
Returns null
on error, e.g. if the requested configuration was not loaded or when a file system error occurred.
Name | Type | Description |
---|---|---|
config | string | (optional) The name of the configuration file to revert, e.g. |
const ctx = cursor(…);
ctx.set('system', '@system[0]', 'hostname', 'example.org');
ctx.revert('system');
- See
save(configopt) → {boolean}nullable
Save accumulated cursor changes to delta directory.
The save()
function writes consolidated changes made to in-memory copies of loaded configuration files to the uci delta directory which effectively makes them available to other processes using the same delta directory path as well as the uci changes
cli command when using the default delta directory.
Note that uci deltas are overlayed over the actual configuration file values so they're reflected by get()
, foreach()
etc. even if the underlying configuration files are not actually changed (yet). The delta records may be either permanently merged into the configuration by invoking commit()
or reverted through revert()
in order to restore the current state of the underlying configuration file.
When the optional "config" parameter is omitted, delta records for all currently loaded configuration files are written.
In case that neither sharing changes with other processes nor any revert functionality is required, changes may be committed directly using commit()
instead, bypassing any delta record creation.
Returns the true
if operation completed successfully.
Returns null
on error, e.g. if the requested configuration was not loaded or when a file system error occurred.
Name | Type | Description |
---|---|---|
config | string | (optional) The name of the configuration file to save delta records for, e.g. |
const ctx = cursor(…);
ctx.set('wireless', '@wifi-iface[0]', 'disabled', '1');
ctx.save('wireless');
set(config, section, option_or_type, valueopt) → {boolean}nullable
Set option value or add named section in given configuration.
When invoked with four arguments, the function sets the value of the given option within the specified section of the given configuration to the provided value. A value of ""
(empty string) can be used to delete an existing option.
When invoked with three arguments, the function adds a new named section to the given configuration, using the specified type.
In either case, the given configuration is implicitly loaded into the cursor if not already present.
Returns the true
if the named section was added or the specified option was set.
Returns null
on error, e.g. if the targeted configuration was not found or if an invalid value was passed.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to set values in, e.g. |
section | string | The section name to create or set a value in. |
option_or_type | string | The option name to set within the section or, when the subsequent value argument is omitted, the type of the section to create within the configuration. |
value | (string|boolean|number)[] | | (optional) The option value to set. |
const ctx = cursor(…);
// Add named `config interface guest` section
ctx.set('network', 'guest', 'interface');
// Set values on the newly added section
ctx.set('network', 'guest', 'proto', 'static');
ctx.set('network', 'guest', 'ipaddr', '10.0.0.1/24');
ctx.set('network', 'guest', 'dns', ['8.8.4.4', '8.8.8.8']);
…
// Delete 'disabled' option in first wifi-iface section
ctx.set('wireless', '@wifi-iface[0]', 'disabled', '');
unload(config) → {boolean}nullable
Explicitly unload configuration file.
The unload()
function forcibly discards a loaded configuration state from the cursor so that the next attempt to read or modify that configuration will load it anew from the file system.
Returns true
if the configuration was successfully unloaded.
Returns false
if the configuration was not loaded to begin with.
Returns null
on error, e.g. if the requested configuration does not exist.
Name | Type | Description |
---|---|---|
config | string | The name of the configuration file to unload. |
Type Definitions
ChangeRecord: string[]
A uci change record is a plain array containing the change operation name as first element, the affected section ID as second argument and an optional third and fourth argument whose meanings depend on the operation.
Name | Type | Description |
---|---|---|
0 | string | The operation name - may be one of |
1 | string | The section ID targeted by the operation. |
2 | string | The meaning of the third element depends on the operation.
|
4 | string | The meaning of the fourth element depends on the operation.
|
SectionCallback(section): function
The sections callback is invoked for each section found within the given configuration and receives the section object and its associated name as arguments.
Name | Type | Description |
---|---|---|
section | SectionObject | The section object. |
SectionObject: Object<string: (boolean|number|string|string[])>
A section object represents the options and their corresponding values enclosed within a configuration section, as well as some additional meta data such as sort indexes and internal ID.
Any internal metadata fields are prefixed with a dot which isn't an allowed character for normal option names.
Name | Type | Description |
---|---|---|
.anonymous | boolean | The |
.index | number | The |
.name | string | The |
.type | string | The |
* | string | | A section object may contain an arbitrary number of further properties representing the uci option enclosed in the section. All option property names will be in the form |