Migrated to XML configure file.
This commit is contained in:
parent
a2bfe2bdd2
commit
ca7b4d3d9e
12 changed files with 117 additions and 54 deletions
|
|
@ -11,8 +11,15 @@ Sep 27 18:11:58: Commit failed. Edit and try again or discard changes:
|
|||
protocol invalid-value Missing mandatory variable: type
|
||||
```
|
||||
|
||||
* If clixon config file has .xml ending, yang/clixon-config.yang is used as
|
||||
* Migrated to XML configure file.
|
||||
** If clixon config file has .xml ending, yang/clixon-config.yang is used as
|
||||
model for an xml-based configuration file. Otherwise legacy format is used.
|
||||
** As migration utility from legacy to XML configure file, clixon_cli -x can be used to print new format, eg:
|
||||
|
||||
```
|
||||
clixon_cli -f /usr/local/etc/routing.conf -1x
|
||||
```
|
||||
|
||||
* The clixon config file format has changed. It now uses XML and YANG.
|
||||
Old configuration files work, but you can use the new by setting an .xml suffix.
|
||||
The yang model is yang/clixon-config.yang.
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
#include "cli_handle.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define CLI_OPTS "hD:f:F:1u:d:m:qpGLl:y:"
|
||||
#define CLI_OPTS "hD:f:F:1u:d:m:qpGLl:y:x"
|
||||
|
||||
/*! terminate cli application */
|
||||
static int
|
||||
|
|
@ -109,9 +109,10 @@ cli_signal_init (clicon_handle h)
|
|||
* @param[in] h CLICON handle
|
||||
* @see cligen_loop
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
cli_interactive(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
int res;
|
||||
char *cmd;
|
||||
char *new_mode;
|
||||
|
|
@ -123,11 +124,72 @@ cli_interactive(clicon_handle h)
|
|||
new_mode = cli_syntax_mode(h);
|
||||
if ((cmd = clicon_cliread(h)) == NULL) {
|
||||
cli_set_exiting(h, 1); /* EOF */
|
||||
break;
|
||||
retval = -1;
|
||||
goto done;
|
||||
}
|
||||
if ((res = clicon_parse(h, cmd, &new_mode, &result)) < 0)
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Read file as configuration file and print xml file for migrating to new fmt
|
||||
* @see clicon_option_readfile_xml
|
||||
*/
|
||||
static int
|
||||
dump_configfile_xml_fn(FILE *fout,
|
||||
const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
char opt[1024];
|
||||
char val[1024];
|
||||
char line[1024];
|
||||
char *cp;
|
||||
FILE *f = NULL;
|
||||
int retval = -1;
|
||||
char *suffix;
|
||||
|
||||
if (filename == NULL || !strlen(filename)){
|
||||
clicon_err(OE_UNIX, 0, "Not specified");
|
||||
goto done;
|
||||
}
|
||||
if ((suffix = rindex(filename, '.')) != NULL &&
|
||||
strcmp((suffix+1), "xml") == 0){
|
||||
clicon_err(OE_CFG, 0, "Configfile %s should not be XML", filename);
|
||||
goto done;
|
||||
}
|
||||
if (stat(filename, &st) < 0){
|
||||
clicon_err(OE_UNIX, errno, "%s", filename);
|
||||
goto done;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)){
|
||||
clicon_err(OE_UNIX, 0, "%s is not a regular file", filename);
|
||||
goto done;
|
||||
}
|
||||
if ((f = fopen(filename, "r")) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
||||
return -1;
|
||||
}
|
||||
clicon_debug(2, "Reading config file %s", __FUNCTION__, filename);
|
||||
fprintf(fout, "<config>\n");
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
if ((cp = strchr(line, '\n')) != NULL) /* strip last \n */
|
||||
*cp = '\0';
|
||||
/* Trim out comments, strip whitespace, and remove CR */
|
||||
if ((cp = strchr(line, '#')) != NULL)
|
||||
memcpy(cp, "\n", 2);
|
||||
if (sscanf(line, "%s %s", opt, val) < 2)
|
||||
continue;
|
||||
fprintf(fout, "\t<%s>%s</%s>\n", opt, val, opt);
|
||||
}
|
||||
fprintf(fout, "</config>\n");
|
||||
retval = 0;
|
||||
done:
|
||||
if (f)
|
||||
fclose(f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -142,6 +204,7 @@ usage(char *argv0, clicon_handle h)
|
|||
"\t-h \t\tHelp\n"
|
||||
"\t-D <level> \tDebug\n"
|
||||
"\t-f <file> \tConfig-file (mandatory)\n"
|
||||
"\t-x\t\tDump configuration file as XML on stdout (migration utility)\n"
|
||||
"\t-F <file> \tRead commands from file (default stdin)\n"
|
||||
"\t-1\t\tDo not enter interactive mode\n"
|
||||
"\t-u <sockpath>\tconfig UNIX domain path (default: %s)\n"
|
||||
|
|
@ -178,6 +241,7 @@ main(int argc, char **argv)
|
|||
int len;
|
||||
int logdst = CLICON_LOG_STDERR;
|
||||
char *restarg = NULL; /* what remains after options */
|
||||
int dump_configfile_xml = 0;
|
||||
|
||||
/* Defaults */
|
||||
|
||||
|
|
@ -216,6 +280,9 @@ main(int argc, char **argv)
|
|||
usage(argv[0], h);
|
||||
clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg);
|
||||
break;
|
||||
case 'x': /* dump config file as xml */
|
||||
dump_configfile_xml++;
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
switch (optarg[0]){
|
||||
case 's':
|
||||
|
|
@ -239,6 +306,14 @@ main(int argc, char **argv)
|
|||
|
||||
clicon_debug_init(debug, NULL);
|
||||
|
||||
/* Use cli as util tool to dump config file as xml for migration */
|
||||
if (dump_configfile_xml) {
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
char *configfile = hash_value(copt, "CLICON_CONFIGFILE", NULL);
|
||||
if (dump_configfile_xml_fn(stdout, configfile) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Find and read configfile */
|
||||
if (clicon_options_main(h) < 0){
|
||||
if (help)
|
||||
|
|
@ -254,6 +329,7 @@ main(int argc, char **argv)
|
|||
case 'D' : /* debug */
|
||||
case 'f': /* config file */
|
||||
case 'l': /* Log destination */
|
||||
case 'x': /* dump config file as xml */
|
||||
break; /* see above */
|
||||
case 'F': /* read commands from file */
|
||||
if (freopen(optarg, "r", stdin) == NULL){
|
||||
|
|
@ -326,7 +402,9 @@ main(int argc, char **argv)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Create tree generated from dataspec */
|
||||
/* Create tree generated from dataspec. If no other trees exists, this is
|
||||
* the only one.
|
||||
*/
|
||||
if (clicon_cli_genmodel(h)){
|
||||
yang_spec *yspec; /* yang spec */
|
||||
parse_tree pt = {0,}; /* cli parse tree */
|
||||
|
|
@ -367,10 +445,8 @@ main(int argc, char **argv)
|
|||
fprintf (stderr, "FATAL: No cli mode set (use -m or CLICON_CLI_MODE)\n");
|
||||
goto done;
|
||||
}
|
||||
if (cli_tree(h, cli_syntax_mode(h)) == NULL){
|
||||
fprintf (stderr, "FATAL: No such cli mode: %s\n", cli_syntax_mode(h));
|
||||
goto done;
|
||||
}
|
||||
if (cli_tree(h, cli_syntax_mode(h)) == NULL)
|
||||
clicon_log(LOG_WARNING, "No such cli mode: %s (Specify cli mode with CLICON_CLI_MODE in config file or -m <mode> on command line", cli_syntax_mode(h));
|
||||
|
||||
if (logclisyntax)
|
||||
cli_logsyntax_set(h, logclisyntax);
|
||||
|
|
|
|||
|
|
@ -713,8 +713,9 @@ done:
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read command from CLIgen's cliread() using current syntax mode.
|
||||
/*! Read command from CLIgen's cliread() using current syntax mode.
|
||||
* @retval string char* buffer containing CLIgen command
|
||||
* @retval NULL Fatal error
|
||||
*/
|
||||
char *
|
||||
clicon_cliread(clicon_handle h)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ CLICON_BACKEND_PIDFILE localstatedir/APPNAME/APPNAME.pidfile
|
|||
# CLICON_CLI_GENMODEL 1
|
||||
|
||||
# Generate code for CLI completion of existing db symbols
|
||||
# CLICON_CLI_GENMODEL_COMPLETION 0
|
||||
# CLICON_CLI_GENMODEL_COMPLETION 1
|
||||
|
||||
# How to generate and show CLI syntax: VARS|ALL
|
||||
# CLICON_CLI_GENMODEL_TYPE VARS
|
||||
|
|
|
|||
|
|
@ -12,21 +12,6 @@ CLICON_YANG_MODULE_MAIN example
|
|||
# <module>[@<revision>]
|
||||
#CLICON_YANG_MODULE_REVISION 2014-06-16
|
||||
|
||||
# Generate code for CLI completion of existing db symbols
|
||||
# CLICON_CLI_GENMODEL_COMPLETION 0
|
||||
CLICON_CLI_GENMODEL_COMPLETION 1
|
||||
|
||||
# How to generate and show CLI syntax: VARS|ALL
|
||||
# CLICON_CLI_GENMODEL_TYPE VARS
|
||||
CLICON_CLI_GENMODEL_TYPE VARS
|
||||
|
||||
# Enabled uses "startup" configuration on boot
|
||||
CLICON_USE_STARTUP_CONFIG 0
|
||||
|
||||
# XMLDB datastore plugin filename (see datastore/ and clixon_xml_db.[ch])
|
||||
CLICON_XMLDB_PLUGIN /usr/local/lib/xmldb/text.so
|
||||
#CLICON_XMLDB_PLUGIN /usr/local/lib/xmldb/keyvalue.so
|
||||
|
||||
# Set to 0 if you want CLI to wrap to next line.
|
||||
# Set to 1 if you want CLI to scroll sideways when approaching right margin
|
||||
CLICON_CLI_LINESCROLLING 0
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<CLICON_YANG_DIR>/usr/local/share/routing/yang</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
|
||||
<CLICON_CLI_MODE>routing</CLICON_CLI_MODE>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/routing/backend></CLICON_BACKEND_DIR>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/routing/backend</CLICON_BACKEND_DIR>
|
||||
<CLICON_NETCONF_DIR>/usr/local/lib/routing/netconf</CLICON_NETCONF_DIR>
|
||||
<CLICON_RESTCONF_DIR>/usr/local/lib/routing/restconf</CLICON_RESTCONF_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/routing/cli</CLICON_CLI_DIR>
|
||||
|
|
|
|||
|
|
@ -69,12 +69,11 @@
|
|||
#include "clixon_xsl.h"
|
||||
#include "clixon_xml_map.h"
|
||||
|
||||
/*
|
||||
* clicon_option_dump
|
||||
* Print registry on file. For debugging.
|
||||
/*! Print registry on file. For debugging.
|
||||
*/
|
||||
void
|
||||
clicon_option_dump(clicon_handle h, int dbglevel)
|
||||
clicon_option_dump(clicon_handle h,
|
||||
int dbglevel)
|
||||
{
|
||||
clicon_hash_t *hash = clicon_options(h);
|
||||
int i;
|
||||
|
|
@ -272,7 +271,7 @@ clicon_option_default(clicon_hash_t *copt)
|
|||
goto done;
|
||||
}
|
||||
if (!hash_lookup(copt, "CLICON_CLI_GENMODEL_COMPLETION")){
|
||||
if (hash_add(copt, "CLICON_CLI_GENMODEL_COMPLETION", "0", strlen("0")+1) < 0)
|
||||
if (hash_add(copt, "CLICON_CLI_GENMODEL_COMPLETION", "1", strlen("1")+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Default is to use line-scrolling */
|
||||
|
|
@ -280,18 +279,12 @@ clicon_option_default(clicon_hash_t *copt)
|
|||
if (hash_add(copt, "CLICON_CLI_LINESCROLLING", "1", strlen("1")+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Default is to use line-scrolling */
|
||||
if (!hash_lookup(copt, "CLICON_CLI_LINESCROLLING")){
|
||||
if (hash_add(copt, "CLICON_CLI_LINESCROLLING", "1", strlen("1")+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Check that options are set
|
||||
* XXX dont detect extra XML
|
||||
*/
|
||||
static int
|
||||
clicon_option_sanity(clicon_hash_t *copt)
|
||||
|
|
@ -440,7 +433,7 @@ clicon_option_str_set(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Get options as integer but stored as string
|
||||
|
||||
*
|
||||
* @param h clicon handle
|
||||
* @param name name of option
|
||||
* @retval int An integer as aresult of atoi
|
||||
|
|
@ -465,7 +458,7 @@ clicon_option_int(clicon_handle h, const char *name)
|
|||
return atoi(s);
|
||||
}
|
||||
|
||||
/*! set option given as int.
|
||||
/*! Set option given as int.
|
||||
*/
|
||||
int
|
||||
clicon_option_int_set(clicon_handle h, const char *name, int val)
|
||||
|
|
@ -477,7 +470,7 @@ clicon_option_int_set(clicon_handle h, const char *name, int val)
|
|||
return clicon_option_str_set(h, name, s);
|
||||
}
|
||||
|
||||
/*! delete option
|
||||
/*! Delete option
|
||||
*/
|
||||
int
|
||||
clicon_option_del(clicon_handle h, const char *name)
|
||||
|
|
@ -557,7 +550,7 @@ clicon_xmldb_plugin(clicon_handle h)
|
|||
return clicon_option_str(h, "CLICON_XMLDB_PLUGIN");
|
||||
}
|
||||
|
||||
/* get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */
|
||||
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */
|
||||
int
|
||||
clicon_sock_family(clicon_handle h)
|
||||
{
|
||||
|
|
@ -609,7 +602,7 @@ clicon_master_plugin(clicon_handle h)
|
|||
return clicon_option_str(h, "CLICON_MASTER_PLUGIN");
|
||||
}
|
||||
|
||||
/* return initial clicon cli mode */
|
||||
/*! Return initial clicon cli mode */
|
||||
char *
|
||||
clicon_cli_mode(clicon_handle h)
|
||||
{
|
||||
|
|
@ -630,7 +623,7 @@ clicon_cli_genmodel(clicon_handle h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* How to generate and show CLI syntax: VARS|ALL */
|
||||
/*! How to generate and show CLI syntax: VARS|ALL */
|
||||
enum genmodel_type
|
||||
clicon_cli_genmodel_type(clicon_handle h)
|
||||
{
|
||||
|
|
@ -709,7 +702,7 @@ clicon_cli_genmodel_completion(clicon_handle h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Where are "running" and "candidate" databases? */
|
||||
/*! Where are "running" and "candidate" databases? */
|
||||
char *
|
||||
clicon_xmldb_dir(clicon_handle h)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1504,7 +1504,7 @@ yang_parse_recurse(clicon_handle h,
|
|||
yang_spec *ysp)
|
||||
{
|
||||
yang_stmt *yi = NULL; /* import */
|
||||
yang_stmt *ymod;
|
||||
yang_stmt *ymod = NULL;
|
||||
yang_stmt *yrev;
|
||||
char *modname;
|
||||
char *subrevision;
|
||||
|
|
@ -1527,7 +1527,7 @@ yang_parse_recurse(clicon_handle h,
|
|||
if ((nr = yang_parse_find_match(h, yang_dir, module, fbuf)) < 0)
|
||||
goto done;
|
||||
if (nr == 0){
|
||||
clicon_err(OE_YANG, errno, "No matching %s yang files found", module);
|
||||
clicon_err(OE_YANG, errno, "No matching %s yang files found (expected modulenameor absolute filename)", module);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Clixon tests
|
||||
|
||||
This directory contains testing code for clixon and the example
|
||||
routing application:
|
||||
routing application. Assumes setup of http daemon as describe under apps/restonf
|
||||
- clixon A top-level script clones clixon in /tmp and starts all.sh. You can copy this file (review it first) and place as cron script
|
||||
- all.sh Run through all tests named 'test*.sh' in this directory. Therefore, if you place a test in this directory matching 'test*.sh' it will be run automatically.
|
||||
- test_cli.sh CLI tests
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
testnr=0
|
||||
testnname=
|
||||
clixon_cf=/usr/local/etc/routing.conf
|
||||
clixon_cf=/usr/local/etc/routing.xml
|
||||
# error and exit, arg is optional extra errmsg
|
||||
err(){
|
||||
echo "Error in Test$testnr [$testname]:"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Test3: backend and restconf basic functionality
|
||||
# Restconf basic functionality
|
||||
# Assume http server setup, such as nginx described in apps/restconf/README.md
|
||||
|
||||
# include err() and new() functions
|
||||
. ./lib.sh
|
||||
|
|
@ -20,7 +21,7 @@ new "kill old restconf daemon"
|
|||
sudo pkill -u www-data clixon_restconf
|
||||
|
||||
new "start restconf daemon"
|
||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -Df /usr/local/etc/routing.conf # -D
|
||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -Df /usr/local/etc/routing.xml # -D
|
||||
|
||||
sleep 1
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@
|
|||
}
|
||||
leaf CLICON_CLI_GENMODEL_COMPLETION {
|
||||
type int32;
|
||||
default 0;
|
||||
default 1;
|
||||
description "Generate code for CLI completion of existing db symbols";
|
||||
}
|
||||
leaf CLICON_CLI_GENMODEL_TYPE {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue