aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--memo-supervisor.txt1180
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/afb-supervision.c5
-rw-r--r--src/afs-config.c429
-rw-r--r--src/afs-config.h40
-rw-r--r--src/afs-discover.h21
-rw-r--r--src/afs-main.c196
-rw-r--r--src/afs-supervision.h3
-rw-r--r--src/afs-supervisor.c192
-rw-r--r--src/afs-supervisor.h23
10 files changed, 964 insertions, 1127 deletions
diff --git a/memo-supervisor.txt b/memo-supervisor.txt
index 6d901003..9f996b78 100644
--- a/memo-supervisor.txt
+++ b/memo-supervisor.txt
@@ -2,29 +2,16 @@
Run the supervisor on the target for the public IP:
---------------------------------------------------
- # ip address show
+ # afs-supervisor --port 1712 --token HELLO
- 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
- link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
- inet 127.0.0.1/8 scope host lo
- valid_lft forever preferred_lft forever
- 2: eth0: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
- link/ether ee:85:bb:23:a2:26 brd ff:ff:ff:ff:ff:ff
- inet 192.168.0.34/24 brd 192.168.0.255 scope global eth0
- valid_lft forever preferred_lft forever
+Run the client
+--------------
- # afs-supervisor 192.168.0.34:5555/supervisor
+ # afb-client-demo -H host:1712/api?token=HELLO
-Run the direct client
----------------------
- # afb-client-demo -H -d 192.168.0.34:5555/
-
-It is an issue that supervisor provides a direct client.
-This may change in some future to include HTTP websocket negociation and token exchange.
-
-Commands that can be run:
--------------------------
+verbs that can be run, all are of the API 'supervisor':
+-------------------------------------------------------
- discover
@@ -73,10 +60,6 @@ Commands that can be run:
allows to trace specific session or any session
- actually events generated by tracing are named with the prefix
- "$/" (that is the internal prefix of supervision in binders)
- could change in future
-
the pid isn't returned in the event (not sure to want it but open...)
use "name" and "tag" feature of "trace" to discrimate events on the client side.
@@ -84,1019 +67,218 @@ Commands that can be run:
Examples of dialog:
-------------------
-discover
-ON-REPLY-SUCCESS 1:discover:
-null
-
-
-list
-ON-REPLY-SUCCESS 2:list:
+supervisor discover
+ON-REPLY 1:supervisor/discover: OK
{
- "4123":{
- "pid":4123,
- "uid":0,
- "gid":0,
- "id":"nfc-binding",
- "label":"User::App::nfc-binding",
- "user":"0"
- },
- "4120":{
- "pid":4120,
- "uid":0,
- "gid":0,
- "id":"homescreen-service-2017",
- "label":"User::App::homescreen-service-2017",
- "user":"0"
- },
- "4119":{
- "pid":4119,
- "uid":0,
- "gid":0,
- "id":"homescreen-2017",
- "label":"User::App::homescreen-2017",
- "user":"0"
- },
- "4118":{
- "pid":4118,
- "uid":0,
- "gid":0,
- "id":"agl-service-wifi",
- "label":"User::App::agl-service-wifi",
- "user":"0"
- },
- "4117":{
- "pid":4117,
- "uid":0,
- "gid":0,
- "id":"windowmanager-service-2017",
- "label":"User::App::windowmanager-service-2017",
- "user":"0"
- },
- "4116":{
- "pid":4116,
- "uid":0,
- "gid":0,
- "id":"agl-service-geoclue",
- "label":"User::App::agl-service-geoclue",
- "user":"0"
- },
- "4115":{
- "pid":4115,
- "uid":0,
- "gid":0,
- "id":"persistence-binding",
- "label":"User::App::persistence-binding",
- "user":"0"
- },
- "4113":{
- "pid":4113,
- "uid":0,
- "gid":0,
- "id":"agl-service-bluetooth",
- "label":"User::App::agl-service-bluetooth",
- "user":"0"
- },
- "4114":{
- "pid":4114,
- "uid":0,
- "gid":0,
- "id":"agl-identity-service",
- "label":"User::App::agl-identity-service",
- "user":"0"
- },
- "4112":{
- "pid":4112,
- "uid":0,
- "gid":0,
- "id":"agl-service-unicens",
- "label":"User::App::agl-service-unicens",
- "user":"0"
- },
- "3734":{
- "pid":3734,
- "uid":0,
- "gid":0,
- "id":"System",
- "label":"System",
- "user":"0"
+ "jtype":"afb-reply",
+ "request":{
+ "status":"success",
+ "uuid":"22563ce6-e07f-4284-91f8-e7eb7ec4ef21"
}
}
-config {"pid":4117}
-ON-REPLY-SUCCESS 4:config:
+supervisor list
+ON-REPLY 2:supervisor/list: OK
{
- "console":".\/AFB-console.out",
- "rootdir":"\/var\/local\/lib\/afm\/applications\/windowmanager-service-2017\/0.1",
- "roothttp":".",
- "rootbase":"\/opa",
- "rootapi":"\/api",
- "workdir":"\/home\/0\/app-data\/windowmanager-service-2017",
- "uploaddir":".",
- "token":"HELLO",
- "name":"afbd-windowmanager-service-2017@0.1",
- "aliases":[
- "\/monitoring"
- ],
- "dbus_clients":[
- ],
- "dbus_servers":[
- ],
- "ws_clients":[
- ],
- "ws_servers":[
- "sd:windowmanager"
- ],
- "so_bindings":[
- "\/var\/local\/lib\/afm\/applications\/windowmanager-service-2017\/0.1\/lib\/windowmanager-service.so"
- ],
- "ldpaths":[
- "\/usr\/lib\/afb"
- ],
- "weak_ldpaths":[
- ],
- "calls":[
- ],
- "exec":[
- ],
- "httpdPort":1039,
- "cacheTimeout":100000,
- "apiTimeout":20,
- "cntxTimeout":32000000,
- "nbSessionMax":10,
- "mode":"local",
- "tracereq":"no",
- "traceditf":"no",
- "tracesvc":"no",
- "traceevt":"no",
- "no_ldpaths":false,
- "noHttpd":false,
- "background":false,
- "monitoring":true,
- "random_token":false
+ "response":{
+ "7054":{
+ "pid":7054,
+ "uid":1001,
+ "gid":1001,
+ "id":"NoLabel",
+ "label":"NoLabel",
+ "user":"1001"
+ }
+ },
+ "jtype":"afb-reply",
+ "request":{
+ "status":"success"
+ }
}
-sessions {"pid":4117}
-ON-REPLY-SUCCESS 5:sessions:
+
+supervisor config {"pid":7054}
+ON-REPLY 3:supervisor/config: OK
{
- "afb-client-demo":{
- "token":"HELLO"
+ "response":{
+ "console":".\/AFB-console.out",
+ "rootdir":".",
+ "roothttp":"..\/test",
+ "rootbase":"\/opa",
+ "rootapi":"\/api",
+ "workdir":".",
+ "uploaddir":".",
+ "token":"",
+ "name":null,
+ "aliases":[
+ "\/monitoring"
+ ],
+ "dbus_clients":[
+ ],
+ "dbus_servers":[
+ ],
+ "ws_clients":[
+ ],
+ "ws_servers":[
+ ],
+ "so_bindings":[
+ ],
+ "ldpaths":[
+ "\/opt\/jobol\/lib64\/afb"
+ ],
+ "weak_ldpaths":[
+ ],
+ "calls":[
+ ],
+ "exec":[
+ ],
+ "httpdPort":5555,
+ "cacheTimeout":100000,
+ "apiTimeout":20,
+ "cntxTimeout":32000000,
+ "nbSessionMax":10,
+ "mode":"local",
+ "tracereq":"no",
+ "traceditf":"no",
+ "tracesvc":"no",
+ "traceevt":"no",
+ "traceses":"no",
+ "no_ldpaths":false,
+ "noHttpd":false,
+ "background":false,
+ "monitoring":true,
+ "random_token":false
},
- "fa050ca1-80b4-41af-bf72-4a1a8e7ee5b6":{
- "token":"HELLO"
+ "jtype":"afb-reply",
+ "request":{
+ "status":"success"
}
}
-do {"pid":4117,"api":"monitor","verb":"get","args":{"apis":true}}
-ON-REPLY-SUCCESS 6:do:
+
+
+
+supervisor sessions {"pid":7054}
+ON-REPLY 4:supervisor/sessions: OK
{
- "apis":{
- "monitor":{
- "openapi":"3.0.0",
- "info":{
- "description":"monitoring of bindings and internals",
- "title":"monitor",
- "version":"1.0",
- "x-binding-c-generator":{
- "api":"monitor",
- "version":2,
- "prefix":"f_",
- "postfix":"",
- "preinit":null,
- "init":null,
- "onevent":null,
- "scope":"static",
- "private":true
- }
- },
- "servers":[
- {
- "url":"ws:\/\/{host}:{port}\/api\/monitor",
- "description":"The API server.",
- "variables":{
- "host":{
- "default":"localhost"
- },
- "port":{
- "default":"1234"
- }
- },
- "x-afb-events":[
- {
- "$ref":"#\/components\/schemas\/afb-event"
- }
- ]
- }
- ],
- "components":{
- "schemas":{
- "afb-reply":{
- "$ref":"#\/components\/schemas\/afb-reply-v1"
- },
- "afb-event":{
- "$ref":"#\/components\/schemas\/afb-event-v1"
- },
- "afb-reply-v1":{
- "title":"Generic response.",
- "type":"object",
- "required":[
- "jtype",
- "request"
- ],
- "properties":{
- "jtype":{
- "type":"string",
- "const":"afb-reply"
- },
- "request":{
- "type":"object",
- "required":[
- "status"
- ],
- "properties":{
- "status":{
- "type":"string"
- },
- "info":{
- "type":"string"
- },
- "token":{
- "type":"string"
- },
- "uuid":{
- "type":"string"
- },
- "reqid":{
- "type":"string"
- }
- }
- },
- "response":{
- "type":"object"
- }
- }
- },
- "afb-event-v1":{
- "type":"object",
- "required":[
- "jtype",
- "event"
- ],
- "properties":{
- "jtype":{
- "type":"string",
- "const":"afb-event"
- },
- "event":{
- "type":"string"
- },
- "data":{
- "type":"object"
- }
- }
- },
- "set-verbosity":{
- "anyOf":[
- {
- "$ref":"#\/components\/schemas\/verbosity-map"
- },
- {
- "$ref":"#\/components\/schemas\/verbosity-level"
- }
- ]
- },
- "get-request":{
- "type":"object",
- "properties":{
- "verbosity":{
- "$ref":"#\/components\/schemas\/get-verbosity"
- },
- "apis":{
- "$ref":"#\/components\/schemas\/get-apis"
- }
- }
- },
- "get-response":{
- "type":"object",
- "properties":{
- "verbosity":{
- "$ref":"#\/components\/schemas\/verbosity-map"
- },
- "apis":{
- "type":"object"
- }
- }
- },
- "get-verbosity":{
- "anyOf":[
- {
- "type":"boolean"
- },
- {
- "type":"array",
- "items":{
- "type":"string"
- }
- },
- {
- "type":"object"
- }
- ]
- },
- "get-apis":{
- "anyOf":[
- {
- "type":"boolean"
- },
- {
- "type":"array",
- "items":{
- "type":"string"
- }
- },
- {
- "type":"object"
- }
- ]
- },
- "verbosity-map":{
- "type":"object",
- "patternProperties":{
- "^.*$":{
- "$ref":"#\/components\/schemas\/verbosity-level"
- }
- }
- },
- "verbosity-level":{
- "enum":[
- "debug",
- 3,
- "info",
- 2,
- "notice",
- "warning",
- 1,
- "error",
- 0
- ]
- },
- "trace-add":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-add-object"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-add-any"
- }
- ]
- },
- "trace-add-any":{
- "anyOf":[
- {
- "$ref":"#\/components\/schemas\/trace-add-request"
- },
- {
- "$ref":"#\/components\/schemas\/trace-add-object"
- }
- ]
- },
- "trace-add-object":{
- "type":"object",
- "properties":{
- "name":{
- "type":"string",
- "description":"name of the generated event",
- "default":"trace"
- },
- "tag":{
- "type":"string",
- "description":"tag for grouping traces",
- "default":"trace"
- },
- "api":{
- "type":"string",
- "description":"api for requests, daemons and services"
- },
- "verb":{
- "type":"string",
- "description":"verb for requests"
- },
- "uuid":{
- "type":"string",
- "description":"uuid of session for requests"
- },
- "pattern":{
- "type":"string",
- "description":"pattern for events"
- },
- "request":{
- "$ref":"#\/components\/schemas\/trace-add-request"
- },
- "daemon":{
- "$ref":"#\/components\/schemas\/trace-add-daemon"
- },
- "service":{
- "$ref":"#\/components\/schemas\/trace-add-service"
- },
- "event":{
- "$ref":"#\/components\/schemas\/trace-add-event"
- },
- "session":{
- "$ref":"#\/components\/schemas\/trace-add-session"
- },
- "for":{
- "$ref":"#\/components\/schemas\/trace-add"
- }
- },
- "examples":[
- {
- "tag":"1",
- "for":[
- "common",
- {
- "api":"xxx",
- "request":"*",
- "daemon":"*",
- "service":"*"
- }
- ]
- }
- ]
- },
- "trace-add-request":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-request-names"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-request-names"
- }
- ]
- },
- "trace-request-names":{
- "title":"name of traceable items of requests",
- "enum":[
- "*",
- "addref",
- "all",
- "args",
- "begin",
- "common",
- "context",
- "context_get",
- "context_set",
- "end",
- "event",
- "extra",
- "fail",
- "get",
- "json",
- "life",
- "ref",
- "result",
- "session",
- "session_close",
- "session_set_LOA",
- "simple",
- "store",
- "stores",
- "subcall",
- "subcall_result",
- "subcalls",
- "subcallsync",
- "subcallsync_result",
- "subscribe",
- "success",
- "unref",
- "unstore",
- "unsubscribe",
- "vverbose"
- ]
- },
- "trace-add-daemon":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-daemon-names"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-daemon-names"
- }
- ]
- },
- "trace-daemon-names":{
- "title":"name of traceable items of daemons",
- "enum":[
- "*",
- "all",
- "common",
- "event_broadcast_after",
- "event_broadcast_before",
- "event_make",
- "extra",
- "get_event_loop",
- "get_system_bus",
- "get_user_bus",
- "queue_job",
- "require_api",
- "require_api_result",
- "rootdir_get_fd",
- "rootdir_open_locale",
- "unstore_req",
- "vverbose"
- ]
- },
- "trace-add-service":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-service-names"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-service-names"
- }
- ]
- },
- "trace-service-names":{
- "title":"name of traceable items of services",
- "enum":[
- "*",
- "all",
- "call",
- "call_result",
- "callsync",
- "callsync_result",
- "on_event_after",
- "on_event_before",
- "start_after",
- "start_before"
- ]
- },
- "trace-add-event":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-event-names"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-event-names"
- }
- ]
- },
- "trace-event-names":{
- "title":"name of traceable items of events",
- "enum":[
- "*",
- "all",
- "broadcast_after",
- "broadcast_before",
- "common",
- "create",
- "drop",
- "extra",
- "name",
- "push_after",
- "push_before"
- ]
- },
- "trace-add-session":{
- "anyOf":[
- {
- "type":"array",
- "items":{
- "$ref":"#\/components\/schemas\/trace-session-names"
- }
- },
- {
- "$ref":"#\/components\/schemas\/trace-session-names"
- }
- ]
- },
- "trace-session-names":{
- "title":"name of traceable items for sessions",
- "enum":[
- "*",
- "addref",
- "all",
- "close",
- "common",
- "create",
- "destroy",
- "renew",
- "unref"
- ]
- },
- "trace-drop":{
- "anyOf":[
- {
- "type":"boolean"
- },
- {
- "type":"object",
- "properties":{
- "event":{
- "anyOf":[
- {
- "type":"string"
- },
- {
- "type":"array",
- "items":"string"
- }
- ]
- },
- "tag":{
- "anyOf":[
- {
- "type":"string"
- },
- {
- "type":"array",
- "items":"string"
- }
- ]
- },
- "uuid":{
- "anyOf":[
- {
- "type":"string"
- },
- {
- "type":"array",
- "items":"string"
- }
- ]
- }
- }
- }
- ]
- }
- }
- },
- "paths":{
- "\/get":{
- "description":"Get monitoring data.",
- "get":{
- "x-permissions":{
- "session":"check"
- },
- "parameters":[
- {
- "in":"query",
- "name":"verbosity",
- "required":false,
- "schema":{
- "$ref":"#\/components\/schemas\/get-verbosity"
- }
- },
- {
- "in":"query",
- "name":"apis",
- "required":false,
- "schema":{
- "$ref":"#\/components\/schemas\/get-apis"
- }
- }
- ],
- "responses":{
- "200":{
- "description":"A complex object array response",
- "content":{
- "application\/json":{
- "schema":{
- "$ref":"#\/components\/schemas\/afb-reply"
- }
- }
- }
- }
- }
- }
- },
- "\/set":{
- "description":"Set monitoring actions.",
- "get":{
- "x-permissions":{
- "session":"check"
- },
- "parameters":[
- {
- "in":"query",
- "name":"verbosity",
- "required":false,
- "schema":{
- "$ref":"#\/components\/schemas\/set-verbosity"
- }
- }
- ],
- "responses":{
- "200":{
- "description":"A complex object array response",
- "content":{
- "application\/json":{
- "schema":{
- "$ref":"#\/components\/schemas\/afb-reply"
- }
- }
- }
- }
- }
- }
- },
- "\/trace":{
- "description":"Set monitoring actions.",
- "get":{
- "x-permissions":{
- "session":"check"
- },
- "parameters":[
- {
- "in":"query",
- "name":"add",
- "required":false,
- "schema":{
- "$ref":"#\/components\/schemas\/trace-add"
- }
- },
- {
- "in":"query",
- "name":"drop",
- "required":false,
- "schema":{
- "$ref":"#\/components\/schemas\/trace-drop"
- }
- }
- ],
- "responses":{
- "200":{
- "description":"A complex object array response",
- "content":{
- "application\/json":{
- "schema":{
- "$ref":"#\/components\/schemas\/afb-reply"
- }
- }
- }
- }
- }
- }
- },
- "\/session":{
- "description":"describes the session.",
- "get":{
- "x-permissions":{
- "session":"check"
- },
- "parameters":[
- {
- "in":"query",
- "name":"refresh-token",
- "required":false,
- "schema":{
- "type":"boolean"
- }
- }
- ],
- "responses":{
- "200":{
- "description":"A complex object array response",
- "content":{
- "application\/json":{
- "schema":{
- "$ref":"#\/components\/schemas\/afb-reply"
- }
- }
- }
- }
- }
- }
- }
- }
+ "response":{
+ "2273ff8d-ee46-4059-959b-0f90fa90f25e":{
+ "token":""
},
- "windowmanager":{
- "openapi":"3.0.0",
- "info":{
- "title":"windowmanager",
- "version":"0.0.0",
- "description":"windowmanager"
- },
- "paths":{
- "\/requestsurface":{
- "get":{
- "responses":{
- "200":{
- "description":"requestsurface"
- }
- }
- }
- },
- "\/requestsurfacexdg":{
- "get":{
- "responses":{
- "200":{
- "description":"requestsurfacexdg"
- }
- }
- }
- },
- "\/activatesurface":{
- "get":{
- "responses":{
- "200":{
- "description":"activatesurface"
- }
- }
- }
- },
- "\/deactivatesurface":{
- "get":{
- "responses":{
- "200":{
- "description":"deactivatesurface"
- }
- }
- }
- },
- "\/enddraw":{
- "get":{
- "responses":{
- "200":{
- "description":"enddraw"
- }
- }
- }
- },
- "\/getdisplayinfo":{
- "get":{
- "responses":{
- "200":{
- "description":"getdisplayinfo"
- }
- }
- }
- },
- "\/getareainfo":{
- "get":{
- "responses":{
- "200":{
- "description":"getareainfo"
- }
- }
- }
- },
- "\/wm_subscribe":{
- "get":{
- "responses":{
- "200":{
- "description":"wm_subscribe"
- }
- }
- }
- },
- "\/list_drawing_names":{
- "get":{
- "responses":{
- "200":{
- "description":"list_drawing_names"
- }
- }
- }
- },
- "\/ping":{
- "get":{
- "responses":{
- "200":{
- "description":"ping"
- }
- }
- }
- },
- "\/debug_status":{
- "get":{
- "responses":{
- "200":{
- "description":"debug_status"
- }
- }
- }
- },
- "\/debug_layers":{
- "get":{
- "responses":{
- "200":{
- "description":"debug_layers"
- }
- }
- }
- },
- "\/debug_surfaces":{
- "get":{
- "responses":{
- "200":{
- "description":"debug_surfaces"
- }
- }
- }
- },
- "\/debug_terminate":{
- "get":{
- "responses":{
- "200":{
- "description":"debug_terminate"
- }
- }
- }
- }
- }
+ "22563ce6-e07f-4284-91f8-e7eb7ec4ef21":{
+ "token":""
}
+ },
+ "jtype":"afb-reply",
+ "request":{
+ "status":"success"
}
}
-trace { "pid": 4117, "add": { "request": "common" } }
-ON-EVENT-CREATE: [4:$/trace]
-ON-EVENT-SUBSCRIBE 15:trace: [4:$/trace]
-ON-REPLY-SUCCESS 15:trace:
-null
-ON-EVENT-PUSH: [4:$/trace]
+
+supervisor do {"pid":7054,"api":"monitor","verb":"get","args":{"apis":true}}
+.....VERY LONG RESPONSE.....
+
+
+
+
+supervisor trace { "pid": 7054, "add": { "request": "common" } }
+ON-REPLY 6:supervisor/trace: OK
{
- "time":"30862.255651",
- "tag":"trace",
- "type":"request",
- "id":51,
+ "jtype":"afb-reply",
"request":{
- "index":5,
- "api":"hello",
- "verb":"ping",
- "action":"begin",
- "session":"fa050ca1-80b4-41af-bf72-4a1a8e7ee5b6"
+ "status":"success"
}
}
-ON-EVENT-PUSH: [4:$/trace]
+
+
+
+
+
+ON-EVENT supervisor/trace:
{
- "time":"30862.255788",
- "tag":"trace",
- "type":"request",
- "id":52,
- "request":{
- "index":5,
- "api":"hello",
- "verb":"ping",
- "action":"json",
- "session":"fa050ca1-80b4-41af-bf72-4a1a8e7ee5b6"
- },
+ "event":"supervisor\/trace",
"data":{
- "result":{
- "toto":"1"
+ "time":"34353.598120",
+ "tag":"trace",
+ "type":"request",
+ "id":34,
+ "request":{
+ "index":1,
+ "api":"ave",
+ "verb":"ping",
+ "action":"begin",
+ "session":"be67cfb8-a346-47c1-ac63-65aaff3599bf"
}
- }
+ },
+ "jtype":"afb-event"
}
-ON-EVENT-PUSH: [4:$/trace]
+ON-EVENT supervisor/trace:
{
- "time":"30862.255871",
- "tag":"trace",
- "type":"request",
- "id":53,
- "request":{
- "index":5,
- "api":"hello",
- "verb":"ping",
- "action":"success",
- "session":"fa050ca1-80b4-41af-bf72-4a1a8e7ee5b6"
+ "event":"supervisor\/trace",
+ "data":{
+ "time":"34353.598182",
+ "tag":"trace",
+ "type":"request",
+ "id":35,
+ "request":{
+ "index":1,
+ "api":"ave",
+ "verb":"ping",
+ "action":"json",
+ "session":"be67cfb8-a346-47c1-ac63-65aaff3599bf"
+ },
+ "data":{
+ "result":"true"
+ }
},
+ "jtype":"afb-event"
+}
+ON-EVENT supervisor/trace:
+{
+ "event":"supervisor\/trace",
"data":{
- "result":"Some String",
- "info":"Ping Binder Daemon tag=pingSample count=1 query={ \"toto\": \"1\" }"
- }
+ "time":"34353.598214",
+ "tag":"trace",
+ "type":"request",
+ "id":36,
+ "request":{
+ "index":1,
+ "api":"ave",
+ "verb":"ping",
+ "action":"success",
+ "session":"be67cfb8-a346-47c1-ac63-65aaff3599bf"
+ },
+ "data":{
+ "result":"Some String",
+ "info":"Ping Binder Daemon tag=pingSample count=1 query=\"true\""
+ }
+ },
+ "jtype":"afb-event"
}
-ON-EVENT-PUSH: [4:$/trace]
+ON-EVENT supervisor/trace:
{
- "time":"30862.255980",
- "tag":"trace",
- "type":"request",
- "id":54,
- "request":{
- "index":5,
- "api":"hello",
- "verb":"ping",
- "action":"end",
- "session":"fa050ca1-80b4-41af-bf72-4a1a8e7ee5b6"
- }
+ "event":"supervisor\/trace",
+ "data":{
+ "time":"34353.598292",
+ "tag":"trace",
+ "type":"request",
+ "id":37,
+ "request":{
+ "index":1,
+ "api":"ave",
+ "verb":"ping",
+ "action":"end",
+ "session":"be67cfb8-a346-47c1-ac63-65aaff3599bf"
+ }
+ },
+ "jtype":"afb-event"
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f72d312e..bfe187f5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -89,7 +89,7 @@ INSTALL(TARGETS afb-daemon
###########################################
# build and install afb-daemon
###########################################
-ADD_EXECUTABLE(afs-supervisor afs-supervisor.c afs-discover.c)
+ADD_EXECUTABLE(afs-supervisor afs-main.c afs-supervisor.c afs-discover.c afs-config.c)
TARGET_LINK_LIBRARIES(afs-supervisor
afb-lib
${link_libraries}
diff --git a/src/afb-supervision.c b/src/afb-supervision.c
index 1ff8f8b5..97595245 100644
--- a/src/afb-supervision.c
+++ b/src/afb-supervision.c
@@ -51,7 +51,8 @@
extern struct afb_config *main_config;
/* api and apiset name */
-static const char supervision_apiname[] = AFS_SURPERVISION_APINAME_INTERNAL;
+static const char supervision_apiname[] = AFS_SURPERVISION_APINAME;
+static const char supervisor_apiname[] = AFS_SURPERVISOR_APINAME;
/* path of the supervision socket */
static const char supervisor_socket_path[] = AFS_SURPERVISION_SOCKET;
@@ -346,7 +347,7 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq)
break;
case Trace:
if (!trace)
- trace = afb_trace_create(supervision_apiname, NULL /* not bound to any session */);
+ trace = afb_trace_create(supervisor_apiname, NULL /* not bound to any session */);
req = xreq_to_req(xreq);
add = drop = NULL;
diff --git a/src/afs-config.c b/src/afs-config.c
new file mode 100644
index 00000000..80504d05
--- /dev/null
+++ b/src/afs-config.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2015, 2016, 2017 "IoT.bzh"
+ * Author José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "verbose.h"
+#include "afs-config.h"
+
+#if !defined(AFB_VERSION)
+#error "you should define AFB_VERSION"
+#endif
+
+// default
+#define DEFLT_CNTX_TIMEOUT 32000000 // default Client Connection
+ // Timeout: few more than one year
+#define DEFLT_API_TIMEOUT 20 // default Plugin API Timeout [0=NoLimit
+ // for Debug Only]
+#define DEFLT_CACHE_TIMEOUT 100000 // default Static File Chache
+ // [Client Side Cache
+ // 100000~=1day]
+#define CTX_NBCLIENTS 10 // allow a default of 10 authenticated
+ // clients
+
+
+// Define command line option
+#define SET_ROOT_DIR 6
+#define SET_ROOT_BASE 7
+#define SET_ROOT_API 8
+
+#define SET_CACHE_TIMEOUT 10
+#define SET_SESSION_DIR 11
+
+#define SET_APITIMEOUT 14
+#define SET_CNTXTIMEOUT 15
+
+#define SET_SESSIONMAX 23
+
+#define SET_ROOT_HTTP 26
+
+#define DISPLAY_HELP 'h'
+#define SET_NAME 'n'
+#define SET_TCP_PORT 'p'
+#define SET_QUIET 'q'
+#define SET_AUTH_TOKEN 't'
+#define SET_UPLOAD_DIR 'u'
+#define DISPLAY_VERSION 'V'
+#define SET_VERBOSE 'v'
+#define SET_WORK_DIR 'w'
+
+const char shortopts[] =
+ "hn:p:qrt:u:Vvw:"
+;
+
+// Command line structure hold cli --command + help text
+typedef struct {
+ int val; // command number within application
+ int has_arg; // command number within application
+ char *name; // command as used in --xxxx cli
+ char *help; // help text
+} AFB_options;
+
+// Supported option
+static AFB_options cliOptions[] = {
+/* *INDENT-OFF* */
+ {SET_VERBOSE, 0, "verbose", "Verbose Mode, repeat to increase verbosity"},
+ {SET_QUIET, 0, "quiet", "Quiet Mode, repeat to decrease verbosity"},
+
+ {SET_NAME, 1, "name", "Set the visible name"},
+
+ {SET_TCP_PORT, 1, "port", "HTTP listening TCP port [default 1234]"},
+ {SET_ROOT_HTTP, 1, "roothttp", "HTTP Root Directory [default no root http (files not served but apis still available)]"},
+ {SET_ROOT_BASE, 1, "rootbase", "Angular Base Root URL [default /opa]"},
+ {SET_ROOT_API, 1, "rootapi", "HTML Root API URL [default /api]"},
+
+ {SET_APITIMEOUT, 1, "apitimeout", "Binding API timeout in seconds [default 10]"},
+ {SET_CNTXTIMEOUT, 1, "cntxtimeout", "Client Session Context Timeout [default 900]"},
+ {SET_CACHE_TIMEOUT, 1, "cache-eol", "Client cache end of live [default 3600]"},
+
+ {SET_WORK_DIR, 1, "workdir", "Set the working directory [default: $PWD or current working directory]"},
+ {SET_UPLOAD_DIR, 1, "uploaddir", "Directory for uploading files [default: workdir]"},
+ {SET_ROOT_DIR, 1, "rootdir", "Root Directory of the application [default: workdir]"},
+ {SET_SESSION_DIR, 1, "sessiondir", "OBSOLETE (was: Sessions file path)"},
+
+ {SET_AUTH_TOKEN, 1, "token", "Initial Secret [default=random, use --token="" to allow any token]"},
+
+ {DISPLAY_VERSION, 0, "version", "Display version and copyright"},
+ {DISPLAY_HELP, 0, "help", "Display this help"},
+
+ {SET_SESSIONMAX, 1, "session-max", "Max count of session simultaneously [default 10]"},
+
+ {0, 0, NULL, NULL}
+/* *INDENT-ON* */
+};
+
+
+struct enumdesc
+{
+ const char *name;
+ int value;
+};
+
+/*----------------------------------------------------------
+ | printversion
+ | print version and copyright
+ +--------------------------------------------------------- */
+static void printVersion(FILE * file)
+{
+ static const char version[] =
+ "\n"
+ " afs-supervisor [Application Framework Supervisor] version="AFB_VERSION"\n"
+ "\n"
+ " Copyright (C) 2015-2018 \"IoT.bzh\"\n"
+ " afs-supervisor comes with ABSOLUTELY NO WARRANTY.\n"
+ " Licence Apache 2\n"
+ "\n";
+
+ fprintf(file, "%s", version);
+}
+
+/*----------------------------------------------------------
+ | printHelp
+ | print information from long option array
+ +--------------------------------------------------------- */
+
+static void printHelp(FILE * file, const char *name)
+{
+ int ind;
+ char command[50];
+
+ fprintf(file, "%s:\nallowed options\n", name);
+ for (ind = 0; cliOptions[ind].name != NULL; ind++) {
+ strcpy(command, cliOptions[ind].name);
+ if (cliOptions[ind].has_arg)
+ strcat(command, "=xxxx");
+ fprintf(file, " --%-15s %s\n", command, cliOptions[ind].help);
+ }
+ fprintf(file,
+ "Example:\n %s --verbose --port=1234 --token='azerty'\n",
+ name);
+}
+
+
+/*---------------------------------------------------------
+ | helpers for argument scanning
+ +--------------------------------------------------------- */
+
+static const char *name_of_option(int optc)
+{
+ AFB_options *o = cliOptions;
+ while (o->name && o->val != optc)
+ o++;
+ return o->name ? : "<unknown-option-name>";
+}
+
+static const char *current_argument(int optc)
+{
+ if (optarg == 0) {
+ ERROR("option [--%s] needs a value i.e. --%s=xxx",
+ name_of_option(optc), name_of_option(optc));
+ exit(1);
+ }
+ return optarg;
+}
+
+static char *argvalstr(int optc)
+{
+ char *result = strdup(current_argument(optc));
+ if (result == NULL) {
+ ERROR("can't alloc memory");
+ exit(1);
+ }
+ return result;
+}
+
+static int argvalint(int optc, int mini, int maxi, int base)
+{
+ const char *beg, *end;
+ long int val;
+ beg = current_argument(optc);
+ val = strtol(beg, (char**)&end, base);
+ if (*end || end == beg) {
+ ERROR("option [--%s] requires a valid integer (found %s)",
+ name_of_option(optc), beg);
+ exit(1);
+ }
+ if (val < (long int)mini || val > (long int)maxi) {
+ ERROR("option [--%s] value out of bounds (not %d<=%ld<=%d)",
+ name_of_option(optc), mini, val, maxi);
+ exit(1);
+ }
+ return (int)val;
+}
+
+static int argvalintdec(int optc, int mini, int maxi)
+{
+ return argvalint(optc, mini, maxi, 10);
+}
+
+static void noarg(int optc)
+{
+ if (optarg != 0) {
+ ERROR("option [--%s] need no value (found %s)", name_of_option(optc), optarg);
+ exit(1);
+ }
+}
+
+/*---------------------------------------------------------
+ | Parse option and launch action
+ +--------------------------------------------------------- */
+
+static void parse_arguments(int argc, char **argv, struct afs_config *config)
+{
+ char *programName = argv[0];
+ int optc, ind;
+ int nbcmd;
+ struct option *gnuOptions;
+
+ // ------------------ Process Command Line -----------------------
+
+ // build GNU getopt info from cliOptions
+ nbcmd = sizeof(cliOptions) / sizeof(AFB_options);
+ gnuOptions = malloc(sizeof(*gnuOptions) * (unsigned)nbcmd);
+ for (ind = 0; ind < nbcmd; ind++) {
+ gnuOptions[ind].name = cliOptions[ind].name;
+ gnuOptions[ind].has_arg = cliOptions[ind].has_arg;
+ gnuOptions[ind].flag = 0;
+ gnuOptions[ind].val = cliOptions[ind].val;
+ }
+
+ // get all options from command line
+ while ((optc = getopt_long(argc, argv, shortopts, gnuOptions, NULL)) != EOF) {
+ switch (optc) {
+ case SET_VERBOSE:
+ verbosity++;
+ break;
+
+ case SET_QUIET:
+ verbosity--;
+ break;
+
+ case SET_TCP_PORT:
+ config->httpdPort = argvalintdec(optc, 1024, 32767);
+ break;
+
+ case SET_APITIMEOUT:
+ config->apiTimeout = argvalintdec(optc, 0, INT_MAX);
+ break;
+
+ case SET_CNTXTIMEOUT:
+ config->cntxTimeout = argvalintdec(optc, 0, INT_MAX);
+ break;
+
+ case SET_ROOT_DIR:
+ config->rootdir = argvalstr(optc);
+ INFO("Forcing Rootdir=%s", config->rootdir);
+ break;
+
+ case SET_ROOT_HTTP:
+ config->roothttp = argvalstr(optc);
+ INFO("Forcing Root HTTP=%s", config->roothttp);
+ break;
+
+ case SET_ROOT_BASE:
+ config->rootbase = argvalstr(optc);
+ INFO("Forcing Rootbase=%s", config->rootbase);
+ break;
+
+ case SET_ROOT_API:
+ config->rootapi = argvalstr(optc);
+ INFO("Forcing Rootapi=%s", config->rootapi);
+ break;
+
+ case SET_AUTH_TOKEN:
+ config->token = argvalstr(optc);
+ break;
+
+ case SET_UPLOAD_DIR:
+ config->uploaddir = argvalstr(optc);
+ break;
+
+ case SET_WORK_DIR:
+ config->workdir = argvalstr(optc);
+ break;
+
+ case SET_CACHE_TIMEOUT:
+ config->cacheTimeout = argvalintdec(optc, 0, INT_MAX);
+ break;
+
+ case SET_SESSIONMAX:
+ config->nbSessionMax = argvalintdec(optc, 1, INT_MAX);
+ break;
+
+ case SET_NAME:
+ config->name = argvalstr(optc);
+ break;
+
+ case DISPLAY_VERSION:
+ noarg(optc);
+ printVersion(stdout);
+ exit(0);
+
+ case DISPLAY_HELP:
+ printHelp(stdout, programName);
+ exit(0);
+
+ default:
+ exit(1);
+ }
+ }
+ free(gnuOptions);
+}
+
+static void fulfill_config(struct afs_config *config)
+{
+ // default HTTP port
+ if (config->httpdPort == 0)
+ config->httpdPort = 1234;
+
+ // default binding API timeout
+ if (config->apiTimeout == 0)
+ config->apiTimeout = DEFLT_API_TIMEOUT;
+
+ // cache timeout default one hour
+ if (config->cacheTimeout == 0)
+ config->cacheTimeout = DEFLT_CACHE_TIMEOUT;
+
+ // cache timeout default one hour
+ if (config->cntxTimeout == 0)
+ config->cntxTimeout = DEFLT_CNTX_TIMEOUT;
+
+ // max count of sessions
+ if (config->nbSessionMax == 0)
+ config->nbSessionMax = CTX_NBCLIENTS;
+
+ /* set directories */
+ if (config->workdir == NULL)
+ config->workdir = ".";
+
+ if (config->rootdir == NULL)
+ config->rootdir = ".";
+
+ if (config->uploaddir == NULL)
+ config->uploaddir = ".";
+
+ // if no Angular/HTML5 rootbase let's try '/' as default
+ if (config->rootbase == NULL)
+ config->rootbase = "/opa";
+
+ if (config->rootapi == NULL)
+ config->rootapi = "/api";
+}
+
+void afs_config_dump(struct afs_config *config)
+{
+#define NN(x) (x)?:""
+#define P(...) fprintf(stderr, __VA_ARGS__)
+#define PF(x) P("-- %15s: ", #x)
+#define PE P("\n")
+#define S(x) PF(x);P("%s",NN(config->x));PE;
+#define D(x) PF(x);P("%d",config->x);PE;
+
+ P("---BEGIN-OF-CONFIG---\n");
+ S(rootdir)
+ S(roothttp)
+ S(rootbase)
+ S(rootapi)
+ S(workdir)
+ S(uploaddir)
+ S(token)
+ S(name)
+
+ D(httpdPort)
+ D(cacheTimeout)
+ D(apiTimeout)
+ D(cntxTimeout)
+ D(nbSessionMax)
+ P("---END-OF-CONFIG---\n");
+
+#undef V
+#undef E
+#undef L
+#undef B
+#undef D
+#undef S
+#undef PE
+#undef PF
+#undef P
+#undef NN
+}
+
+static void parse_environment(struct afs_config *config)
+{
+}
+
+struct afs_config *afs_config_parse_arguments(int argc, char **argv)
+{
+ struct afs_config *result;
+
+ result = calloc(1, sizeof *result);
+
+ parse_environment(result);
+ parse_arguments(argc, argv, result);
+ fulfill_config(result);
+ if (verbosity >= 3)
+ afs_config_dump(result);
+ return result;
+}
+
diff --git a/src/afs-config.h b/src/afs-config.h
new file mode 100644
index 00000000..826f6a25
--- /dev/null
+++ b/src/afs-config.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015, 2016, 2017 "IoT.bzh"
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// main config structure
+struct afs_config {
+ char *rootdir; // base dir for files
+ char *roothttp; // directory for http files
+ char *rootbase; // Angular HTML5 base URL
+ char *rootapi; // Base URL for REST APIs
+ char *workdir; // where to run the program
+ char *uploaddir; // where to store transient files
+ char *token; // initial authentication token [default NULL no session]
+ char *name; /* name to set to the daemon */
+
+ /* integers */
+ int httpdPort;
+ int cacheTimeout;
+ int apiTimeout;
+ int cntxTimeout; // Client Session Context timeout
+ int nbSessionMax; // max count of sessions
+};
+
+extern struct afs_config *afs_config_parse_arguments(int argc, char **argv);
+extern void afs_config_dump(struct afs_config *config);
+
diff --git a/src/afs-discover.h b/src/afs-discover.h
new file mode 100644
index 00000000..7a27a5df
--- /dev/null
+++ b/src/afs-discover.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+extern void afs_discover(const char *pattern, void (*callback)(void *closure, pid_t pid), void *closure);
+
diff --git a/src/afs-main.c b/src/afs-main.c
new file mode 100644
index 00000000..99689e90
--- /dev/null
+++ b/src/afs-main.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016, 2017 "IoT.bzh"
+ * Author José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "afb-common.h"
+#include "afb-hsrv.h"
+#include "afb-hswitch.h"
+#include "afb-hreq.h"
+#include "afb-apiset.h"
+#include "afb-session.h"
+
+#include "afs-supervisor.h"
+#include "afs-config.h"
+
+#include "verbose.h"
+#include "jobs.h"
+#include "process-name.h"
+
+/* the main config */
+struct afs_config *main_config;
+
+/* the main apiset */
+struct afb_apiset *main_apiset;
+
+/*************************************************************************************/
+
+static int init_http_server(struct afb_hsrv *hsrv)
+{
+ if (!afb_hsrv_add_handler
+ (hsrv, main_config->rootapi, afb_hswitch_websocket_switch, main_apiset, 20))
+ return 0;
+
+ if (!afb_hsrv_add_handler
+ (hsrv, main_config->rootapi, afb_hswitch_apis, main_apiset, 10))
+ return 0;
+
+ if (main_config->roothttp != NULL) {
+ if (!afb_hsrv_add_alias
+ (hsrv, "", afb_common_rootdir_get_fd(), main_config->roothttp,
+ -10, 1))
+ return 0;
+ }
+
+ if (!afb_hsrv_add_handler
+ (hsrv, main_config->rootbase, afb_hswitch_one_page_api_redirect, NULL,
+ -20))
+ return 0;
+
+ return 1;
+}
+
+static struct afb_hsrv *start_http_server()
+{
+ int rc;
+ struct afb_hsrv *hsrv;
+
+ if (afb_hreq_init_download_path(main_config->uploaddir)) {
+ ERROR("unable to set the upload directory %s", main_config->uploaddir);
+ return NULL;
+ }
+
+ hsrv = afb_hsrv_create();
+ if (hsrv == NULL) {
+ ERROR("memory allocation failure");
+ return NULL;
+ }
+
+ if (!afb_hsrv_set_cache_timeout(hsrv, main_config->cacheTimeout)
+ || !init_http_server(hsrv)) {
+ ERROR("initialisation of httpd failed");
+ afb_hsrv_put(hsrv);
+ return NULL;
+ }
+
+ NOTICE("Waiting port=%d rootdir=%s", main_config->httpdPort, main_config->rootdir);
+ NOTICE("Browser URL= http://localhost:%d", main_config->httpdPort);
+
+ rc = afb_hsrv_start(hsrv, (uint16_t) main_config->httpdPort, 15);
+ if (!rc) {
+ ERROR("starting of httpd failed");
+ afb_hsrv_put(hsrv);
+ return NULL;
+ }
+
+ return hsrv;
+}
+
+static void start(int signum, void *arg)
+{
+ struct afb_hsrv *hsrv;
+ int rc;
+
+ /* check illness */
+ if (signum) {
+ ERROR("start aborted: received signal %s", strsignal(signum));
+ exit(1);
+ }
+
+ /* set the directories */
+ mkdir(main_config->workdir, S_IRWXU | S_IRGRP | S_IXGRP);
+ if (chdir(main_config->workdir) < 0) {
+ ERROR("Can't enter working dir %s", main_config->workdir);
+ goto error;
+ }
+ if (afb_common_rootdir_set(main_config->rootdir) < 0) {
+ ERROR("failed to set common root directory");
+ goto error;
+ }
+
+ /* configure the daemon */
+ if (afb_session_init(main_config->nbSessionMax, main_config->cntxTimeout, main_config->token)) {
+ ERROR("initialisation of session manager failed");
+ goto error;
+ }
+
+ main_apiset = afb_apiset_create("main", main_config->apiTimeout);
+ if (!main_apiset) {
+ ERROR("can't create main apiset");
+ goto error;
+ }
+
+ /* init the main apiset */
+ rc = afs_supervisor_add(main_apiset);
+ if (rc < 0) {
+ ERROR("Can't create supervision's apiset: %m");
+ goto error;
+ }
+
+ /* start the services */
+ if (afb_apiset_start_all_services(main_apiset, 1) < 0)
+ goto error;
+
+ /* start the HTTP server */
+ if (main_config->httpdPort <= 0) {
+ ERROR("no port is defined");
+ goto error;
+ }
+
+ if (!afb_hreq_init_cookie(main_config->httpdPort, main_config->rootapi, main_config->cntxTimeout)) {
+ ERROR("initialisation of HTTP cookies failed");
+ goto error;
+ }
+
+ hsrv = start_http_server();
+ if (hsrv == NULL)
+ goto error;
+
+ /* ready */
+ sd_notify(1, "READY=1");
+ afs_supervisor_discover();
+ return;
+error:
+ exit(1);
+}
+
+/**
+ * initalize the supervision
+ */
+int main(int ac, char **av)
+{
+ /* scan arguments */
+ main_config = afs_config_parse_arguments(ac, av);
+ if (main_config->name) {
+ verbose_set_name(main_config->name, 0);
+ process_name_set_name(main_config->name);
+ process_name_replace_cmdline(av, main_config->name);
+ }
+ /* enter job processing */
+ jobs_start(3, 0, 10, start, av[1]);
+ WARNING("hoops returned from jobs_enter! [report bug]");
+ return 1;
+}
+
diff --git a/src/afs-supervision.h b/src/afs-supervision.h
index 6fc2023b..edfa6a1b 100644
--- a/src/afs-supervision.h
+++ b/src/afs-supervision.h
@@ -45,4 +45,5 @@ struct afs_supervision_initiator
char extra[27]; /**< zero terminated extra computed here to be 64-37 */
};
-#define AFS_SURPERVISION_APINAME_INTERNAL "$"
+#define AFS_SURPERVISION_APINAME "$"
+#define AFS_SURPERVISOR_APINAME "supervisor"
diff --git a/src/afs-supervisor.c b/src/afs-supervisor.c
index 1e92b9f3..71a00369 100644
--- a/src/afs-supervisor.c
+++ b/src/afs-supervisor.c
@@ -35,7 +35,6 @@
#include <json-c/json.h>
#include <afb/afb-binding-v2.h>
-#include "afs-supervision.h"
#include "afb-systemd.h"
#include "afb-session.h"
#include "afb-cred.h"
@@ -49,8 +48,11 @@
#include "jobs.h"
#include "verbose.h"
#include "wrap-json.h"
+#include "process-name.h"
-extern void afs_discover(const char *pattern, void (*callback)(void *closure, pid_t pid), void *closure);
+#include "afs-supervision.h"
+#include "afs-supervisor.h"
+#include "afs-discover.h"
/* supervised items */
struct supervised
@@ -66,11 +68,8 @@ struct supervised
};
/* api and apiset name */
-static const char supervision_apiname[] = AFS_SURPERVISION_APINAME_INTERNAL;
-static const char supervisor_apiname[] = "supervisor";
-
-/* the main apiset */
-struct afb_apiset *main_apiset;
+static const char supervision_apiname[] = AFS_SURPERVISION_APINAME;
+static const char supervisor_apiname[] = AFS_SURPERVISOR_APINAME;
/* the empty apiset */
static struct afb_apiset *empty_apiset;
@@ -86,7 +85,6 @@ static struct supervised *superviseds;
/*************************************************************************************/
-static int afb_init_supervision_api();
/*************************************************************************************/
@@ -291,110 +289,14 @@ static void discovered_cb(void *closure, pid_t pid)
}
}
-static int discover_supervised()
+int afs_supervisor_discover()
{
int n = 0;
afs_discover("afb-daemon", discovered_cb, &n);
return n;
}
-/**
- * initalize the supervision
- */
-static int init(const char *spec)
-{
- int rc, fd;
-
- /* check argument */
- if (!spec) {
- ERROR("invalid socket spec");
- return -1;
- }
-
- rc = afb_session_init(100, 600, "");
- /* TODO check that value */
-
- /* create the apisets */
- main_apiset = afb_apiset_create(supervisor_apiname, 0);
- if (!main_apiset) {
- ERROR("Can't create supervisor's apiset");
- return -1;
- }
- empty_apiset = afb_apiset_create(supervision_apiname, 0);
- if (!empty_apiset) {
- ERROR("Can't create supervision apiset");
- return -1;
- }
-
-
- /* init the main apiset */
- rc = afb_init_supervision_api();
- if (rc < 0) {
- ERROR("Can't create supervision's apiset: %m");
- return -1;
- }
-
- /* create the supervision socket */
- fd = create_supervision_socket(supervision_socket_path);
- if (fd < 0)
- return fd;
-
- /* listen the socket */
- rc = listen(fd, 5);
- if (rc < 0) {
- ERROR("refused to listen on socket");
- return rc;
- }
-
- /* integrate the socket to the loop */
- rc = sd_event_add_io(afb_systemd_get_event_loop(),
- NULL, fd, EPOLLIN,
- listening, NULL);
- if (rc < 0) {
- ERROR("handling socket event isn't possible");
- return rc;
- }
-
- /* adds the server socket */
- rc = afb_api_ws_add_server(spec, main_apiset);
- if (rc < 0) {
- ERROR("can't start the server socket");
- return -1;
- }
- return 0;
-}
-
-/* start should not be null but */
-static void start(int signum, void *arg)
-{
- char *xpath = arg;
- int rc;
-
- if (signum)
- exit(1);
-
- rc = init(xpath);
- if (rc)
- exit(1);
-
- sd_notify(1, "READY=1");
-
- discover_supervised();
-}
-
-/**
- * initalize the supervision
- */
-int main(int ac, char **av)
-{
- verbosity = Verbosity_Level_Debug;
- /* enter job processing */
- jobs_start(3, 0, 10, start, av[1]);
- WARNING("hoops returned from jobs_enter! [report bug]");
- return 1;
-}
-
-/*********************************************************************************************************/
+/*************************************************************************************/
static struct afb_binding_data_v2 datav2;
@@ -425,7 +327,7 @@ static void f_list(struct afb_req req)
static void f_discover(struct afb_req req)
{
- discover_supervised();
+ afs_supervisor_discover();
afb_req_success(req, NULL, NULL);
}
@@ -501,7 +403,49 @@ static void f_debug_break(struct afb_req req)
propagate(req, "break");
}
-static const struct afb_auth _afb_auths_v2_supervision[] = {
+/*************************************************************************************/
+
+/**
+ * initalize the supervisor
+ */
+static int init_supervisor()
+{
+ int rc, fd;
+
+ /* create an empty set for superviseds */
+ empty_apiset = afb_apiset_create(supervision_apiname, 0);
+ if (!empty_apiset) {
+ ERROR("Can't create supervision apiset");
+ return -1;
+ }
+
+ /* create the supervision socket */
+ fd = create_supervision_socket(supervision_socket_path);
+ if (fd < 0)
+ return fd;
+
+ /* listen the socket */
+ rc = listen(fd, 5);
+ if (rc < 0) {
+ ERROR("refused to listen on socket");
+ return rc;
+ }
+
+ /* integrate the socket to the loop */
+ rc = sd_event_add_io(afb_systemd_get_event_loop(),
+ NULL, fd, EPOLLIN,
+ listening, NULL);
+ if (rc < 0) {
+ ERROR("handling socket event isn't possible");
+ return rc;
+ }
+
+ return 0;
+}
+
+/*************************************************************************************/
+
+static const struct afb_auth _afb_auths_v2_supervisor[] = {
/* 0 */
{
.type = afb_auth_Permission,
@@ -509,93 +453,93 @@ static const struct afb_auth _afb_auths_v2_supervision[] = {
}
};
-static const struct afb_verb_v2 _afb_verbs_v2_supervision[] = {
+static const struct afb_verb_v2 _afb_verbs_v2_supervisor[] = {
{
.verb = "list",
.callback = f_list,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "config",
.callback = f_config,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "do",
.callback = f_do,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "trace",
.callback = f_trace,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "sessions",
.callback = f_sessions,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "session-close",
.callback = f_session_close,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "exit",
.callback = f_exit,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "debug-wait",
.callback = f_debug_wait,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "debug-break",
.callback = f_debug_break,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{
.verb = "discover",
.callback = f_discover,
- .auth = &_afb_auths_v2_supervision[0],
+ .auth = &_afb_auths_v2_supervisor[0],
.info = NULL,
.session = AFB_SESSION_NONE_V2
},
{ .verb = NULL }
};
-static const struct afb_binding_v2 _afb_binding_v2_supervision = {
+static const struct afb_binding_v2 _afb_binding_v2_supervisor = {
.api = supervisor_apiname,
.specification = NULL,
.info = NULL,
- .verbs = _afb_verbs_v2_supervision,
+ .verbs = _afb_verbs_v2_supervisor,
.preinit = NULL,
- .init = NULL,
+ .init = init_supervisor,
.onevent = NULL,
.noconcurrency = 0
};
-static int afb_init_supervision_api()
+int afs_supervisor_add(struct afb_apiset *apiset)
{
- return afb_api_so_v2_add_binding(&_afb_binding_v2_supervision, NULL, main_apiset, &datav2);
+ return afb_api_so_v2_add_binding(&_afb_binding_v2_supervisor, NULL, apiset, &datav2);
}
diff --git a/src/afs-supervisor.h b/src/afs-supervisor.h
new file mode 100644
index 00000000..aeae6c72
--- /dev/null
+++ b/src/afs-supervisor.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+
+extern int afs_supervisor_discover();
+extern int afs_supervisor_add(struct afb_apiset *apiset);
+