diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index e5653cd8..0673d651 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -918,6 +918,7 @@ main(int argc, if (ret != 1) if (xmldb_copy(h, "tmp", "running") < 0) goto done; + xmldb_delete(h, "tmp"); if (ret2status(ret, &status) < 0) goto done; break; diff --git a/apps/backend/backend_startup.c b/apps/backend/backend_startup.c index a5695cde..6052de51 100644 --- a/apps/backend/backend_startup.c +++ b/apps/backend/backend_startup.c @@ -312,8 +312,9 @@ startup_extraxml(clicon_handle h, if (ret == 1) goto ok; xt = NULL; - /* Validate the tmp db and return possibly upgraded xml in xt - */ + /* Clear db cache so that it can be read by startup */ + xmldb_clear(h, tmp_db); + /* Validate the tmp db and return possibly upgraded xml in xt */ if ((ret = startup_validate(h, tmp_db, &xt, cbret)) < 0) goto done; if (ret == 0) diff --git a/example/main/example_backend.c b/example/main/example_backend.c index 1e728857..7aa4bef7 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -1194,31 +1194,35 @@ upgrade_interfaces(clicon_handle h, * This involves creating default configuration files for various daemons, set interface * flags etc. * @param[in] h Clicon handle - * @param[in] db Name of database. Not may be other than "running" - * In this example, a loopback interface is added - * @note This assumes example yang with interfaces/interface + * @param[in] db Name of database. Not3 may be other than "running" + * In this example, a loopback parameter is added */ int example_reset(clicon_handle h, const char *db) { - int retval = -1; - cxobj *xt = NULL; - int ret; - cbuf *cbret = NULL; + int retval = -1; + cxobj *xt = NULL; + int ret; + cbuf *cbret = NULL; yang_stmt *yspec; + cxobj *xerr = NULL; if (!_reset) goto ok; /* Note not enabled by default */ yspec = clicon_dbspec_yang(h); - if (clixon_xml_parse_string("" - "loex:loopback" - "", YB_MODULE, yspec, &xt, NULL) < 0) - goto done; - /* Replace parent w first child */ - if (xml_rootchild(xt, 0, &xt) < 0) + /* Parse extra XML */ + if ((ret = clixon_xml_parse_string("" + "loopback99" + "
", YB_MODULE, yspec, &xt, &xerr)) < 0) goto done; + if (ret == 0){ + clicon_debug_xml(1, xerr, "Error when parsing XML"); + goto ok; + } + /* xmldb_put requires modification tree to be: ... */ + xml_name_set(xt, "config"); if ((cbret = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; @@ -1236,6 +1240,8 @@ example_reset(clicon_handle h, done: if (cbret) cbuf_free(cbret); + if (xerr) + xml_free(xerr); if (xt != NULL) xml_free(xt); return retval; diff --git a/test/test_plugin_reset.sh b/test/test_plugin_reset.sh new file mode 100755 index 00000000..af6ec584 --- /dev/null +++ b/test/test_plugin_reset.sh @@ -0,0 +1,209 @@ +#!/usr/bin/env bash +# Test plugin reset functionality +# First go through all startup modes and modstate true/false and add a loopback XML +# in reset +# Then do the same with an outdated modstate requiring upgrade + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example +cfg=$dir/conf_yang.xml +fyang=$dir/example@2020-01-01.yang +changelog=$dir/changelog.xml # Module revision changelog + +# Create configuration +cat < $cfg + + /usr/local/etc/clixon.xml + *:* + ietf-netconf:startup + ${YANG_INSTALLDIR} + $dir + $fyang + hello + /usr/local/lib/hello/clispec + /usr/local/var/hello.sock + /usr/local/var/hello.pidfile + /usr/local/lib/$APPNAME/backend + $dir + false + false + $changelog + false + +EOF + +cat < $fyang +module clixon-example { + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2020-01-01 { + description + "Clixon hello world example"; + } + revision 2010-01-01 { + description + "Clixon hello world example"; + } + container table{ + list parameter{ + key name; + leaf name{ + type string; + } + leaf value{ + type string; + } + } + } +} +EOF + +cat < $changelog + + + urn:example:clixon + 2010-01-01 + 2020-01-01 + + rename foo to value + rename + /ex:table/ex:parameter/ex:foo + "value" + + + +EOF + +# Start and stop backend with reset function that adds extraxml +# Args: +# 1: db Startup db +# 2: mode Startup mode (init, startup, running, none) +# 3: modstate true: Add yang-lib modstate to sytartup file +# 4: outdated true: Outdated modstate requires upgrade +function testrun() +{ + db=$1 + mode=$2 + modstate=$3 + outdated=$4 + + if $outdated; then + TAG=foo + REV=2010-01-01 + else + TAG=value + REV=2020-01-01 + fi + if [ -n "$db" ]; then + sudo rm $dir/$db + cat < $dir/$db +<${DATASTORE_TOP}> + + + x + <$TAG>42 + +
+EOF + if $modstate; then + cat <> $dir/$db + + 42 + + default + + clixon-example + $REV + urn:example:clixon + + + +EOF + fi + cat <> $dir/$db + +EOF + fi + + # Bring your own backend + if [ $BE -ne 0 ]; then + # kill old backend (if any) + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s $mode -f $cfg -o CLICON_XMLDB_MODSTATE=$modstate -o CLICON_XML_CHANGELOG=$outdated -- -r" + start_backend -s $mode -f $cfg -o CLICON_XMLDB_MODSTATE=$modstate -o CLICON_XML_CHANGELOG=$outdated -- -r + fi + + new "wait backend" + wait_backend + + if [ -n "$db" ]; then + XMLDB="x42" + else + XMLDB="" + fi + XML="loopback99$XMLDB
" + + new "get config" + expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "$XML" + + if [ $BE -ne 0 ]; then + new "Kill backend" + # Check if premature kill + pid=$(pgrep -u root -f clixon_backend) + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg + fi +} + +new "test params: -f $cfg" + +new "Startup and modstate" +testrun startup_db startup true false + +new "Startup and no modstate" +testrun startup_db startup false false + +new "Running and modstate" +testrun running_db running true false + +new "Running and no modstate" +testrun running_db running false false + +new "Init and modstate" +testrun "" init true false + +new "Init and no modstate" +testrun "" init false false + +new "None and modstate" +testrun "" none true false + +new "None and no modstate" +testrun "" none false false + +new "Startup and old modstate" +testrun startup_db startup true true + +new "Running and old modstate" +testrun running_db running true true + +new "Init and old modstate" +testrun "" init true true + +new "None and modstate" +testrun "" none true true + +rm -rf $dir + +new "endtest" +endtest