doc startup with new upgrade mechanism
This commit is contained in:
parent
9d64ddd305
commit
f4a19f6371
1 changed files with 120 additions and 27 deletions
139
doc/startup.md
139
doc/startup.md
|
|
@ -3,12 +3,13 @@
|
||||||
* [Background](#background)
|
* [Background](#background)
|
||||||
* [Modes](#modes)
|
* [Modes](#modes)
|
||||||
* [Startup configuration](#startup-configuration)
|
* [Startup configuration](#startup-configuration)
|
||||||
* [Model-state](#model-state)
|
* [Module-state](#module-state)
|
||||||
* [Upgrade callback](#upgrade-callback)
|
* [Upgrade callback](#upgrade-callback)
|
||||||
* [Extra XML](#extra-xml)
|
* [Extra XML](#extra-xml)
|
||||||
* [Startup status](#startup-status)
|
* [Startup status](#startup-status)
|
||||||
* [Failsafe mode](#failsafe-mode)
|
* [Failsafe mode](#failsafe-mode)
|
||||||
* [Repair](#repair)
|
* [Repair](#repair)
|
||||||
|
* [Automatic upgrades](#automatic-upgrades)
|
||||||
* [Flowcharts](#flowcharts)
|
* [Flowcharts](#flowcharts)
|
||||||
* [Thanks](#thanks)
|
* [Thanks](#thanks)
|
||||||
* [References](#references)
|
* [References](#references)
|
||||||
|
|
@ -28,6 +29,11 @@ Notes on this document:
|
||||||
|
|
||||||
## Modes
|
## Modes
|
||||||
|
|
||||||
|
Clixon by default supports the Netconf `startup` feature. But a clixon
|
||||||
|
system nevertheless can be started in four different ways, starting
|
||||||
|
from the `startup` datastore is mainly only an option on reboot of a
|
||||||
|
system.
|
||||||
|
|
||||||
When the Clixon backend starts, it can start in one of four modes:
|
When the Clixon backend starts, it can start in one of four modes:
|
||||||
* `startup`: The configuration is loaded from a persistent `startup` datastore. The XML is loaded, parsed, validated and committed into the running database.
|
* `startup`: The configuration is loaded from a persistent `startup` datastore. The XML is loaded, parsed, validated and committed into the running database.
|
||||||
* `running`: Similar to `startup`, but instead the `running` datastore is used as a persistent database. The system copies the original running-db to a temporary store(tmp_db), and commits that temporary datastore into the (new) running datastore.
|
* `running`: Similar to `startup`, but instead the `running` datastore is used as a persistent database. The system copies the original running-db to a temporary store(tmp_db), and commits that temporary datastore into the (new) running datastore.
|
||||||
|
|
@ -58,7 +64,7 @@ If yang-models do not match, an `upgrade` callback is made.
|
||||||
|
|
||||||
If any errors are detected, the backend enters a `failsafe` mode.
|
If any errors are detected, the backend enters a `failsafe` mode.
|
||||||
|
|
||||||
## Model-state
|
## Module-state
|
||||||
|
|
||||||
Clixon has the ability to store Yang module-state information according to
|
Clixon has the ability to store Yang module-state information according to
|
||||||
RFC7895 in the datastores. Including yang module-state in the
|
RFC7895 in the datastores. Including yang module-state in the
|
||||||
|
|
@ -101,35 +107,106 @@ Example of a (simplified) datastore with Yang module-state:
|
||||||
|
|
||||||
## Upgrade callback
|
## Upgrade callback
|
||||||
|
|
||||||
If the module-state of the startup configuration does not match the
|
This section describes how a user can write upgrade callbacks for data
|
||||||
module-state of the backend daemon, an _upgrade_ callback is
|
modeled by outdated Yang models. The scenario is that a Clixon system
|
||||||
made. This allows the user to automatically upgrade the XML to the
|
is started with a set of current yang models, but loads a datastore
|
||||||
recent version. As a hint, the module-state differences is passed to
|
with old or even obsolete data.
|
||||||
the callback.
|
|
||||||
|
|
||||||
Example upgrade callback:
|
Note that this feature is only available if
|
||||||
|
[module-state](module-state) in the datastore is enabled.
|
||||||
|
|
||||||
|
If the module-state of the startup configuration does not match the
|
||||||
|
module-state of the backend daemon, a set of _upgrade_ callbacks are
|
||||||
|
made. This allows a user to program upgrade funtions in the backend
|
||||||
|
plugins to automatically upgrade the XML to the current version.
|
||||||
|
|
||||||
|
Clixon also has a system-provided [automatic upgrading method](#automatic-upgrades) based on Yang changelogs covered in a separate chapter.
|
||||||
|
|
||||||
|
A user registers upgrade callbacks based on module and revision
|
||||||
|
ranges. A user can register many callbacks, or choose wildcards.
|
||||||
|
When an upgrade occurs, the callbacks will be called if they match the
|
||||||
|
module and revision ranges registered.
|
||||||
|
|
||||||
|
Different strategies can be used for upgrade functions. One
|
||||||
|
coarse-grained method is to register a single callback to handle all
|
||||||
|
modules and all revisions.
|
||||||
|
|
||||||
|
A fine-grained method is to register a separate _stepwise_ upgrade
|
||||||
|
callback per module and revision range that will be called in a series.
|
||||||
|
|
||||||
|
### Registering a callback
|
||||||
|
|
||||||
|
A user registers upgrade callbacks in the backend `clixon_plugin_init()` function. The signature of upgrade callback is as follows:
|
||||||
```
|
```
|
||||||
/*! Upgrade configuration from one version to another
|
int upgrade_callback_register(clicon_handle h,
|
||||||
|
clicon_upgrade_cb cb,
|
||||||
|
char *namespace,
|
||||||
|
uint32_t from,
|
||||||
|
uint32_t to,
|
||||||
|
void *arg)
|
||||||
|
```
|
||||||
|
where:
|
||||||
|
* `h` is the Clicon handle,
|
||||||
|
* `cb` is the actual callback,
|
||||||
|
* `namespace` defines a Yang module. NULL denotes all modules.
|
||||||
|
* `revision` is the revision date to where the upgrade is made. It is either the same revision as the Clixon system module, but can also be an older version, provided the user also supplies an upgrade function to the most recent revision. If revision is `0` it means that this module is not present in the system and is _obsolete_.
|
||||||
|
* `from` is a revision date indicated an optional start date of the upgrade. This allows for defining a partial upgrade. It can also be `0` to denote any old version.
|
||||||
|
* `arg` is a user defined argument which can be passed to the callback.
|
||||||
|
|
||||||
|
Catch-all upgrade:
|
||||||
|
```
|
||||||
|
upgrade_callback_register(h, yang_changelog_upgrade, NULL, 0, 0, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
Fine-grained stepwise upgrades of a single module A:
|
||||||
|
```
|
||||||
|
upgrade_callback_register(h, upgrade_a_1, "urn:example:a",
|
||||||
|
20171201, 20180101, NULL);
|
||||||
|
upgrade_callback_register(h, upgrade_a_2, "urn:example:a",
|
||||||
|
20180101, 20190101, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
In the latter case, one upgrade function updates data modelled by `A`
|
||||||
|
from revision 2017-12-01 to 2018-01-01; a separate one updates from
|
||||||
|
2018-01-01 to 2019-01-01.
|
||||||
|
|
||||||
|
### Upgrade callback
|
||||||
|
|
||||||
|
When Clixon loads a startup datastore with outdated modules, the matching
|
||||||
|
upgrade callbacks will be called.
|
||||||
|
|
||||||
|
Note the following:
|
||||||
|
* Upgrade callbacks will not be called for data that is up-to-date with the current system
|
||||||
|
* Upgrade callbacks will not be called if there is no module-state in the datastore, or if module-state support is disabled.
|
||||||
|
* Upgrade callbacks will be called if the datastore contains a version of a module that is older than the module loaded in Clixon.
|
||||||
|
* Upgrade callbacks will also be called if the datastore contains a version of a module that is not present in Clixon - an obsolete module.
|
||||||
|
|
||||||
|
An example upgrade callback:
|
||||||
|
```
|
||||||
|
/*! Automatic upgrade of module A
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] xms Module state differences
|
* @param[in] xn XML tree to be updated
|
||||||
* @retval 0 OK
|
* @param[in] modname Name of module
|
||||||
|
* @param[in] modns Namespace of module (for info)
|
||||||
|
* @param[in] from From revision on the form YYYYMMDD
|
||||||
|
* @param[in] to To revision on the form YYYYMMDD (0 not in system)
|
||||||
|
* @param[in] arg User argument given at rpc_callback_register()
|
||||||
|
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||||
|
* @retval 1 OK
|
||||||
|
* @retval 0 Invalid
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
example_upgrade(clicon_handle h,
|
upgrade_a_1(clicon_handle h,
|
||||||
cxobj *xms)
|
cxobj *xn,
|
||||||
|
char *namespace,
|
||||||
|
uint32_t from,
|
||||||
|
uint32_t to,
|
||||||
|
void *arg,
|
||||||
|
cbuf *cbret)
|
||||||
{
|
{
|
||||||
if (xms)
|
return 1;
|
||||||
clicon_log_xml(LOG_NOTICE, xms, "%s", __FUNCTION__);
|
|
||||||
// Perform upgrade of startup XML
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static clixon_plugin_api api = {
|
|
||||||
"example", /* name */
|
|
||||||
...
|
|
||||||
.ca_upgrade=example_upgrade, /* upgrade configuration */
|
|
||||||
};
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the example shown is only a template for an upgrade
|
Note that the example shown is only a template for an upgrade
|
||||||
|
|
@ -254,6 +331,22 @@ Finally, the candidate is validate and committed:
|
||||||
|
|
||||||
The example shown in this Section is also available as a regression [test script](../test/test_upgrade_repair.sh).
|
The example shown in this Section is also available as a regression [test script](../test/test_upgrade_repair.sh).
|
||||||
|
|
||||||
|
## Automatic upgrades
|
||||||
|
|
||||||
|
Clixon supports an experimental yang changelog feature based on
|
||||||
|
draft-wang-netmod-module-revision-management-01 (Zitao Wang et al)
|
||||||
|
where changes to the Yang model are documented and loaded into
|
||||||
|
Clixon.
|
||||||
|
|
||||||
|
When upgrading, the system parses the changelog and tries to upgrade
|
||||||
|
the datastore automatically. This featire is experimental and has
|
||||||
|
several limitations.
|
||||||
|
|
||||||
|
You enable the automatic upgrading by registering the changelog upgrade method:
|
||||||
|
```
|
||||||
|
upgrade_callback_register(h, yang_changelog_upgrade, NULL, 0, 0, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
## Flowcharts
|
## Flowcharts
|
||||||
|
|
||||||
This section contains "pseudo" flowcharts showing the dynamics of
|
This section contains "pseudo" flowcharts showing the dynamics of
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue