diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-04-11 11:47:27 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-04-11 11:47:27 +0200 |
commit | 52d837d3964307375018c728120ed649ef0fbb8c (patch) | |
tree | 89b09bb428b3f8b9375f60ce28d13ae6aaf6330c | |
parent | ca9807f73646f536ac58c002d963a8bb8d245f5d (diff) |
Add startup call in command line
The option -c (aka --call) allows to specify calls
to api/verb at startup. The calls are made sequentially.
Change-Id: I7f087dce71480fe288cca355c209a4c8ccf4f4b9
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-config.c | 9 | ||||
-rw-r--r-- | src/afb-config.h | 1 | ||||
-rw-r--r-- | src/main.c | 101 |
3 files changed, 110 insertions, 1 deletions
diff --git a/src/afb-config.c b/src/afb-config.c index 1b4a3693..0fcb1cb2 100644 --- a/src/afb-config.c +++ b/src/afb-config.c @@ -85,6 +85,7 @@ #define SET_NO_HTTPD 28 +#define ADD_CALL 'c' #define SET_TRACEDITF 'D' #define SET_EXEC 'e' #define DISPLAY_HELP 'h' @@ -97,7 +98,7 @@ #define SET_VERBOSE 'v' #define SET_WORK_DIR 'w' -#define SHORTOPTS "D:ehqrT:t:u:Vvw:" +#define SHORTOPTS "c:D:ehqrT:t:u:Vvw:" // Command line structure hold cli --command + help text typedef struct { @@ -151,6 +152,7 @@ static AFB_options cliOptions[] = { {SET_TRACEREQ, 1, "tracereq", "Log the requests: no, common, extra, all"}, {SET_TRACEDITF, 1, "traceditf", "Log the requests: no, common, extra, all"}, + {ADD_CALL, 1, "call", "call at start format of val: API/VERB:json-args"}, {SET_NO_HTTPD, 0, "no-httpd", "Forbids HTTP service"}, {SET_EXEC, 0, "exec", "Execute the remaining arguments"}, @@ -437,6 +439,10 @@ static void parse_arguments(int argc, char **argv, struct afb_config *config) list_add(&config->ldpaths, argvalstr(optc)); break; + case ADD_CALL: + list_add(&config->calls, argvalstr(optc)); + break; + case SET_SESSION_DIR: /* config->sessiondir = argvalstr(optc); */ WARNING("Obsolete otpion %s ignored", optname(optc)); @@ -620,6 +626,7 @@ void afb_config_dump(struct afb_config *config) L(ws_servers) L(so_bindings) L(ldpaths) + L(calls) V(exec) diff --git a/src/afb-config.h b/src/afb-config.h index 4c9f6241..a636a788 100644 --- a/src/afb-config.h +++ b/src/afb-config.h @@ -43,6 +43,7 @@ struct afb_config { struct afb_config_list *ws_servers; struct afb_config_list *so_bindings; struct afb_config_list *ldpaths; + struct afb_config_list *calls; char **exec; @@ -27,6 +27,8 @@ #include <sys/stat.h> #include <sys/wait.h> +#include <json-c/json.h> + #include <systemd/sd-event.h> #include <systemd/sd-daemon.h> @@ -41,6 +43,7 @@ #include "afb-hsrv.h" #include "afb-context.h" #include "afb-hreq.h" +#include "afb-xreq.h" #include "jobs.h" #include "afb-session.h" #include "verbose.h" @@ -431,6 +434,101 @@ static int execute_command() } /*--------------------------------------------------------- + | startup calls + +--------------------------------------------------------- */ + +struct startup_req +{ + struct afb_xreq xreq; + char *api; + char *verb; + struct afb_config_list *current; + struct afb_session *session; +}; + +static void startup_call_reply(void *closure, int iserror, struct json_object *obj) +{ + struct startup_req *sreq = closure; + + if (!iserror) + NOTICE("startup call %s returned %s", sreq->current->value, json_object_get_string(obj)); + else { + ERROR("startup call %s ERROR! %s", sreq->current->value, json_object_get_string(obj)); + exit(1); + } +} + +static void startup_call_current(struct startup_req *sreq); + +static void startup_call_unref(void *closure) +{ + struct startup_req *sreq = closure; + + free(sreq->api); + free(sreq->verb); + json_object_put(sreq->xreq.json); + sreq->current = sreq->current->next; + if (sreq->current) + startup_call_current(sreq); + else { + afb_session_close(sreq->session); + afb_session_unref(sreq->session); + free(sreq); + } +} + +static struct afb_xreq_query_itf startup_xreq_itf = +{ + .reply = startup_call_reply, + .unref = startup_call_unref +}; + +static void startup_call_current(struct startup_req *sreq) +{ + char *api, *verb, *json; + + api = sreq->current->value; + verb = strchr(api, '/'); + if (verb) { + json = strchr(verb, ':'); + if (json) { + memset(&sreq->xreq, 0, sizeof sreq->xreq); + afb_context_init(&sreq->xreq.context, sreq->session, NULL); + sreq->xreq.context.validated = 1; + sreq->api = strndup(api, verb - api); + sreq->xreq.api = sreq->api; + sreq->verb = strndup(verb + 1, json - verb - 1); + sreq->xreq.verb = sreq->verb; + sreq->xreq.json = json_tokener_parse(json + 1); + sreq->xreq.refcount = 1; + sreq->xreq.query = sreq; + sreq->xreq.queryitf = &startup_xreq_itf; + if (sreq->api && sreq->verb && sreq->xreq.json) { + afb_apis_call(&sreq->xreq); + afb_xreq_unref(&sreq->xreq); + return; + } + } + } + ERROR("Bad call specification %s", sreq->current->value); + exit(1); +} + +static void run_startup_calls() +{ + struct afb_config_list *list; + struct startup_req *sreq; + + list = config->calls; + if (list) { + sreq = calloc(1, sizeof *sreq); + sreq->session = afb_session_create("startup", 3600); + sreq->current = list; + startup_call_current(sreq); + } +} + +/*--------------------------------------------------------- | job for starting the daemon +--------------------------------------------------------- */ @@ -497,6 +595,9 @@ static void start() /* ready */ sd_notify(1, "READY=1"); + + /* run the startup calls */ + run_startup_calls(); return; error: exit(1); |