Feature: [Add support for -V option to give version](https://github.com/clicon/clixon/issues/472)
This commit is contained in:
parent
2f81a086c8
commit
261469be16
11 changed files with 209 additions and 42 deletions
|
|
@ -13,6 +13,9 @@ Expected: February 2024
|
||||||
|
|
||||||
### Minor features
|
### Minor features
|
||||||
|
|
||||||
|
* Feature: [Add support for -V option to give version](https://github.com/clicon/clixon/issues/472)
|
||||||
|
* All clixon applications added command-line option `-V` for printing version
|
||||||
|
* New ca_version callback for customized version output
|
||||||
* Optimization:
|
* Optimization:
|
||||||
* Added mountpoint cache as yang flag `YANG_FLAG_MTPOINT_POTENTIAL`
|
* Added mountpoint cache as yang flag `YANG_FLAG_MTPOINT_POTENTIAL`
|
||||||
* Optimized `yang_find`, especially namespace lookup
|
* Optimized `yang_find`, especially namespace lookup
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
#include "backend_plugin_restconf.h"
|
#include "backend_plugin_restconf.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define BACKEND_OPTS "hD:f:E:l:C:d:p:b:Fza:u:P:1qs:c:U:g:y:o:"
|
#define BACKEND_OPTS "hVD:f:E:l:C:d:p:b:Fza:u:P:1qs:c:U:g:y:o:"
|
||||||
|
|
||||||
#define BACKEND_LOGFILE "/usr/local/var/clixon_backend.log"
|
#define BACKEND_LOGFILE "/usr/local/var/clixon_backend.log"
|
||||||
|
|
||||||
|
|
@ -462,6 +462,7 @@ usage(clicon_handle h,
|
||||||
fprintf(stderr, "usage:%s <options>*\n"
|
fprintf(stderr, "usage:%s <options>*\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h\t\tHelp\n"
|
"\t-h\t\tHelp\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level>\tDebug level\n"
|
"\t-D <level>\tDebug level\n"
|
||||||
"\t-f <file>\tClixon config file\n"
|
"\t-f <file>\tClixon config file\n"
|
||||||
"\t-E <dir> \tExtra configuration file directory\n"
|
"\t-E <dir> \tExtra configuration file directory\n"
|
||||||
|
|
@ -532,6 +533,7 @@ main(int argc,
|
||||||
size_t sz;
|
size_t sz;
|
||||||
int config_dump;
|
int config_dump;
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
|
int print_version = 0;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
@ -560,6 +562,10 @@ main(int argc,
|
||||||
*/
|
*/
|
||||||
help = 1;
|
help = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
print_version++; /* plugins may also print versions w ca-version callback */
|
||||||
|
break;
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -611,12 +617,13 @@ main(int argc,
|
||||||
while ((c = getopt(argc, argv, BACKEND_OPTS)) != -1)
|
while ((c = getopt(argc, argv, BACKEND_OPTS)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
|
case 'V' : /* version */
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
case 'f': /* config file */
|
case 'f' : /* config file */
|
||||||
case 'E': /* extra config dir */
|
case 'E' : /* extra config dir */
|
||||||
case 'l' :
|
case 'l' :
|
||||||
break; /* see above */
|
break; /* see above */
|
||||||
case 'C': /* Explicitly dump configuration */
|
case 'C' : /* Explicitly dump configuration */
|
||||||
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
||||||
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -823,7 +830,12 @@ main(int argc,
|
||||||
clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir,
|
clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir,
|
||||||
clicon_option_str(h, "CLICON_BACKEND_REGEXP")) < 0)
|
clicon_option_str(h, "CLICON_BACKEND_REGEXP")) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* Print version, customized variant must wait for plugins to load */
|
||||||
|
if (print_version){
|
||||||
|
if (clixon_plugin_version_all(h, stdout) < 0)
|
||||||
|
goto done;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
/* Load Yang modules
|
/* Load Yang modules
|
||||||
* 1. Load a yang module as a specific absolute filename */
|
* 1. Load a yang module as a specific absolute filename */
|
||||||
if ((str = clicon_yang_main_file(h)) != NULL)
|
if ((str = clicon_yang_main_file(h)) != NULL)
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,7 @@
|
||||||
#include "cli_handle.h"
|
#include "cli_handle.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define CLI_OPTS "+hD:f:E:l:C:F:1a:u:d:m:qp:GLy:c:U:o:"
|
#define CLI_OPTS "+hVD:f:E:l:C:F:1a:u:d:m:qp:GLy:c:U:o:"
|
||||||
|
|
||||||
/*! Check if there is a CLI history file and if so dump the CLI histiry to it
|
/*! Check if there is a CLI history file and if so dump the CLI histiry to it
|
||||||
*
|
*
|
||||||
* Just log if file does not exist or is not readable
|
* Just log if file does not exist or is not readable
|
||||||
|
|
@ -481,6 +480,7 @@ usage(clicon_handle h,
|
||||||
"and extra-options are app-dependent and passed to the plugin init function\n"
|
"and extra-options are app-dependent and passed to the plugin init function\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h \t\tHelp\n"
|
"\t-h \t\tHelp\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level> \tDebug level\n"
|
"\t-D <level> \tDebug level\n"
|
||||||
"\t-f <file> \tConfig-file (mandatory)\n"
|
"\t-f <file> \tConfig-file (mandatory)\n"
|
||||||
"\t-E <dir> \tExtra configuration file directory\n"
|
"\t-E <dir> \tExtra configuration file directory\n"
|
||||||
|
|
@ -532,8 +532,9 @@ main(int argc,
|
||||||
size_t cligen_bufthreshold;
|
size_t cligen_bufthreshold;
|
||||||
int dbg=0;
|
int dbg=0;
|
||||||
int nr;
|
int nr;
|
||||||
int config_dump;
|
int config_dump;
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
|
int print_version = 0;
|
||||||
|
|
||||||
/* Defaults */
|
/* Defaults */
|
||||||
once = 0;
|
once = 0;
|
||||||
|
|
@ -574,6 +575,10 @@ main(int argc,
|
||||||
*/
|
*/
|
||||||
help = 1;
|
help = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'V': /* version */
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
print_version++; /* plugins may also print versions w ca-version callback */
|
||||||
|
break;
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -616,11 +621,12 @@ main(int argc,
|
||||||
while ((c = getopt(argc, argv, CLI_OPTS)) != -1){
|
while ((c = getopt(argc, argv, CLI_OPTS)) != -1){
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
case 'f': /* config file */
|
case 'V' : /* version */
|
||||||
case 'E': /* extra config dir */
|
case 'f' : /* config file */
|
||||||
case 'l': /* Log destination */
|
case 'E' : /* extra config dir */
|
||||||
|
case 'l' : /* Log destination */
|
||||||
break; /* see above */
|
break; /* see above */
|
||||||
case 'C': /* Explicitly dump configuration */
|
case 'C' : /* Explicitly dump configuration */
|
||||||
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
||||||
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -766,7 +772,12 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Print version, customized variant must wait for plugins to load */
|
||||||
|
if (print_version){
|
||||||
|
if (clixon_plugin_version_all(h, stdout) < 0)
|
||||||
|
goto done;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
/* Add (hardcoded) netconf features in case ietf-netconf loaded here
|
/* Add (hardcoded) netconf features in case ietf-netconf loaded here
|
||||||
* Otherwise it is loaded in netconf_module_load below
|
* Otherwise it is loaded in netconf_module_load below
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
#include "netconf_rpc.h"
|
#include "netconf_rpc.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define NETCONF_OPTS "hD:f:E:l:C:q01ca:u:d:p:y:U:t:eo:"
|
#define NETCONF_OPTS "hVD:f:E:l:C:q01ca:u:d:p:y:U:t:eo:"
|
||||||
|
|
||||||
#define NETCONF_LOGFILE "/tmp/clixon_netconf.log"
|
#define NETCONF_LOGFILE "/tmp/clixon_netconf.log"
|
||||||
|
|
||||||
|
|
@ -637,6 +637,7 @@ usage(clicon_handle h,
|
||||||
fprintf(stderr, "usage:%s\n"
|
fprintf(stderr, "usage:%s\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h\t\tHelp\n"
|
"\t-h\t\tHelp\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level>\tDebug level\n"
|
"\t-D <level>\tDebug level\n"
|
||||||
"\t-f <file>\tConfiguration file (mandatory)\n"
|
"\t-f <file>\tConfiguration file (mandatory)\n"
|
||||||
"\t-E <dir> \tExtra configuration file directory\n"
|
"\t-E <dir> \tExtra configuration file directory\n"
|
||||||
|
|
@ -683,6 +684,7 @@ main(int argc,
|
||||||
size_t sz;
|
size_t sz;
|
||||||
int config_dump = 0;
|
int config_dump = 0;
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
|
int print_version = 0;
|
||||||
|
|
||||||
/* Create handle */
|
/* Create handle */
|
||||||
if ((h = clicon_handle_init()) == NULL)
|
if ((h = clicon_handle_init()) == NULL)
|
||||||
|
|
@ -702,6 +704,10 @@ main(int argc,
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
break;
|
break;
|
||||||
|
case 'V': /* version */
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
print_version++; /* plugins may also print versions w ca-version callback */
|
||||||
|
break;
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -743,12 +749,13 @@ main(int argc,
|
||||||
while ((c = getopt(argc, argv, NETCONF_OPTS)) != -1)
|
while ((c = getopt(argc, argv, NETCONF_OPTS)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
|
case 'V' : /* version */
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
case 'f': /* config file */
|
case 'f' : /* config file */
|
||||||
case 'E': /* extra config dir */
|
case 'E' : /* extra config dir */
|
||||||
case 'l': /* log */
|
case 'l' : /* log */
|
||||||
break; /* see above */
|
break; /* see above */
|
||||||
case 'C': /* Explicitly dump configuration */
|
case 'C' : /* Explicitly dump configuration */
|
||||||
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
if ((config_dump_format = format_str2int(optarg)) == (enum format_enum)-1){
|
||||||
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
fprintf(stderr, "Unrecognized dump format: %s(expected: xml|json|text)\n", argv[0]);
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -855,7 +862,12 @@ main(int argc,
|
||||||
if ((dir = clicon_netconf_dir(h)) != NULL &&
|
if ((dir = clicon_netconf_dir(h)) != NULL &&
|
||||||
clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* Print version, customized variant must wait for plugins to load */
|
||||||
|
if (print_version){
|
||||||
|
if (clixon_plugin_version_all(h, stdout) < 0)
|
||||||
|
goto done;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
/* Load Yang modules
|
/* Load Yang modules
|
||||||
* 1. Load a yang module as a specific absolute filename */
|
* 1. Load a yang module as a specific absolute filename */
|
||||||
if ((str = clicon_yang_main_file(h)) != NULL){
|
if ((str = clicon_yang_main_file(h)) != NULL){
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
#include "restconf_stream.h"
|
#include "restconf_stream.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define RESTCONF_OPTS "hD:f:E:l:C:p:d:y:a:u:rW:R:o:"
|
#define RESTCONF_OPTS "hVD:f:E:l:C:p:d:y:a:u:rW:R:o:"
|
||||||
|
|
||||||
/*! Convert FCGI parameters to clixon runtime data
|
/*! Convert FCGI parameters to clixon runtime data
|
||||||
*
|
*
|
||||||
|
|
@ -270,6 +270,7 @@ usage(clicon_handle h,
|
||||||
fprintf(stderr, "usage:%s [options]\n"
|
fprintf(stderr, "usage:%s [options]\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h \t\t Help\n"
|
"\t-h \t\t Help\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level>\t Debug level\n"
|
"\t-D <level>\t Debug level\n"
|
||||||
"\t-f <file>\t Configuration file (mandatory)\n"
|
"\t-f <file>\t Configuration file (mandatory)\n"
|
||||||
"\t-E <dir> \t Extra configuration file directory\n"
|
"\t-E <dir> \t Extra configuration file directory\n"
|
||||||
|
|
@ -321,6 +322,7 @@ main(int argc,
|
||||||
size_t sz;
|
size_t sz;
|
||||||
int config_dump = 0;
|
int config_dump = 0;
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
|
int print_version = 0;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & debug flag set later */
|
/* In the startup, logs to stderr & debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
@ -336,6 +338,10 @@ main(int argc,
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
print_version++; /* plugins may also print versions w ca-version callback */
|
||||||
|
break;
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
|
|
@ -391,6 +397,7 @@ main(int argc,
|
||||||
while ((c = getopt(argc, argv, RESTCONF_OPTS)) != -1)
|
while ((c = getopt(argc, argv, RESTCONF_OPTS)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
|
case 'V' : /* version */
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
case 'f': /* config file */
|
case 'f': /* config file */
|
||||||
case 'E': /* extra config dir */
|
case 'E': /* extra config dir */
|
||||||
|
|
@ -480,6 +487,12 @@ main(int argc,
|
||||||
if ((dir = clicon_restconf_dir(h)) != NULL)
|
if ((dir = clicon_restconf_dir(h)) != NULL)
|
||||||
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
/* Print version, customized variant must wait for plugins to load */
|
||||||
|
if (print_version){
|
||||||
|
if (clixon_plugin_version_all(h, stdout) < 0)
|
||||||
|
goto done;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
/* Create a pseudo-plugin to create extension callback to set the ietf-routing
|
/* Create a pseudo-plugin to create extension callback to set the ietf-routing
|
||||||
* yang-data extension for api-root top-level restconf function.
|
* yang-data extension for api-root top-level restconf function.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define RESTCONF_OPTS "hD:f:E:l:C:p:y:a:u:rW:R:o:"
|
#define RESTCONF_OPTS "hVD:f:E:l:C:p:y:a:u:rW:R:o:"
|
||||||
|
|
||||||
/* If set, open outwards socket non-blocking, as opposed to blocking
|
/* If set, open outwards socket non-blocking, as opposed to blocking
|
||||||
* Should work both ways, but in the ninblocking case,
|
* Should work both ways, but in the ninblocking case,
|
||||||
|
|
@ -903,6 +903,7 @@ restconf_openssl_init(clicon_handle h,
|
||||||
* That is, EITHER local config OR read config from backend once
|
* That is, EITHER local config OR read config from backend once
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] inline_config If set, restconf conf is given by -R command-line
|
* @param[in] inline_config If set, restconf conf is given by -R command-line
|
||||||
|
* @param[in] print_version If set, print version and exit
|
||||||
* @param[out] xrestconf XML restconf config, malloced (if retval = 1)
|
* @param[out] xrestconf XML restconf config, malloced (if retval = 1)
|
||||||
* @retval 1 OK (and xrestconf set)
|
* @retval 1 OK (and xrestconf set)
|
||||||
* @retval 0 Fail - no config
|
* @retval 0 Fail - no config
|
||||||
|
|
@ -911,6 +912,7 @@ restconf_openssl_init(clicon_handle h,
|
||||||
int
|
int
|
||||||
restconf_clixon_init(clicon_handle h,
|
restconf_clixon_init(clicon_handle h,
|
||||||
char *inline_config,
|
char *inline_config,
|
||||||
|
int print_version,
|
||||||
cxobj **xrestconfp)
|
cxobj **xrestconfp)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -954,6 +956,12 @@ restconf_clixon_init(clicon_handle h,
|
||||||
if ((dir = clicon_restconf_dir(h)) != NULL)
|
if ((dir = clicon_restconf_dir(h)) != NULL)
|
||||||
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
/* Print version, customized variant must wait for plugins to load */
|
||||||
|
if (print_version){
|
||||||
|
if (clixon_plugin_version_all(h, stdout) < 0)
|
||||||
|
goto done;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
/* Create a pseudo-plugin to create extension callback to set the ietf-routing
|
/* Create a pseudo-plugin to create extension callback to set the ietf-routing
|
||||||
* yang-data extension for api-root top-level restconf function.
|
* yang-data extension for api-root top-level restconf function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1101,6 +1109,7 @@ usage(clicon_handle h,
|
||||||
fprintf(stderr, "usage:%s [options]\n"
|
fprintf(stderr, "usage:%s [options]\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h \t\t Help\n"
|
"\t-h \t\t Help\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level>\t Debug level, overrides any config debug setting\n"
|
"\t-D <level>\t Debug level, overrides any config debug setting\n"
|
||||||
"\t-f <file>\t Configuration file (mandatory)\n"
|
"\t-f <file>\t Configuration file (mandatory)\n"
|
||||||
"\t-E <dir> \t Extra configuration file directory\n"
|
"\t-E <dir> \t Extra configuration file directory\n"
|
||||||
|
|
@ -1136,8 +1145,9 @@ main(int argc,
|
||||||
int ret;
|
int ret;
|
||||||
cxobj *xrestconf = NULL;
|
cxobj *xrestconf = NULL;
|
||||||
char *inline_config = NULL;
|
char *inline_config = NULL;
|
||||||
int config_dump = 0;
|
int config_dump = 0;
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
|
int print_version = 0;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & debug flag set later */
|
/* In the startup, logs to stderr & debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
@ -1151,6 +1161,10 @@ main(int argc,
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(h, argv0);
|
usage(h, argv0);
|
||||||
break;
|
break;
|
||||||
|
case 'V': /* version */
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
print_version++; /* plugins may also print versions w ca-version callback */
|
||||||
|
break;
|
||||||
case 'D' : /* debug. Note this overrides any setting in the config */
|
case 'D' : /* debug. Note this overrides any setting in the config */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv0);
|
usage(h, argv0);
|
||||||
|
|
@ -1300,7 +1314,7 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Clixon inits / configs */
|
/* Clixon inits / configs */
|
||||||
if ((ret = restconf_clixon_init(h, inline_config, &xrestconf)) < 0)
|
if ((ret = restconf_clixon_init(h, inline_config, print_version, &xrestconf)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* restconf disabled */
|
if (ret == 0){ /* restconf disabled */
|
||||||
clicon_log(LOG_INFO, "restconf configuration not found or disabled");
|
clicon_log(LOG_INFO, "restconf configuration not found or disabled");
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
#include "snmp_register.h"
|
#include "snmp_register.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define SNMP_OPTS "hD:f:l:C:o:z"
|
#define SNMP_OPTS "hVD:f:l:C:o:z"
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static int clixon_snmp_input_cb(int s, void *arg);
|
static int clixon_snmp_input_cb(int s, void *arg);
|
||||||
|
|
@ -319,6 +319,7 @@ usage(clicon_handle h,
|
||||||
fprintf(stderr, "usage:%s\n"
|
fprintf(stderr, "usage:%s\n"
|
||||||
"where options are\n"
|
"where options are\n"
|
||||||
"\t-h\t\tHelp\n"
|
"\t-h\t\tHelp\n"
|
||||||
|
"\t-V \t\tPrint version and exit\n"
|
||||||
"\t-D <level>\tDebug level (>1 for extensive libnetsnmp debug)\n"
|
"\t-D <level>\tDebug level (>1 for extensive libnetsnmp debug)\n"
|
||||||
"\t-f <file>\tConfiguration file (mandatory)\n"
|
"\t-f <file>\tConfiguration file (mandatory)\n"
|
||||||
"\t-l (e|o|s|f<file>) Log on std(e)rr, std(o)ut, (s)yslog(default), (f)ile\n"
|
"\t-l (e|o|s|f<file>) Log on std(e)rr, std(o)ut, (s)yslog(default), (f)ile\n"
|
||||||
|
|
@ -373,23 +374,27 @@ main(int argc,
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
break;
|
break;
|
||||||
|
case 'V': /* version */
|
||||||
|
cligen_output(stdout, "Clixon version %s\n", CLIXON_VERSION_STRING);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
case 'D' : /* debug */
|
case 'D' : /* debug */
|
||||||
if (sscanf(optarg, "%d", &dbg) != 1)
|
if (sscanf(optarg, "%d", &dbg) != 1)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
break;
|
break;
|
||||||
case 'f': /* override config file */
|
case 'f': /* override config file */
|
||||||
if (!strlen(optarg))
|
if (!strlen(optarg))
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg);
|
clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg);
|
||||||
break;
|
break;
|
||||||
case 'l': /* Log destination: s|e|o */
|
case 'l': /* Log destination: s|e|o */
|
||||||
if ((logdst = clicon_log_opt(optarg[0])) < 0)
|
if ((logdst = clicon_log_opt(optarg[0])) < 0)
|
||||||
usage(h, argv[0]);
|
usage(h, argv[0]);
|
||||||
if (logdst == CLICON_LOG_FILE &&
|
if (logdst == CLICON_LOG_FILE &&
|
||||||
strlen(optarg)>1 &&
|
strlen(optarg)>1 &&
|
||||||
clicon_log_file(optarg+1) < 0)
|
clicon_log_file(optarg+1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -269,14 +269,34 @@ example_cli_errmsg(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Callback for printing version output and exit
|
||||||
|
*
|
||||||
|
* A plugin can customize a version (or banner) output on stdout.
|
||||||
|
* Several version strings can be printed if there are multiple callbacks.
|
||||||
|
* If not regstered plugins exist, clixon prints CLIXON_VERSION_STRING
|
||||||
|
* Typically invoked by command-line option -V
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] f Output file
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
example_version(clicon_handle h,
|
||||||
|
FILE *f)
|
||||||
|
{
|
||||||
|
cligen_output(f, "Clixon main example version 0\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CLIXON_STATIC_PLUGINS
|
#ifndef CLIXON_STATIC_PLUGINS
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
"example", /* name */
|
"example", /* name */
|
||||||
clixon_plugin_init, /* init */
|
clixon_plugin_init, /* init */
|
||||||
NULL, /* start */
|
NULL, /* start */
|
||||||
NULL, /* exit */
|
NULL, /* exit */
|
||||||
.ca_yang_mount=example_cli_yang_mount, /* RFC 8528 schema mount */
|
.ca_yang_mount= example_cli_yang_mount, /* RFC 8528 schema mount */
|
||||||
.ca_errmsg=example_cli_errmsg, /* customize errmsg */
|
.ca_errmsg = example_cli_errmsg, /* customize errmsg */
|
||||||
|
.ca_version = example_version /* Customized version string */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! CLI plugin initialization
|
/*! CLI plugin initialization
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,6 @@ typedef int (plgstart_t)(clicon_handle); /* Plugin start */
|
||||||
*/
|
*/
|
||||||
typedef int (plgdaemon_t)(clicon_handle); /* Plugin pre/post daemonized */
|
typedef int (plgdaemon_t)(clicon_handle); /* Plugin pre/post daemonized */
|
||||||
|
|
||||||
|
|
||||||
/* Called just before plugin unloaded.
|
/* Called just before plugin unloaded.
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
*/
|
*/
|
||||||
|
|
@ -325,6 +324,19 @@ typedef int (yang_patch_t)(clicon_handle h, yang_stmt *ymod);
|
||||||
*/
|
*/
|
||||||
typedef int (netconf_errmsg_t)(clicon_handle, cxobj *xerr, cbuf *cberr);
|
typedef int (netconf_errmsg_t)(clicon_handle, cxobj *xerr, cbuf *cberr);
|
||||||
|
|
||||||
|
/*! Callback for printing version output and exit
|
||||||
|
*
|
||||||
|
* A plugin can customize a version (or banner) output on stdout.
|
||||||
|
* Several version strings can be printed if there are multiple callbacks.
|
||||||
|
* If not regstered plugins exist, clixon prints CLIXON_VERSION_STRING
|
||||||
|
* Typically invoked by command-line option -V
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] f Output file
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
typedef int (plgversion_t)(clicon_handle, FILE*);
|
||||||
|
|
||||||
/*! Startup status for use in startup-callback
|
/*! Startup status for use in startup-callback
|
||||||
*
|
*
|
||||||
* Note that for STARTUP_ERR and STARTUP_INVALID, running runs in failsafe mode
|
* Note that for STARTUP_ERR and STARTUP_INVALID, running runs in failsafe mode
|
||||||
|
|
@ -343,18 +355,19 @@ enum startup_status{
|
||||||
* Note: Implicit init function
|
* Note: Implicit init function
|
||||||
*/
|
*/
|
||||||
struct clixon_plugin_api;
|
struct clixon_plugin_api;
|
||||||
typedef struct clixon_plugin_api* (plginit2_t)(clicon_handle); /* Clixon plugin Init */
|
typedef struct clixon_plugin_api* (plginit_t)(clicon_handle); /* Clixon plugin Init */
|
||||||
|
|
||||||
struct clixon_plugin_api{
|
struct clixon_plugin_api{
|
||||||
/*--- Common fields. ---*/
|
/*--- Common fields. ---*/
|
||||||
char ca_name[MAXPATHLEN]; /* Name of plugin (given by plugin) */
|
char ca_name[MAXPATHLEN]; /* Name of plugin (given by plugin) */
|
||||||
plginit2_t *ca_init; /* Clixon plugin Init (implicit) */
|
plginit_t *ca_init; /* Clixon plugin Init (implicit) */
|
||||||
plgstart_t *ca_start; /* Plugin start */
|
plgstart_t *ca_start; /* Plugin start */
|
||||||
plgexit_t *ca_exit; /* Plugin exit */
|
plgexit_t *ca_exit; /* Plugin exit */
|
||||||
plgextension_t *ca_extension; /* Yang extension/unknown handler */
|
plgextension_t *ca_extension; /* Yang extension/unknown handler */
|
||||||
yang_mount_t *ca_yang_mount; /* RFC 8528 schema mount */
|
yang_mount_t *ca_yang_mount; /* RFC 8528 schema mount */
|
||||||
yang_patch_t *ca_yang_patch; /* Patch yang after parse */
|
yang_patch_t *ca_yang_patch; /* Patch yang after parse */
|
||||||
netconf_errmsg_t *ca_errmsg; /* Customize error message callback */
|
netconf_errmsg_t *ca_errmsg; /* Customize error message callback */
|
||||||
|
plgversion_t *ca_version; /* Output a customized version message */
|
||||||
union {
|
union {
|
||||||
struct { /* cli-specific */
|
struct { /* cli-specific */
|
||||||
cli_prompthook_t *ci_prompt; /* Prompt hook */
|
cli_prompthook_t *ci_prompt; /* Prompt hook */
|
||||||
|
|
@ -370,7 +383,6 @@ struct clixon_plugin_api{
|
||||||
plgdaemon_t *cb_pre_daemon; /* Plugin just before daemonization (only daemon) */
|
plgdaemon_t *cb_pre_daemon; /* Plugin just before daemonization (only daemon) */
|
||||||
plgdaemon_t *cb_daemon; /* Plugin daemonized (always called) */
|
plgdaemon_t *cb_daemon; /* Plugin daemonized (always called) */
|
||||||
plgreset_t *cb_reset; /* Reset system status */
|
plgreset_t *cb_reset; /* Reset system status */
|
||||||
|
|
||||||
plgstatedata_t *cb_statedata; /* Provide state data XML from plugin */
|
plgstatedata_t *cb_statedata; /* Provide state data XML from plugin */
|
||||||
plglockdb_t *cb_lockdb; /* Database lock changed state */
|
plglockdb_t *cb_lockdb; /* Database lock changed state */
|
||||||
trans_cb_t *cb_trans_begin; /* Transaction start */
|
trans_cb_t *cb_trans_begin; /* Transaction start */
|
||||||
|
|
@ -490,6 +502,9 @@ int clixon_plugin_yang_patch_all(clicon_handle h, yang_stmt *ymod);
|
||||||
int clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp, clicon_handle h, cxobj *xerr, cbuf *cberr);
|
int clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp, clicon_handle h, cxobj *xerr, cbuf *cberr);
|
||||||
int clixon_plugin_netconf_errmsg_all(clicon_handle h, cxobj *xerr, cbuf *cberr);
|
int clixon_plugin_netconf_errmsg_all(clicon_handle h, cxobj *xerr, cbuf *cberr);
|
||||||
|
|
||||||
|
int clixon_plugin_version_one(clixon_plugin_t *cp, clicon_handle h, FILE *f);
|
||||||
|
int clixon_plugin_version_all(clicon_handle h, FILE *f);
|
||||||
|
|
||||||
/* rpc callback API */
|
/* rpc callback API */
|
||||||
int rpc_callback_register(clicon_handle h, clicon_rpc_cb cb, void *arg, const char *ns, const char *name);
|
int rpc_callback_register(clicon_handle h, clicon_rpc_cb cb, void *arg, const char *ns, const char *name);
|
||||||
int rpc_callback_call(clicon_handle h, cxobj *xe, void *arg, int *nrp, cbuf *cbret);
|
int rpc_callback_call(clicon_handle h, cxobj *xe, void *arg, int *nrp, cbuf *cbret);
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ plugin_load_one(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *error;
|
char *error;
|
||||||
void *handle = NULL;
|
void *handle = NULL;
|
||||||
plginit2_t *initfn;
|
plginit_t *initfn;
|
||||||
clixon_plugin_api *api = NULL;
|
clixon_plugin_api *api = NULL;
|
||||||
clixon_plugin_t *cp = NULL;
|
clixon_plugin_t *cp = NULL;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
@ -690,7 +690,7 @@ plugin_context_check(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_plugin_start_one(clixon_plugin_t *cp,
|
clixon_plugin_start_one(clixon_plugin_t *cp,
|
||||||
clicon_handle h)
|
clicon_handle h)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
plgstart_t *fn; /* Plugin start */
|
plgstart_t *fn; /* Plugin start */
|
||||||
|
|
@ -747,7 +747,7 @@ clixon_plugin_start_all(clicon_handle h)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
clixon_plugin_exit_one(clixon_plugin_t *cp,
|
clixon_plugin_exit_one(clixon_plugin_t *cp,
|
||||||
clicon_handle h)
|
clicon_handle h)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *error;
|
char *error;
|
||||||
|
|
@ -804,6 +804,7 @@ clixon_plugin_exit_all(clicon_handle h)
|
||||||
|
|
||||||
/*! Run the restconf user-defined credentials callback
|
/*! Run the restconf user-defined credentials callback
|
||||||
*
|
*
|
||||||
|
* @param[in] cp Plugin handle
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Per-message request www handle to use with restconf_api.h
|
* @param[in] req Per-message request www handle to use with restconf_api.h
|
||||||
* @param[in] auth_type Authentication type: none, user-defined, or client-cert
|
* @param[in] auth_type Authentication type: none, user-defined, or client-cert
|
||||||
|
|
@ -973,7 +974,7 @@ clixon_plugin_extension_all(clicon_handle h,
|
||||||
* Upgrade datastore on load before or as an alternative to module-specific upgrading mechanism
|
* Upgrade datastore on load before or as an alternative to module-specific upgrading mechanism
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp,
|
clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp,
|
||||||
clicon_handle h,
|
clicon_handle h,
|
||||||
const char *db,
|
const char *db,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
|
|
@ -1188,7 +1189,7 @@ clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp,
|
||||||
goto done;
|
goto done;
|
||||||
if (fn(h, xerr, cberr) < 0) {
|
if (fn(h, xerr, cberr) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Yang patch callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Netconf err callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1225,6 +1226,64 @@ clixon_plugin_netconf_errmsg_all(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Call one plugin to get version output
|
||||||
|
*
|
||||||
|
* @param[in] cp Plugin handle
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] f Output file
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_version_one(clixon_plugin_t *cp,
|
||||||
|
clicon_handle h,
|
||||||
|
FILE *f)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
plgversion_t *fn;
|
||||||
|
void *wh = NULL;
|
||||||
|
|
||||||
|
if ((fn = cp->cp_api.ca_version) != NULL){
|
||||||
|
wh = NULL;
|
||||||
|
if (plugin_context_check(h, &wh, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
|
if (fn(h, f) < 0) {
|
||||||
|
if (clicon_errno < 0)
|
||||||
|
clicon_log(LOG_WARNING, "%s: Internal error: version callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
|
__FUNCTION__, cp->cp_name);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (plugin_context_check(h, &wh, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Call all plugins to get version output
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] f Output file
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_version_all(clicon_handle h,
|
||||||
|
FILE *f)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
clixon_plugin_t *cp = NULL;
|
||||||
|
cp = NULL;
|
||||||
|
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||||
|
if (clixon_plugin_version_one(cp, h, f) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
* RPC callbacks for both client/frontend and backend plugins.
|
* RPC callbacks for both client/frontend and backend plugins.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,9 @@ fi
|
||||||
new "wait backend"
|
new "wait backend"
|
||||||
wait_backend
|
wait_backend
|
||||||
|
|
||||||
|
new "cli version"
|
||||||
|
expectpart "$($clixon_cli -1 -f $cfg -V)" 0 "Clixon version $CLIXON_VERSION" "Clixon main example version"
|
||||||
|
|
||||||
new "cli configure top"
|
new "cli configure top"
|
||||||
expectpart "$($clixon_cli -1 -f $cfg set interfaces)" 0 "^$"
|
expectpart "$($clixon_cli -1 -f $cfg set interfaces)" 0 "^$"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue