d0c52e37cb17308f7ff33435f88bba4341027c0c
[src/app-framework-binder.git] / src / main-afs-supervisor.c
1 /*
2  * Copyright (C) 2016-2019 "IoT.bzh"
3  * Author José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #define _GNU_SOURCE
19
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25
26 #include <systemd/sd-daemon.h>
27
28 #include "afb-common.h"
29 #include "afb-hsrv.h"
30 #include "afb-hswitch.h"
31 #include "afb-hreq.h"
32 #include "afb-apiset.h"
33 #include "afb-api-ws.h"
34 #include "afb-session.h"
35
36 #include "afs-supervisor.h"
37 #include "afs-args.h"
38
39 #include "verbose.h"
40 #include "jobs.h"
41 #include "process-name.h"
42 #include "watchdog.h"
43
44 #if !defined(DEFAULT_SUPERVISOR_INTERFACE)
45 #  define DEFAULT_SUPERVISOR_INTERFACE NULL
46 #endif
47
48 /* the main config */
49 struct afs_args *main_config;
50
51 /* the main apiset */
52 struct afb_apiset *main_apiset;
53
54 /*************************************************************************************/
55
56 static int init_http_server(struct afb_hsrv *hsrv)
57 {
58         if (!afb_hsrv_add_handler
59             (hsrv, main_config->rootapi, afb_hswitch_websocket_switch, main_apiset, 20))
60                 return 0;
61
62         if (!afb_hsrv_add_handler
63             (hsrv, main_config->rootapi, afb_hswitch_apis, main_apiset, 10))
64                 return 0;
65
66         if (main_config->roothttp != NULL) {
67                 if (!afb_hsrv_add_alias
68                     (hsrv, "", afb_common_rootdir_get_fd(), main_config->roothttp,
69                      -10, 1))
70                         return 0;
71         }
72
73         if (!afb_hsrv_add_handler
74             (hsrv, main_config->rootbase, afb_hswitch_one_page_api_redirect, NULL,
75              -20))
76                 return 0;
77
78         return 1;
79 }
80
81 static struct afb_hsrv *start_http_server()
82 {
83         int rc;
84         struct afb_hsrv *hsrv;
85
86         if (afb_hreq_init_download_path(main_config->uploaddir)) {
87                 ERROR("unable to set the upload directory %s", main_config->uploaddir);
88                 return NULL;
89         }
90
91         hsrv = afb_hsrv_create();
92         if (hsrv == NULL) {
93                 ERROR("memory allocation failure");
94                 return NULL;
95         }
96
97         if (!afb_hsrv_set_cache_timeout(hsrv, main_config->cacheTimeout)
98             || !init_http_server(hsrv)) {
99                 ERROR("initialisation of httpd failed");
100                 afb_hsrv_put(hsrv);
101                 return NULL;
102         }
103
104         NOTICE("Waiting port=%d rootdir=%s", main_config->httpdPort, main_config->rootdir);
105         NOTICE("Browser URL= http://localhost:%d", main_config->httpdPort);
106
107         rc = afb_hsrv_start(hsrv, 15);
108         if (!rc) {
109                 ERROR("starting of httpd failed");
110                 afb_hsrv_put(hsrv);
111                 return NULL;
112         }
113
114         rc = afb_hsrv_add_interface_tcp(hsrv, DEFAULT_SUPERVISOR_INTERFACE, (uint16_t) main_config->httpdPort);
115         if (!rc) {
116                 ERROR("setting interface failed");
117                 afb_hsrv_put(hsrv);
118                 return NULL;
119         }
120
121         return hsrv;
122 }
123
124 static void start(int signum, void *arg)
125 {
126         struct afb_hsrv *hsrv;
127         int rc;
128
129         /* check illness */
130         if (signum) {
131                 ERROR("start aborted: received signal %s", strsignal(signum));
132                 exit(1);
133         }
134
135         /* set the directories */
136         mkdir(main_config->workdir, S_IRWXU | S_IRGRP | S_IXGRP);
137         if (chdir(main_config->workdir) < 0) {
138                 ERROR("Can't enter working dir %s", main_config->workdir);
139                 goto error;
140         }
141         if (afb_common_rootdir_set(main_config->rootdir) < 0) {
142                 ERROR("failed to set common root directory");
143                 goto error;
144         }
145
146         /* configure the daemon */
147         if (afb_session_init(main_config->nbSessionMax, main_config->cntxTimeout)) {
148                 ERROR("initialisation of session manager failed");
149                 goto error;
150         }
151
152         main_apiset = afb_apiset_create("main", main_config->apiTimeout);
153         if (!main_apiset) {
154                 ERROR("can't create main apiset");
155                 goto error;
156         }
157
158         /* init the main apiset */
159         rc = afs_supervisor_add(main_apiset, main_apiset);
160         if (rc < 0) {
161                 ERROR("Can't create supervision's apiset: %m");
162                 goto error;
163         }
164
165         /* export the service if required */
166         if (main_config->ws_server) {
167                 rc = afb_api_ws_add_server(main_config->ws_server, main_apiset, main_apiset);
168                 if (rc < 0) {
169                         ERROR("Can't export (ws-server) api %s: %m", main_config->ws_server);
170                         goto error;
171                 }
172         }
173
174         /* start the services */
175         if (afb_apiset_start_all_services(main_apiset) < 0)
176                 goto error;
177
178         /* start the HTTP server */
179         if (main_config->httpdPort <= 0) {
180                 ERROR("no port is defined");
181                 goto error;
182         }
183
184         if (!afb_hreq_init_cookie(main_config->httpdPort, main_config->rootapi, main_config->cntxTimeout)) {
185                 ERROR("initialisation of HTTP cookies failed");
186                 goto error;
187         }
188
189         hsrv = start_http_server();
190         if (hsrv == NULL)
191                 goto error;
192
193         /* ready */
194         sd_notify(1, "READY=1");
195
196         /* activate the watchdog */
197 #if HAS_WATCHDOG
198         if (watchdog_activate() < 0)
199                 ERROR("can't start the watchdog");
200 #endif
201
202         /* discover binders */
203         afs_supervisor_discover();
204         return;
205 error:
206         exit(1);
207 }
208
209 /**
210  * initialize the supervision
211  */
212 int main(int ac, char **av)
213 {
214         /* scan arguments */
215         main_config = afs_args_parse(ac, av);
216         if (main_config->name) {
217                 verbose_set_name(main_config->name, 0);
218                 process_name_set_name(main_config->name);
219                 process_name_replace_cmdline(av, main_config->name);
220         }
221         /* enter job processing */
222         jobs_start(3, 0, 10, start, av[1]);
223         WARNING("hoops returned from jobs_enter! [report bug]");
224         return 1;
225 }
226