diff --git a/CHANGELOG.md b/CHANGELOG.md index 0197235f..dd710a45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)` diff --git a/apps/backend/Makefile.in b/apps/backend/Makefile.in index bd8bc619..aecf95c7 100644 --- a/apps/backend/Makefile.in +++ b/apps/backend/Makefile.in @@ -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 diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index c4ffbe4a..6244d200 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -67,8 +67,8 @@ #include #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" diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 8d06de86..1bda0f73 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -66,9 +66,9 @@ #include #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, "", NETCONF_BASE_NAMESPACE); - /* Call plugin transaction end callbacks */ - plugin_transaction_end_all(h, td); + if (ret == 1) + cprintf(cbret, "", 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 */ diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index dda4b759..36494aff 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -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" diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index c4eecc9c..d045dd42 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -62,8 +62,8 @@ #include #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 diff --git a/apps/backend/backend_startup.c b/apps/backend/backend_startup.c index 9dd44436..f97b9b01 100644 --- a/apps/backend/backend_startup.c +++ b/apps/backend/backend_startup.c @@ -66,9 +66,9 @@ #include #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 diff --git a/apps/backend/clixon_backend.h b/apps/backend/clixon_backend.h index 533a3fe9..80c2c599 100644 --- a/apps/backend/clixon_backend.h +++ b/apps/backend/clixon_backend.h @@ -52,6 +52,8 @@ extern "C" { /* Common code (API and Backend daemon) */ #include #include +#include +#include #endif /* _CLIXON_BACKEND_H_ */ diff --git a/apps/backend/backend_commit.h b/apps/backend/clixon_backend_commit.h similarity index 92% rename from apps/backend/backend_commit.h rename to apps/backend/clixon_backend_commit.h index 0c98da80..ad387f78 100644 --- a/apps/backend/backend_commit.h +++ b/apps/backend/clixon_backend_commit.h @@ -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_ */ diff --git a/apps/backend/backend_plugin.h b/apps/backend/clixon_backend_plugin.h similarity index 97% rename from apps/backend/backend_plugin.h rename to apps/backend/clixon_backend_plugin.h index f5edb4f3..c661e151 100644 --- a/apps/backend/backend_plugin.h +++ b/apps/backend/clixon_backend_plugin.h @@ -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_ */ diff --git a/apps/backend/clixon_backend_transaction.c b/apps/backend/clixon_backend_transaction.c index 1e427f3e..ffc97d43 100644 --- a/apps/backend/clixon_backend_transaction.c +++ b/apps/backend/clixon_backend_transaction.c @@ -61,7 +61,7 @@ #include #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. diff --git a/test/travis/before_script.sh b/test/travis/before_script.sh deleted file mode 100755 index 84edd2c1..00000000 --- a/test/travis/before_script.sh +++ /dev/null @@ -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) diff --git a/test/travis/build_evhtp.sh b/test/travis/build_evhtp.sh deleted file mode 100755 index a5531d56..00000000 --- a/test/travis/build_evhtp.sh +++ /dev/null @@ -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) diff --git a/test/travis/script.sh b/test/travis/script.sh deleted file mode 100755 index 1b578981..00000000 --- a/test/travis/script.sh +++ /dev/null @@ -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