Fixed: [Backend can not read datastore with container named config #147](https://github.com/clicon/clixon/issues/147)
This commit is contained in:
parent
07d196dfd0
commit
9087694b58
9 changed files with 51 additions and 61 deletions
|
|
@ -67,6 +67,7 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
|
* Fixed: [Backend can not read datastore with container named "config" #147](https://github.com/clicon/clixon/issues/147)
|
||||||
* Fixed: [The config false leaf shouldn't be configed in startup stage #189](https://github.com/clicon/clixon/issues/189)
|
* Fixed: [The config false leaf shouldn't be configed in startup stage #189](https://github.com/clicon/clixon/issues/189)
|
||||||
* Fixed: [CLIXON is not waiting for the hello message #184](https://github.com/clicon/clixon/issues/184)
|
* Fixed: [CLIXON is not waiting for the hello message #184](https://github.com/clicon/clixon/issues/184)
|
||||||
* See also API changes
|
* See also API changes
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ api_data_write(clicon_handle h,
|
||||||
}
|
}
|
||||||
/* Create a dummy data tree parent to hook in the parsed data.
|
/* Create a dummy data tree parent to hook in the parsed data.
|
||||||
*/
|
*/
|
||||||
if ((xdata0 = xml_new("data0", NULL, CX_ELMNT)) == NULL)
|
if ((xdata0 = xml_new(XML_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (api_path){ /* XXX mv to copy? */
|
if (api_path){ /* XXX mv to copy? */
|
||||||
cxobj *xfrom;
|
cxobj *xfrom;
|
||||||
|
|
@ -357,8 +357,12 @@ api_data_write(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xml_spec(xdata0)==NULL)
|
if (xml_spec(xdata0)==NULL){
|
||||||
yb = YB_MODULE;
|
if (api_path==NULL)
|
||||||
|
yb = YB_MODULE_NEXT; /* data is eg: <data><x> */
|
||||||
|
else
|
||||||
|
yb = YB_MODULE; /* data is eg: <x> */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
yb = YB_PARENT;
|
yb = YB_PARENT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,16 +72,6 @@
|
||||||
*/
|
*/
|
||||||
#define XML_EXPLICIT_INDEX
|
#define XML_EXPLICIT_INDEX
|
||||||
|
|
||||||
/*! Treat <config> and <data> specially in a xmldb datastore.
|
|
||||||
* config/data is treated as a "neutral" tag that does not have a yang spec.
|
|
||||||
* In particular when binding xml to yang, if <config> is encountered as top-of-tree, do not
|
|
||||||
* try to bind a yang-spec to this symbol.
|
|
||||||
* The root of this is GET and PUT commands where the <config> and <data> tag belongs to the
|
|
||||||
* RPC rather than the data.
|
|
||||||
* This is a hack, there must be a way to make this more generic
|
|
||||||
*/
|
|
||||||
#define XMLDB_CONFIG_HACK
|
|
||||||
|
|
||||||
/*! Let state data be ordered-by system
|
/*! Let state data be ordered-by system
|
||||||
* RFC 7950 is cryptic about this
|
* RFC 7950 is cryptic about this
|
||||||
* It says in 7.7.7:
|
* It says in 7.7.7:
|
||||||
|
|
@ -97,6 +87,5 @@
|
||||||
* This is traditionally same as NETCONF_INPUT_CONFIG ("config") but can be different
|
* This is traditionally same as NETCONF_INPUT_CONFIG ("config") but can be different
|
||||||
* If you change this, you need to change test shell variable in lib.sh: DATASTORE_TOP
|
* If you change this, you need to change test shell variable in lib.sh: DATASTORE_TOP
|
||||||
* Consider making this an option or configure option
|
* Consider making this an option or configure option
|
||||||
* see XMLDB_CONFIG_HACK
|
|
||||||
*/
|
*/
|
||||||
#define DATASTORE_TOP_SYMBOL "config"
|
#define DATASTORE_TOP_SYMBOL "config"
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,14 @@ enum cxobj_type {CX_ERROR=-1,
|
||||||
*/
|
*/
|
||||||
enum yang_bind{
|
enum yang_bind{
|
||||||
YB_NONE=0, /* Dont do Yang binding */
|
YB_NONE=0, /* Dont do Yang binding */
|
||||||
YB_MODULE, /* Search for matching yang binding among top-level symbols of Yang modules */
|
YB_MODULE, /* Search for matching yang binding among top-level symbols of Yang modules of direct
|
||||||
|
* children
|
||||||
|
* Ie, xml looks like: <top><x>... where "x" is a top-level symbol in a module
|
||||||
|
*/
|
||||||
|
YB_MODULE_NEXT, /* Search for matching yang binding among top-level symbols of Yang modules of
|
||||||
|
* next-level children
|
||||||
|
* Ie, xml looks like: <top><config><x>... where "x" is a top-level symbol in a module
|
||||||
|
*/
|
||||||
YB_PARENT, /* Assume yang binding of existing parent and match its children by name */
|
YB_PARENT, /* Assume yang binding of existing parent and match its children by name */
|
||||||
YB_RPC, /* Assume top-level xml is an netconf RPC message (or hello) */
|
YB_RPC, /* Assume top-level xml is an netconf RPC message (or hello) */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -462,8 +462,11 @@ xmldb_readfile(clicon_handle h,
|
||||||
if ((ret = clixon_json_parse_file(fp, yb, yspec, &x0, NULL)) < 0) /* XXX: ret == 0*/
|
if ((ret = clixon_json_parse_file(fp, yb, yspec, &x0, NULL)) < 0) /* XXX: ret == 0*/
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else if ((ret = clixon_xml_parse_file(fp, yb, yspec, NULL /* "</config>" XXX */, &x0, NULL)) < 0)
|
else {
|
||||||
goto done;
|
if ((ret = clixon_xml_parse_file(fp, yb, yspec, NULL, &x0, NULL)) < 0){
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef XMLDB_READFILE_FAIL /* The functions calling this function cannot handle a failed parse yet */
|
#ifdef XMLDB_READFILE_FAIL /* The functions calling this function cannot handle a failed parse yet */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -553,7 +556,10 @@ xmldb_get_nocache(clicon_handle h,
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((ret = xmldb_readfile(h, db, YB_MODULE, yspec, &xt, &de0, msdiff)) < 0)
|
/* xml looks like: <top><config><x>... where "x" is a top-level symbol in a module */
|
||||||
|
if ((ret = xmldb_readfile(h, db,
|
||||||
|
yb==YB_MODULE?YB_MODULE_NEXT:yb,
|
||||||
|
yspec, &xt, &de0, msdiff)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -664,7 +670,10 @@ xmldb_get_cache(clicon_handle h,
|
||||||
de = clicon_db_elmnt_get(h, db);
|
de = clicon_db_elmnt_get(h, db);
|
||||||
if (de == NULL || de->de_xml == NULL){ /* Cache miss, read XML from file */
|
if (de == NULL || de->de_xml == NULL){ /* Cache miss, read XML from file */
|
||||||
/* If there is no xml x0 tree (in cache), then read it from file */
|
/* If there is no xml x0 tree (in cache), then read it from file */
|
||||||
if ((ret = xmldb_readfile(h, db, yb, yspec, &x0t, &de0, msdiff)) < 0)
|
/* xml looks like: <top><config><x>... where "x" is a top-level symbol in a module */
|
||||||
|
if ((ret = xmldb_readfile(h, db,
|
||||||
|
yb==YB_MODULE?YB_MODULE_NEXT:yb,
|
||||||
|
yspec, &x0t, &de0, msdiff)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -808,7 +817,10 @@ xmldb_get_zerocopy(clicon_handle h,
|
||||||
de = clicon_db_elmnt_get(h, db);
|
de = clicon_db_elmnt_get(h, db);
|
||||||
if (de == NULL || de->de_xml == NULL){ /* Cache miss, read XML from file */
|
if (de == NULL || de->de_xml == NULL){ /* Cache miss, read XML from file */
|
||||||
/* If there is no xml x0 tree (in cache), then read it from file */
|
/* If there is no xml x0 tree (in cache), then read it from file */
|
||||||
if ((ret = xmldb_readfile(h, db, yb, yspec, &x0t, &de0, msdiff)) < 0)
|
/* xml looks like: <top><config><x>... where "x" is a top-level symbol in a module */
|
||||||
|
if ((ret = xmldb_readfile(h, db,
|
||||||
|
yb==YB_MODULE?YB_MODULE_NEXT:yb,
|
||||||
|
yspec, &x0t, &de0, msdiff)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -947,7 +947,8 @@ xmldb_put(clicon_handle h,
|
||||||
/* If there is no xml x0 tree (in cache), then read it from file */
|
/* If there is no xml x0 tree (in cache), then read it from file */
|
||||||
if (x0 == NULL){
|
if (x0 == NULL){
|
||||||
firsttime++; /* to avoid leakage on error, see fail from text_modify */
|
firsttime++; /* to avoid leakage on error, see fail from text_modify */
|
||||||
if ((ret = xmldb_readfile(h, db, YB_MODULE, yspec, &x0, de, NULL)) < 0)
|
/* xml looks like: <top><config><x>... where "x" is a top-level symbol in a module */
|
||||||
|
if ((ret = xmldb_readfile(h, db, YB_MODULE_NEXT, yspec, &x0, de, NULL)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -1231,10 +1231,7 @@ _json_parse(char *str,
|
||||||
* members of a top-level JSON object
|
* members of a top-level JSON object
|
||||||
*/
|
*/
|
||||||
if (yspec && xml_prefix(x) == NULL
|
if (yspec && xml_prefix(x) == NULL
|
||||||
#ifdef XMLDB_CONFIG_HACK
|
/* && yb != YB_MODULE_NEXT XXX Dont know what this is for */
|
||||||
// && !xml_flag(x, XML_FLAG_TOP)
|
|
||||||
&& strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) != 0
|
|
||||||
#endif
|
|
||||||
){
|
){
|
||||||
if ((cberr = cbuf_new()) == NULL){
|
if ((cberr = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
|
@ -1260,24 +1257,15 @@ _json_parse(char *str,
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
failed++;
|
failed++;
|
||||||
break;
|
break;
|
||||||
|
case YB_MODULE_NEXT:
|
||||||
|
if ((ret = xml_bind_yang(x, YB_MODULE, yspec, xerr)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
failed++;
|
||||||
|
break;
|
||||||
case YB_MODULE:
|
case YB_MODULE:
|
||||||
#ifdef XMLDB_CONFIG_HACK
|
if ((ret = xml_bind_yang0(x, yb, yspec, xerr)) < 0)
|
||||||
if (
|
goto done;
|
||||||
// xml_flag(x, XML_FLAG_TOP)
|
|
||||||
strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) == 0
|
|
||||||
|| strcmp(xml_name(x), NETCONF_OUTPUT_DATA) == 0
|
|
||||||
){
|
|
||||||
/* xt:<top> nospec
|
|
||||||
* x: <config>
|
|
||||||
* <a> <-- populate from modules
|
|
||||||
*/
|
|
||||||
if ((ret = xml_bind_yang(x, yb, yspec, xerr)) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ((ret = xml_bind_yang0(x, yb, yspec, xerr)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
failed++;
|
failed++;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -508,25 +508,16 @@ _xml_parse(const char *str,
|
||||||
failed++;
|
failed++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case YB_MODULE_NEXT:
|
||||||
|
if ((ret = xml_bind_yang(x, YB_MODULE, yspec, xerr)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
failed++;
|
||||||
|
break;
|
||||||
case YB_MODULE:
|
case YB_MODULE:
|
||||||
/* xt:<top> nospec
|
/* xt:<top> nospec
|
||||||
* x: <a> <-- populate from modules
|
* x: <a> <-- populate from modules
|
||||||
*/
|
*/
|
||||||
#ifdef XMLDB_CONFIG_HACK
|
|
||||||
if (
|
|
||||||
// xml_flag(x, XML_FLAG_TOP)
|
|
||||||
strcmp(xml_name(x), DATASTORE_TOP_SYMBOL) == 0
|
|
||||||
|| strcmp(xml_name(x), NETCONF_OUTPUT_DATA) == 0
|
|
||||||
){
|
|
||||||
/* xt:<top> nospec
|
|
||||||
* x: <config>
|
|
||||||
* <a> <-- populate from modules
|
|
||||||
*/
|
|
||||||
if ((ret = xml_bind_yang(x, YB_MODULE, yspec, xerr)) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ((ret = xml_bind_yang0(x, YB_MODULE, yspec, xerr)) < 0)
|
if ((ret = xml_bind_yang0(x, YB_MODULE, yspec, xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
|
|
||||||
|
|
@ -1762,9 +1762,6 @@ assign_namespace_element(cxobj *x0, /* source */
|
||||||
char *prefix0 = NULL;;
|
char *prefix0 = NULL;;
|
||||||
int isroot;
|
int isroot;
|
||||||
|
|
||||||
/* XXX: need to identify root better than hiereustics and strcmp,...
|
|
||||||
* see XMLDB_CONFIG_HACK
|
|
||||||
*/
|
|
||||||
isroot = xml_parent(x1p)==NULL &&
|
isroot = xml_parent(x1p)==NULL &&
|
||||||
xml_flag(x1p, XML_FLAG_TOP) &&
|
xml_flag(x1p, XML_FLAG_TOP) &&
|
||||||
xml_prefix(x1p)==NULL;
|
xml_prefix(x1p)==NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue