Disabled key-value datastore; Removed mandatory requirements for BACKEND, NETCONF, RESTCONF and CLI dirs
This commit is contained in:
parent
13377da34e
commit
548ffd2da6
21 changed files with 64 additions and 55 deletions
|
|
@ -26,6 +26,8 @@ clixon_cli -f /usr/local/etc/routing.conf -1x
|
|||
Backward compatibility is enabled by defining BACKEND_STARTUP_BACKWARD_COMPAT in include/clixon_custom.h
|
||||
|
||||
### Minor changes:
|
||||
* Disabled key-value datastore. Enable with --with-keyvalue
|
||||
* Removed mandatory requirements for BACKEND, NETCONF, RESTCONF and CLI dirs.
|
||||
* When user callbacks such as statedata() call returns -1, clixon_backend no
|
||||
longer silently exits. Instead a log is printed and an RPC error is returned.
|
||||
* Added Floating point and negative number support to JSON
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ usage(char *argv0, clicon_handle h)
|
|||
" -1\t\tRun once and then quit (dont wait for events)\n"
|
||||
" -u <path>\tConfig UNIX domain path / ip address (default: %s)\n"
|
||||
" -P <file>\tPid filename (default: %s)\n"
|
||||
" -s <mode>\tSpecify backend startup mode: none|startup|running|init (replaces -IRCc:r:\n"
|
||||
" -s <mode>\tSpecify backend startup mode: none|startup|running|init (replaces -IRCr\n"
|
||||
" -c <file>\tLoad extra xml configuration, but don't commit.\n"
|
||||
#ifdef BACKEND_STARTUP_BACKWARD_COMPAT
|
||||
" -I\t\tInitialize running state database\n"
|
||||
|
|
@ -835,7 +835,8 @@ main(int argc, char **argv)
|
|||
) < 0)
|
||||
goto done;
|
||||
#else
|
||||
clicon_log(LOG_ERR, "Startup mode indefined. Specify option CLICON_STARTUP_MODE or specify -s option to clicon_backend.\n");
|
||||
clicon_log(LOG_ERR, "Startup mode undefined. Specify option CLICON_STARTUP_MODE or specify -s option to clicon_backend.\n");
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -431,11 +431,9 @@ plugin_initiate(clicon_handle h)
|
|||
return -1;
|
||||
|
||||
/* Then load application plugins */
|
||||
if ((dir = clicon_backend_dir(h)) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "backend_dir not defined");
|
||||
return -1;
|
||||
}
|
||||
if (backend_plugin_load_dir(h, dir) < 0)
|
||||
dir = clicon_backend_dir(h);
|
||||
/* If backend directory, load the backend plugisn */
|
||||
if (dir && backend_plugin_load_dir(h, dir) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -400,12 +400,6 @@ main(int argc, char **argv)
|
|||
if (yang_spec_main(h, stdout, printspec) < 0)
|
||||
goto done;
|
||||
|
||||
/* Check plugin directory */
|
||||
if (clicon_cli_dir(h) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "clicon_cli_dir not defined");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create tree generated from dataspec. If no other trees exists, this is
|
||||
* the only one.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -366,7 +366,9 @@ done:
|
|||
/*! Load plugins within a directory
|
||||
*/
|
||||
static int
|
||||
cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
|
||||
cli_plugin_load_dir(clicon_handle h,
|
||||
char *dir,
|
||||
cli_syntax_t *stx)
|
||||
{
|
||||
int i;
|
||||
int ndp;
|
||||
|
|
@ -452,10 +454,7 @@ cli_syntax_load (clicon_handle h)
|
|||
return 0;
|
||||
|
||||
/* Format plugin directory path */
|
||||
if ((plugin_dir = clicon_cli_dir(h)) == NULL){
|
||||
clicon_err(OE_FATAL, 0, "clicon_cli_dir not set");
|
||||
goto quit;
|
||||
}
|
||||
plugin_dir = clicon_cli_dir(h);
|
||||
clispec_dir = clicon_clispec_dir(h);
|
||||
clispec_file = clicon_option_str(h, "CLICON_CLISPEC_FILE");
|
||||
|
||||
|
|
@ -474,7 +473,7 @@ cli_syntax_load (clicon_handle h)
|
|||
goto quit;
|
||||
|
||||
/* Then load application plugins */
|
||||
if (cli_plugin_load_dir(h, plugin_dir, stx) < 0)
|
||||
if (plugin_dir && cli_plugin_load_dir(h, plugin_dir, stx) < 0)
|
||||
goto quit;
|
||||
|
||||
if (clispec_file){
|
||||
|
|
|
|||
|
|
@ -286,8 +286,6 @@ static void
|
|||
usage(clicon_handle h,
|
||||
char *argv0)
|
||||
{
|
||||
char *netconfdir = clicon_netconf_dir(h);
|
||||
|
||||
fprintf(stderr, "usage:%s\n"
|
||||
"where options are\n"
|
||||
"\t-h\t\tHelp\n"
|
||||
|
|
@ -298,7 +296,7 @@ usage(clicon_handle h,
|
|||
"\t-S\t\tLog on syslog\n"
|
||||
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n",
|
||||
argv0,
|
||||
netconfdir
|
||||
clicon_netconf_dir(h)
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,8 +92,9 @@ netconf_plugin_load(clicon_handle h)
|
|||
char filename[MAXPATHLEN];
|
||||
plghndl_t *handle;
|
||||
|
||||
/* If no DIR defined, then dont load plugins */
|
||||
if ((dir = clicon_netconf_dir(h)) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "clicon_netconf_dir not defined");
|
||||
retval = 0;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ restconf_plugin_load(clicon_handle h)
|
|||
char filename[MAXPATHLEN];
|
||||
|
||||
if ((dir = clicon_restconf_dir(h)) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "clicon_restconf_dir not defined");
|
||||
retval = 0;
|
||||
goto quit;
|
||||
}
|
||||
/* Get plugin objects names from plugin directory */
|
||||
|
|
|
|||
|
|
@ -269,8 +269,6 @@ usage(clicon_handle h,
|
|||
char *argv0)
|
||||
|
||||
{
|
||||
char *restconfdir = clicon_restconf_dir(h);
|
||||
|
||||
fprintf(stderr, "usage:%s [options]\n"
|
||||
"where options are\n"
|
||||
"\t-h \t\tHelp\n"
|
||||
|
|
@ -279,7 +277,7 @@ usage(clicon_handle h,
|
|||
"\t-d <dir>\tSpecify restconf plugin directory dir (default: %s)\n"
|
||||
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n",
|
||||
argv0,
|
||||
restconfdir
|
||||
clicon_restconf_dir(h)
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
6
configure
vendored
6
configure
vendored
|
|
@ -1344,7 +1344,7 @@ Optional Packages:
|
|||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||
--with-cligen=dir Use CLIGEN here
|
||||
--without-restconf disable support for restconf
|
||||
--without-keyvalue disable support for key-value xmldb datastore
|
||||
--with-keyvalue enable support for key-value xmldb datastore
|
||||
--with-qdbm=dir Use QDBM here, if keyvalue
|
||||
|
||||
Some influential environment variables:
|
||||
|
|
@ -3943,10 +3943,10 @@ fi
|
|||
if test "${with_keyvalue+set}" = set; then :
|
||||
withval=$with_keyvalue;
|
||||
else
|
||||
with_keyvalue=yes
|
||||
with_keyvalue=no
|
||||
fi
|
||||
|
||||
|
||||
echo "keyvalue:${with_keyvalue}"
|
||||
if test "x${with_keyvalue}" == xyes; then
|
||||
echo "yes keyvalue"
|
||||
# This is for qdbm
|
||||
|
|
|
|||
|
|
@ -138,10 +138,10 @@ fi
|
|||
|
||||
# This is for keyvalue datastore (and qdbm)
|
||||
AC_ARG_WITH([keyvalue],
|
||||
[AS_HELP_STRING([--without-keyvalue],[disable support for key-value xmldb datastore])],
|
||||
[],
|
||||
[with_keyvalue=yes])
|
||||
|
||||
[AS_HELP_STRING([--with-keyvalue],[enable support for key-value xmldb datastore])],
|
||||
[],
|
||||
[with_keyvalue=no])
|
||||
echo "keyvalue:${with_keyvalue}"
|
||||
if test "x${with_keyvalue}" == xyes; then
|
||||
echo "yes keyvalue"
|
||||
# This is for qdbm
|
||||
|
|
|
|||
|
|
@ -881,7 +881,7 @@ text_unlock_all(xmldb_handle xh,
|
|||
int pid)
|
||||
{
|
||||
struct text_handle *th = handle(xh);
|
||||
char **keys;
|
||||
char **keys = NULL;
|
||||
size_t klen;
|
||||
int i;
|
||||
int *val;
|
||||
|
|
@ -893,6 +893,8 @@ text_unlock_all(xmldb_handle xh,
|
|||
if ((val = hash_value(th->th_dbs, keys[i], &vlen)) != NULL &&
|
||||
*val == pid)
|
||||
hash_del(th->th_dbs, keys[i]);
|
||||
if (keys)
|
||||
free(keys);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ route_count(clicon_handle h,
|
|||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see xmldb_get
|
||||
* @note this example code returns a static statedata used in testing.
|
||||
* Real code would poll state
|
||||
*/
|
||||
int
|
||||
plugin_statedata(clicon_handle h,
|
||||
|
|
@ -162,15 +164,11 @@ plugin_statedata(clicon_handle h,
|
|||
int retval = -1;
|
||||
cxobj **xvec = NULL;
|
||||
|
||||
fprintf(stderr, "%s xpath:%s\n", __FUNCTION__, xpath);
|
||||
/* Example of (static) statedata, real code would poll state */
|
||||
if (xml_parse("<interfaces-state><interface>"
|
||||
"<name>eth0</name>"
|
||||
"<type>eth</type>"
|
||||
"<admin-status>up</admin-status>"
|
||||
"<oper-status>up</oper-status>"
|
||||
"<if-index>42</if-index>"
|
||||
"<speed>1000000000</speed>"
|
||||
"</interface></interfaces-state>", xstate) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
|
|
@ -218,6 +216,7 @@ plugin_init(clicon_handle h)
|
|||
* @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
|
||||
*/
|
||||
int
|
||||
plugin_reset(clicon_handle h,
|
||||
|
|
@ -239,7 +238,7 @@ plugin_reset(clicon_handle h,
|
|||
retval = 0;
|
||||
done:
|
||||
if (xt != NULL)
|
||||
free(xt);
|
||||
xml_free(xt);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,8 @@ clicon_option_readfile_xml(clicon_hash_t *copt,
|
|||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (xt)
|
||||
xml_free(xt);
|
||||
if (f)
|
||||
fclose(f);
|
||||
return retval;
|
||||
|
|
@ -356,7 +358,7 @@ clicon_options_main(clicon_handle h)
|
|||
clicon_hash_t *copt = clicon_options(h);
|
||||
char *suffix;
|
||||
char xml = 0; /* Configfile is xml, otherwise legacy */
|
||||
yang_spec *yspec;
|
||||
yang_spec *yspec = NULL;
|
||||
|
||||
/*
|
||||
* Set configure file if not set by command-line above
|
||||
|
|
@ -380,6 +382,8 @@ clicon_options_main(clicon_handle h)
|
|||
/* Read configfile */
|
||||
if (clicon_option_readfile_xml(copt, configfile, yspec) < 0)
|
||||
goto done;
|
||||
if (yspec)
|
||||
yspec_free(yspec);
|
||||
}
|
||||
else {
|
||||
/* Set default options */
|
||||
|
|
@ -529,6 +533,7 @@ clicon_yang_module_revision(clicon_handle h)
|
|||
return clicon_option_str(h, "CLICON_YANG_MODULE_REVISION");
|
||||
}
|
||||
|
||||
/*! Directory of backend plugins. If null, no plugins are loaded */
|
||||
char *
|
||||
clicon_backend_dir(clicon_handle h)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ xmldb_unlock_all(clicon_handle h,
|
|||
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
|
||||
goto done;
|
||||
}
|
||||
retval =xa->xa_unlock_all_fn(xh, pid);
|
||||
retval = xa->xa_unlock_all_fn(xh, pid);
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ new "netconf edit state operation should fail"
|
|||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
||||
|
||||
new "netconf get state operation"
|
||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf lock/unlock"
|
||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ EOF
|
|||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
echo "clixon_backend -zf $clixon_cf -y $fyang"
|
||||
sudo clixon_backend -zf $clixon_cf -y $fyang
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
. ./lib.sh
|
||||
|
||||
# This is a fixed 'state' implemented in routing_backend. It is always there
|
||||
state='{"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}}'
|
||||
state='{"interfaces-state": {"interface": {"name": "eth0","type": "eth","if-index": "42"}}}'
|
||||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
|
|
@ -47,7 +47,7 @@ new "restconf Add subtree to datastore using POST"
|
|||
expectfn 'curl -sS -X POST -d {"interfaces":{"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}}} http://localhost/restconf/data' ""
|
||||
|
||||
new "restconf Check interfaces eth/0/0 added"
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}}
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","if-index": "42"}}}
|
||||
$'
|
||||
|
||||
new "restconf delete interfaces"
|
||||
|
|
@ -60,7 +60,7 @@ new "restconf Add interfaces subtree eth/0/0 using POST"
|
|||
expectfn 'curl -sS -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces' ""
|
||||
|
||||
new "restconf Check eth/0/0 added"
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}}
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","if-index": "42"}}}
|
||||
$'
|
||||
|
||||
new "restconf Re-post eth/0/0 which should generate error"
|
||||
|
|
@ -86,7 +86,7 @@ new "restconf Add subtree eth/0/0 using PUT"
|
|||
expectfn 'curl -sS -X PUT -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' ""
|
||||
|
||||
new "restconf get subtree"
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","admin-status": "up","oper-status": "up","if-index": "42","speed": "1000000000"}}}
|
||||
expectfn "curl -sS -G http://localhost/restconf/data" '{"interfaces": {"interface": {"name": "eth/0/0","type": "eth","enabled": "true"}},"interfaces-state": {"interface": {"name": "eth0","type": "eth","if-index": "42"}}}
|
||||
$'
|
||||
|
||||
new "restconf operation rpc using POST json"
|
||||
|
|
|
|||
|
|
@ -55,20 +55,20 @@ EOF
|
|||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
sudo clixon_backend -zf $clixon_cf $yang
|
||||
sudo clixon_backend -zf $clixon_cf
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
|
||||
new "start backend"
|
||||
# start new backend
|
||||
sudo clixon_backend -f $clixon_cf $yang -s $mode -c /tmp/config
|
||||
sudo clixon_backend -f $clixon_cf -s $mode -c /tmp/config
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
|
||||
new "Check $mode"
|
||||
expecteof "$clixon_netconf -qf $clixon_cf $yang" '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||
|
||||
new "Kill backend"
|
||||
# Check if still alive
|
||||
|
|
|
|||
|
|
@ -3,12 +3,29 @@
|
|||
|
||||
# include err() and new() functions
|
||||
. ./lib.sh
|
||||
clixon_cf=/tmp/conf_yang.xml
|
||||
|
||||
# For memcheck
|
||||
# clixon_netconf="valgrind --leak-check=full --show-leak-kinds=all clixon_netconf"
|
||||
clixon_netconf=clixon_netconf
|
||||
clixon_cli=clixon_cli
|
||||
|
||||
cat <<EOF > /tmp/conf_yang.xml
|
||||
<config>
|
||||
<CLICON_CONFIGFILE>/tmp/test_yang.xml</CLICON_CONFIGFILE>
|
||||
<CLICON_YANG_DIR>/usr/local/share/routing/yang</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
|
||||
<CLICON_CLISPEC_DIR>/usr/local/lib/routing/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/routing/cli</CLICON_CLI_DIR>
|
||||
<CLICON_CLI_MODE>routing</CLICON_CLI_MODE>
|
||||
<CLICON_SOCK>/usr/local/var/routing/routing.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/routing/routing.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/routing</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
cat <<EOF > /tmp/test.yang
|
||||
module example{
|
||||
container x {
|
||||
|
|
|
|||
|
|
@ -89,18 +89,15 @@
|
|||
}
|
||||
leaf CLICON_BACKEND_DIR {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "Location of backend .so plugins. Load all .so
|
||||
plugins in this dir as backend plugins";
|
||||
}
|
||||
leaf CLICON_NETCONF_DIR {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "Location of netconf (frontend) .so plugins";
|
||||
}
|
||||
leaf CLICON_RESTCONF_DIR {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "Location of restconf (frontend) .so plugins. Load all .so
|
||||
plugins in this dir as restconf code plugins";
|
||||
}
|
||||
|
|
@ -112,7 +109,6 @@
|
|||
}
|
||||
leaf CLICON_CLI_DIR {
|
||||
type string;
|
||||
mandatory true;
|
||||
description "Location of cli frontend .so plugins. Load all .so
|
||||
plugins in this dir as CLI object plugins";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue