From 79eb5fd5f40a75987b22065b64d0aff697046e87 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 2 Apr 2023 16:16:58 +0200 Subject: [PATCH] confd: startup-config hook with support for merging in at bootstrap This change adds a hook to the startup datastore, we use the ietf-system module because the module argument is mandatory. The hook runs when all changes have been saved to the internal store. Since sysrepo has many startup files in /etc/sysrepo, we saving a JSON copy of all these files in /cfg/startup-config.cfg, which is persistent. On system bootstrap this file is merged into the (empty) running datastore, which is what the sysrepo maintainers recommend to be independent of any yang model updates that might occur on image upgrades. Signed-off-by: Joachim Wiberg --- package/confd/sysrepo.conf | 4 +++- src/confd/src/core.c | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/package/confd/sysrepo.conf b/package/confd/sysrepo.conf index d5e00ded..a78d4e56 100644 --- a/package/confd/sysrepo.conf +++ b/package/confd/sysrepo.conf @@ -1,6 +1,8 @@ run if: [S] /lib/infix/clean-etc -- run if: [S] /lib/infix/prep-db -- -service if: name:sysrepo [12345789] sysrepo-plugind -n -- Configuration daemon + +service if: name:sysrepo [S12345789] sysrepo-plugind -p /run/sysrepo.pid -n -- Configuration daemon +run if: [S] log sysrepocfg -v4 -E/cfg/startup-config.cfg -f json -- service if: name:netopeer [12345789] netopeer2-server -n -- NETCONF daemon task if: [12345789] resolvconf -u -- Update DNS configuration diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 1727cace..1d5faa58 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -4,12 +4,24 @@ static struct confd confd; +static int startup_save_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + if (run("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) + return SR_ERR_SYS; + + return SR_ERR_OK; +} + int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) { + sr_session_ctx_t *startup; int rc = SR_ERR_SYS; openlog("confd", LOG_USER, 0); + /* Save context with default running config datastore for all our models */ + *priv = (void *)&confd; confd.session = session; confd.conn = sr_session_get_connection(session); confd.sub = NULL; @@ -21,11 +33,21 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) if (!confd.aug) goto err; - *priv = (void *)&confd; - - if (ietf_system_init(&confd)) + if (rc = ietf_system_init(&confd)) goto err; + /* YOUR_INIT GOES HERE */ + + /* Set up hook to save startup-config to persisten backend store */ + if (rc = sr_session_start(confd.conn, SR_DS_STARTUP, &startup)) + goto err; + + if (rc = sr_module_change_subscribe(startup, "ietf-system", "/ietf-system:system//.", + startup_save_hook, NULL, 0, SR_SUBSCR_PASSIVE | SR_SUBSCR_DONE_ONLY, &confd.sub)) { + ERROR("failed setting up startup-config hook: %s", sr_strerror(rc)); + goto err; + } + return SR_ERR_OK; err: ERROR("init failed: %s", sr_strerror(rc));