* New process-control RPC feature in clixon-lib.yang to manage processes

* This is an alternative to manage a clixon daemon via sudtemd, containerd or other
  * One important special case is starting the clixon-restconf daemon internally
  * This is how it works:
    * Register a process via `clixon_process_register(h, name, namespace, argv, argc)`
    * Use process-control RPC defined in clixon-lib.yang to start/stop/restart or query status on that process
  * Example code in the main example
This commit is contained in:
Olof hagsand 2020-12-15 14:43:01 +01:00
parent 8540820698
commit 22adc58187
19 changed files with 971 additions and 47 deletions

View file

@ -1560,7 +1560,49 @@ from_client_restart_plugin(clicon_handle h,
return retval;
}
/*!
/*! Control a specific process or daemon: start/stop, etc
* @param[in] h Clicon handle
* @param[in] xe Request: <rpc><xn></rpc>
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
* @param[in] arg client-entry
* @param[in] regarg User argument given at rpc_callback_register()
* @retval 0 OK
* @retval -1 Error
*/
static int
from_client_process_control(clicon_handle h,
cxobj *xe,
cbuf *cbret,
void *arg,
void *regarg)
{
int retval = -1;
cxobj *x;
char *name = NULL;
char *operation = NULL;
int status = 0;
clicon_debug(1, "%s", __FUNCTION__);
if ((x = xml_find_type(xe, NULL, "name", CX_ELMNT)) != NULL)
name = xml_body(x);
if ((x = xml_find_type(xe, NULL, "operation", CX_ELMNT)) != NULL)
operation = xml_body(x);
/* Make the actual process operation */
if (clixon_process_operation(h, name, operation, &status) < 0)
goto done;
if (strcmp(operation, "status") == 0)
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><status xmlns=\"%s\">%s</status></rpc-reply>",
NETCONF_BASE_NAMESPACE,
CLIXON_LIB_NS,
status?"true":"false");
else
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
retval = 0;
done:
return retval;
}
/*! Clixon hello to check liveness
* @retval 0 OK
* @retval -1 Error
*/
@ -1569,7 +1611,6 @@ from_client_hello(clicon_handle h,
cxobj *x,
struct client_entry *ce,
cbuf *cbret)
{
int retval = -1;
uint32_t id;
@ -1592,6 +1633,7 @@ from_client_hello(clicon_handle h,
return retval;
}
/*! An internal clicon message has arrived from a client. Receive and dispatch.
* @param[in] h Clicon handle
* @param[in] s Socket where message arrived. read from this.
@ -1922,6 +1964,9 @@ backend_rpc_init(clicon_handle h)
if (rpc_callback_register(h, from_client_restart_plugin, NULL,
CLIXON_LIB_NS, "restart-plugin") < 0)
goto done;
if (rpc_callback_register(h, from_client_process_control, NULL,
CLIXON_LIB_NS, "process-control") < 0)
goto done;
retval =0;
done:
return retval;

View file

@ -126,7 +126,10 @@ backend_terminate(clicon_handle h)
/* Delete all backend plugin RPC callbacks */
rpc_callback_delete_all(h);
/* Delete all backend plugin upgrade callbacks */
upgrade_callback_delete_all(h);
upgrade_callback_delete_all(h);
/* Delete all process-control entries */
clixon_process_delete_all(h);
xpath_optimize_exit();
if (pidfile)
@ -529,6 +532,10 @@ main(int argc,
usage(h, argv[0]);
goto done;
}
/* Add some specific options from autotools configure NOT config file */
clicon_option_str_set(h, "CLICON_WWWUSER", WWWUSER);
clicon_option_str_set(h, "CLICON_WWWDIR", WWWDIR);
/* External NACM file? */
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
if (nacm_mode && strcmp(nacm_mode, "external") == 0)

View file

@ -1196,7 +1196,6 @@ restconf_config(clicon_handle h,
xml_free(xconfig2);
if (nsc)
cvec_free(nsc);
clicon_debug(1, "restconf_main_evhtp done");
return retval;
}