* Made backend transaction and commit/validate API available to plugin code.

* This enables that RPOC handles can call commit and validate via lib
  * The commit/validate API is now: `candidate_validate()` and `candidate_commit()`
This commit is contained in:
Olof hagsand 2021-06-17 19:20:27 +02:00
parent 1f7fc3afcb
commit dd8883420c
14 changed files with 110 additions and 110 deletions

View file

@ -81,6 +81,9 @@ Users may have to change how they access the system
Developers may need to change their code
* Made backend transaction and commit/validate API available to plugin code.
* This enables that RPOC handles can call commit and validate via lib
* The commit/validate API is now: `candidate_validate()` and `candidate_commit()`
* Event exit API changed to a single decrementing counter where 1 means exit.
* Removed: `clicon_exit_reset()`
* Changed: `clicon_exit_set()` --> `clixon_exit_set(int nr)`

View file

@ -85,14 +85,15 @@ APPL = clixon_backend
APPSRC = backend_main.c
APPSRC += backend_socket.c
APPSRC += backend_client.c
APPSRC += backend_commit.c
APPSRC += backend_plugin.c
APPSRC += backend_plugin_restconf.c # Pseudo plugin for restconf daemon
APPSRC += backend_startup.c
APPOBJ = $(APPSRC:.c=.o)
# Accessible from plugin
LIBSRC = clixon_backend_transaction.c clixon_backend_handle.c
LIBSRC = clixon_backend_transaction.c
LIBSRC += clixon_backend_handle.c
LIBSRC += backend_commit.c
LIBSRC += backend_plugin.c
LIBOBJ = $(LIBSRC:.c=.o)
# Name of lib
@ -143,7 +144,7 @@ uninstall:
rm -f $(DESTDIR)$(libdir)/$(MYLIBLINK)*
rm -f $(DESTDIR)$(includedir)/clixon/*
install-include: clixon_backend.h clixon_backend_handle.h clixon_backend_transaction.h
install-include: clixon_backend.h clixon_backend_handle.h clixon_backend_transaction.h clixon_backend_plugin.h clixon_backend_commit.h
install -d -m 0755 $(DESTDIR)$(includedir)/clixon
install -m 0644 $^ $(DESTDIR)$(includedir)/clixon

View file

@ -67,8 +67,8 @@
#include <clixon/clixon.h>
#include "clixon_backend_handle.h"
#include "backend_plugin.h"
#include "backend_commit.h"
#include "clixon_backend_plugin.h"
#include "clixon_backend_commit.h"
#include "backend_client.h"
#include "backend_handle.h"

View file

@ -66,9 +66,9 @@
#include <clixon/clixon.h>
#include "clixon_backend_transaction.h"
#include "backend_plugin.h"
#include "clixon_backend_plugin.h"
#include "backend_handle.h"
#include "backend_commit.h"
#include "clixon_backend_commit.h"
#include "backend_client.h"
/*! Key values are checked for validity independent of user-defined callbacks
@ -177,7 +177,7 @@ generic_validate(clicon_handle h,
* 4. Validate startup db. (valid)
* 5. If valid fails, call startup-cb(Invalid, msdiff), keep startup in candidate and commit failsafe db. Done.
* 6. Call startup-cb(OK, msdiff) and commit.
* @see from_validate_common for incoming validate/commit
* @see validate_common for incoming validate/commit
*/
static int
startup_common(clicon_handle h,
@ -478,21 +478,21 @@ startup_commit(clicon_handle h,
/*! Validate a candidate db and comnpare to running
* Get both source and dest datastore, validate target, compute diffs
* and call application callback validations.
* @param[in] h Clicon handle
* @param[in] candidate The candidate database. The wanted backend state
* @param[out] xret Error XML tree. Free with xml_free after use
* @retval -1 Error - or validation failed (but cbret not set)
* @retval 0 Validation failed (with cbret set)
* @retval 1 Validation OK
* @param[in] h Clicon handle
* @param[in] candidate The candidate database. The wanted backend state
* @param[out] xret Error XML tree. Free with xml_free after use
* @retval -1 Error - or validation failed (but cbret not set)
* @retval 0 Validation failed (with cbret set)
* @retval 1 Validation OK
* @note Need to differentiate between error and validation fail
* (only done for generic_validate)
* @see startup_common for startup scenario
*/
static int
from_validate_common(clicon_handle h,
char *candidate,
transaction_data_t *td,
cxobj **xret)
validate_common(clicon_handle h,
char *db,
transaction_data_t *td,
cxobj **xret)
{
int retval = -1;
yang_stmt *yspec;
@ -505,7 +505,7 @@ from_validate_common(clicon_handle h,
goto done;
}
/* This is the state we are going to */
if (xmldb_get0(h, candidate, YB_MODULE, NULL, "/", 0, &td->td_target, NULL, NULL) < 0)
if (xmldb_get0(h, db, YB_MODULE, NULL, "/", 0, &td->td_target, NULL, NULL) < 0)
goto done;
/* Clear flags xpath for get */
@ -579,20 +579,73 @@ from_validate_common(clicon_handle h,
goto done;
}
/*! Start a validate transaction
*
* @param[in] h Clicon handle
* @param[in] db A candidate database, typically "candidate" but not necessarily so
* @retval -1 Error - or validation failed
* @retval 0 Validation failed (with cbret set)
* @retval 1 Validation OK
*/
int
candidate_validate(clicon_handle h,
char *db,
cbuf *cbret)
{
int retval = -1;
transaction_data_t *td = NULL;
cxobj *xret = NULL;
int ret;
clicon_debug(1, "%s", __FUNCTION__);
if (db == NULL || cbret == NULL){
clicon_err(OE_CFG, EINVAL, "db or cbret is NULL");
goto done;
}
/* 1. Start transaction */
if ((td = transaction_new()) == NULL)
goto done;
/* Common steps (with commit) */
if ((ret = validate_common(h, db, td, &xret)) < 1){
/* A little complex due to several sources of validation fails or errors.
* (1) xerr is set -> translate to cbret; (2) cbret set use that; otherwise
* use clicon_err. */
if (xret && clicon_xml2cbuf(cbret, xret, 0, 0, -1) < 0)
goto done;
plugin_transaction_abort_all(h, td);
if (!cbuf_len(cbret) &&
netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
goto fail;
}
if (xmldb_get0_clear(h, td->td_src) < 0 ||
xmldb_get0_clear(h, td->td_target) < 0){
plugin_transaction_abort_all(h, td);
goto done;
}
plugin_transaction_end_all(h, td);
retval = 1;
done:
return retval;
fail:
retval = 0;
goto done;
}
/*! Do a diff between candidate and running, then start a commit transaction
*
* The code reverts changes if the commit fails. But if the revert
* fails, we just ignore the errors and proceed. Maybe we should
* do something more drastic?
* @param[in] h Clicon handle
* @param[in] candidate A candidate database, not necessarily "candidate"
* @retval -1 Error - or validation failed
* @retval 0 Validation failed (with cbret set)
* @retval 1 Validation OK
* @param[in] h Clicon handle
* @param[in] db A candidate database, not necessarily "candidate"
* @retval -1 Error - or validation failed
* @retval 0 Validation failed (with cbret set)
* @retval 1 Validation OK
*/
int
candidate_commit(clicon_handle h,
char *candidate,
char *db,
cbuf *cbret)
{
int retval = -1;
@ -607,7 +660,7 @@ candidate_commit(clicon_handle h,
/* Common steps (with validate). Load candidate and running and compute diffs
* Note this is only call that uses 3-values
*/
if ((ret = from_validate_common(h, candidate, td, &xret)) < 0)
if ((ret = validate_common(h, db, td, &xret)) < 0)
goto done;
if (ret == 0){
if (clicon_xml2cbuf(cbret, xret, 0, 0, -1) < 0)
@ -630,9 +683,9 @@ candidate_commit(clicon_handle h,
/* 8. Success: Copy candidate to running
*/
if (xmldb_copy(h, candidate, "running") < 0)
if (xmldb_copy(h, db, "running") < 0)
goto done;
xmldb_modified_set(h, candidate, 0); /* reset dirty bit */
xmldb_modified_set(h, db, 0); /* reset dirty bit */
/* Here pointers to old (source) tree are obsolete */
if (td->td_dvec){
td->td_dlen = 0;
@ -664,7 +717,7 @@ candidate_commit(clicon_handle h,
retval = 0;
goto done;
}
/*! Commit the candidate configuration as the device's new current configuration
*
* @param[in] h Clicon handle
@ -818,57 +871,23 @@ from_client_validate(clicon_handle h,
void *arg,
void *regarg)
{
int retval = -1;
transaction_data_t *td = NULL;
int ret;
char *db;
cxobj *xret = NULL;
int retval = -1;
int ret;
char *db;
clicon_debug(1, "%s", __FUNCTION__);
if ((db = netconf_db_find(xe, "source")) == NULL){
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
goto done;
goto ok;
}
clicon_debug(1, "Validate %s", db);
/* 1. Start transaction */
if ((td = transaction_new()) == NULL)
if ((ret = candidate_validate(h, db, cbret)) < 0)
goto done;
/* Common steps (with commit) */
if ((ret = from_validate_common(h, db, td, &xret)) < 1){
/* A little complex due to several sources of validation fails or errors.
* (1) xerr is set -> translate to cbret; (2) cbret set use that; otherwise
* use clicon_err. */
if (xret && clicon_xml2cbuf(cbret, xret, 0, 0, -1) < 0)
goto done;
plugin_transaction_abort_all(h, td);
if (!cbuf_len(cbret) &&
netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
goto ok;
}
if (xmldb_get0_clear(h, td->td_src) < 0 ||
xmldb_get0_clear(h, td->td_target) < 0){
plugin_transaction_abort_all(h, td);
goto done;
}
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
/* Call plugin transaction end callbacks */
plugin_transaction_end_all(h, td);
if (ret == 1)
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
if (td){
if (retval < 0)
plugin_transaction_abort_all(h, td);
xmldb_get0_free(h, &td->td_target);
xmldb_get0_free(h, &td->td_src);
transaction_free(td);
}
if (xret)
xml_free(xret);
return retval;
} /* from_client_validate */

View file

@ -72,8 +72,8 @@
#include "clixon_backend_transaction.h"
#include "backend_socket.h"
#include "backend_client.h"
#include "backend_plugin.h"
#include "backend_commit.h"
#include "clixon_backend_plugin.h"
#include "clixon_backend_commit.h"
#include "backend_handle.h"
#include "backend_startup.h"
#include "backend_plugin_restconf.h"

View file

@ -62,8 +62,8 @@
#include <clixon/clixon.h>
#include "clixon_backend_transaction.h"
#include "backend_plugin.h"
#include "backend_commit.h"
#include "clixon_backend_plugin.h"
#include "clixon_backend_commit.h"
/*! Request plugins to reset system state
* The system 'state' should be the same as the contents of running_db

View file

@ -66,9 +66,9 @@
#include <clixon/clixon.h>
#include "clixon_backend_transaction.h"
#include "backend_plugin.h"
#include "clixon_backend_plugin.h"
#include "backend_handle.h"
#include "backend_commit.h"
#include "clixon_backend_commit.h"
#include "backend_startup.h"
/*! Merge db1 into db2 without commit

View file

@ -52,6 +52,8 @@ extern "C" {
/* Common code (API and Backend daemon) */
#include <clixon/clixon_backend_handle.h>
#include <clixon/clixon_backend_transaction.h>
#include <clixon/clixon_backend_commit.h>
#include <clixon/clixon_backend_plugin.h>
#endif /* _CLIXON_BACKEND_H_ */

View file

@ -36,14 +36,15 @@
*/
#ifndef _BACKEND_COMMIT_H_
#define _BACKEND_COMMIT_H_
#ifndef _CLIXON_BACKEND_COMMIT_H_
#define _CLIXON_BACKEND_COMMIT_H_
/*
* Prototypes
*/
int startup_validate(clicon_handle h, char *db, cxobj **xtr, cbuf *cbret);
int startup_commit(clicon_handle h, char *db, cbuf *cbret);
int candidate_validate(clicon_handle h, char *db, cbuf *cbret);
int candidate_commit(clicon_handle h, char *db, cbuf *cbret);
int from_client_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
@ -52,4 +53,4 @@ int from_client_cancel_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg
int from_client_validate(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
int from_client_restart_one(clicon_handle h, clixon_plugin_t *cp, cbuf *cbret);
#endif /* _BACKEND_COMMIT_H_ */
#endif /* _CLIXON_BACKEND_COMMIT_H_ */

View file

@ -35,8 +35,8 @@
*/
#ifndef _BACKEND_PLUGIN_H_
#define _BACKEND_PLUGIN_H_
#ifndef _CLIXON_BACKEND_PLUGIN_H_
#define _CLIXON_BACKEND_PLUGIN_H_
/*
* Types
@ -101,4 +101,4 @@ int plugin_transaction_end_all(clicon_handle h, transaction_data_t *td);
int plugin_transaction_abort_one(clixon_plugin_t *cp, clicon_handle h, transaction_data_t *td);
int plugin_transaction_abort_all(clicon_handle h, transaction_data_t *td);
#endif /* _BACKEND_PLUGIN_H_ */
#endif /* _CLIXON_BACKEND_PLUGIN_H_ */

View file

@ -61,7 +61,7 @@
#include <clixon/clixon.h>
#include "clixon_backend_transaction.h"
#include "backend_plugin.h"
#include "clixon_backend_plugin.h"
/* Access functions for transaction-data handle in callbacks
* Expressed in a transition from an current -> wanted state.

View file

@ -1,6 +0,0 @@
#!/bin/sh
# Travis pre-config script.
# Clone and install CLIgen (needed for clixon configure and make)
# Note travis builds and installs, then starts a clixon container where all tests are run from.
git clone https://github.com/clicon/cligen.git
(cd cligen && ./configure && make && sudo make install)

View file

@ -1,5 +0,0 @@
#!/usr/bin/env bash
# Travis pre-config script.
# build libevhtp
git clone https://github.com/clicon/libevhtp.git
(cd libevhtp/build && cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON .. && make && sudo make install)

View file

@ -1,15 +0,0 @@
#!/usr/bin/env bash
set -eux
./configure --with-restconf=fcgi
make
sudo make install
(cd example; make; sudo make install)
(cd util; make; sudo make install)
sudo ldconfig
ps aux|grep clixon
cd test;
./test_api_path.sh
ps aux|grep clixon
./test_augment.sh
ps aux|grep clixon
./all.sh