diff --git a/CHANGELOG.md b/CHANGELOG.md index 959955b2..b572922e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,8 @@ Users may have to change how they access the system ### Minor features +* Added new startup-mode: `running-startup`: First try running db, if it is empty try startup db. + * See [Can startup mode to be extended to support running-startup mode? #234](https://github.com/clicon/clixon/issues/234) * Restconf: added inline configuration using `-R ` command line as an alternative to making advanced restconf configuration * [Need an option to disable restconf mandatory action of overwriting startup_db #230](https://github.com/clicon/clixon/issues/230) * Configure option `CLICON_RESTCONF_STARTUP_DONTUPDATE` added to disable RFC 8040 mandatory copy of running to startup after commit diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 03529fbd..47931b42 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -854,17 +854,24 @@ main(int argc, goto done; } /* Check that netconf :startup is enabled */ - if (startup_mode == SM_STARTUP && + if ((startup_mode == SM_STARTUP || startup_mode == SM_RUNNING_STARTUP) && !if_feature(yspec, "ietf-netconf", "startup")){ clicon_log(LOG_ERR, "Startup mode selected but Netconf :startup feature is not enabled. Enable with option: ietf-netconf:startup"); goto done; } /* Init running db if it is not there + * change running_startup -> running or startup depending on if running exists or not */ - if (xmldb_exists(h, "running") != 1) + if (xmldb_exists(h, "running") != 1){ + if (startup_mode == SM_RUNNING_STARTUP) + startup_mode = SM_STARTUP; if (xmldb_create(h, "running") < 0) return -1; + } + else + if (startup_mode == SM_RUNNING_STARTUP) + startup_mode = SM_RUNNING; xmldb_delete(h, "candidate"); /* If startup fails, lib functions report invalidation info in a cbuf */ if ((cbret = cbuf_new()) == NULL){ @@ -909,6 +916,9 @@ main(int argc, if (ret2status(ret, &status) < 0) goto done; /* if status = STARTUP_INVALID, cbret contains info */ + break; + default:; + break; } /* Quit after upgrade catch-all, running/startup quits in upgrade code */ if (clicon_quit_upgrade_get(h) == 1) diff --git a/lib/clixon/clixon_options.h b/lib/clixon/clixon_options.h index d9d39ec2..72073f09 100644 --- a/lib/clixon/clixon_options.h +++ b/lib/clixon/clixon_options.h @@ -82,10 +82,11 @@ typedef enum genmodel_type genmodel_type; /*! See clixon-config.yang type startup_mode */ enum startup_mode_t{ - SM_NONE=0, - SM_STARTUP, - SM_RUNNING, - SM_INIT + SM_NONE=0, /* Do not touch running state */ + SM_INIT, /* Initialize running state */ + SM_RUNNING, /* Commit running db configuration into running state */ + SM_STARTUP, /* Commit startup configuration into running state */ + SM_RUNNING_STARTUP /* First try running db, if it is empty try startup db */ }; /*! See clixon-config.yang type priv_mode (privileges mode) */ diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index 5c9c7188..57a67e0a 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -1218,8 +1218,14 @@ xml_yang_validate_all(clicon_handle h, goto done; if (!nr){ ye = yang_find(yc, Y_ERROR_MESSAGE, NULL); + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + cprintf(cb, "Failed MUST xpath '%s' of '%s' in module %s", + xpath, xml_name(xt), yang_argument_get(ys_module(ys))); if (netconf_operation_failed_xml(xret, "application", - ye?yang_argument_get(ye):"must xpath validation failed") < 0) + ye?yang_argument_get(ye):cbuf_get(cb)) < 0) goto done; goto fail; } diff --git a/lib/src/clixon_xpath_eval.c b/lib/src/clixon_xpath_eval.c index 6c6e9449..7c75ad1c 100644 --- a/lib/src/clixon_xpath_eval.c +++ b/lib/src/clixon_xpath_eval.c @@ -140,7 +140,7 @@ nodetest_eval_node(cxobj *x, retval = 0; /* no match */ goto done; } - /* here names are equal + /* Here names are equal * Now look for namespaces * 1) prefix1 and prefix2 point to same namespace <<-- try this first * 2) prefix1 is equal to prefix2 <<-- then try this @@ -345,7 +345,8 @@ xp_eval_step(xp_ctx *xc0, if (ret == 0){/* regular code, no optimization made */ while ((x = xml_child_each(xv, x, CX_ELMNT)) != NULL) { /* xs->xs_c0 is nodetest */ - if (nodetest == NULL || nodetest_eval(x, nodetest, nsc, localonly) == 1){ + if (nodetest == NULL || + nodetest_eval(x, nodetest, nsc, localonly) == 1){ if (cxvec_append(x, &vec, &veclen) < 0) goto done; } diff --git a/test/test_yang_deviation.sh b/test/test_yang_deviation.sh index 17a16be7..d4749b32 100755 --- a/test/test_yang_deviation.sh +++ b/test/test_yang_deviation.sh @@ -101,7 +101,7 @@ function testrun() if $mustdate; then # fail since there is neither date or daytime (delete rule) new "netconf validate expect error" - expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrormust xpath validation failed]]>]]>$" + expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorFailed MUST xpath 'daytime or time' of 'system' in module example-base]]>]]>$" else new "netconf validate ok" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "]]>]]" diff --git a/yang/clixon/clixon-config@2021-05-20.yang b/yang/clixon/clixon-config@2021-05-20.yang index 947880ac..7dafd4bf 100644 --- a/yang/clixon/clixon-config@2021-05-20.yang +++ b/yang/clixon/clixon-config@2021-05-20.yang @@ -181,6 +181,10 @@ module clixon-config { "Commit startup configuration into running state After reboot when no persistent running db exists"; } + enum running-startup{ + description + "First try running db, if it is empty try startup db."; + } } } typedef datastore_format{