11781d5fbd17fe955af2d5cae380b16b05c1a03c
[src/app-framework-main.git] / docs / 1-afm-daemons.md
1 # The application framework daemons
2
3 ## Foreword
4
5 This document describes application framework daemons
6 FCS (Fully Conform to Specification) implementation is still under development.  
7 It may happen that current implementation somehow diverges with specifications.
8
9 ## Introduction
10
11 Daemons ***afm-user-daemon*** and ***afm-system-daemon*** handle applications
12 life.  
13 Understand that they will manage operations like:
14
15 - ***installation***
16 - ***uninstallation***
17 - ***running***
18 - ***suspend***
19 - ***inventory***
20 - ...
21
22 In addition, they ensure that operations use the security framework as needed
23 and that applications are executed in the correct context.
24
25 ***D-Bus*** is in charge of transmitting orders to the appropriate daemon
26 depending upon ***D-Bus*** destination.
27
28 The figure below summarizes the situation of both **afm-system-daemon** and
29 **afm-user-daemon** in the system.
30
31 ![afm-daemons][afm-daemons]{style width:65%;}
32
33 ## The D-Bus interface
34
35 ### Overview of the dbus interface
36
37 The ***afm daemons*** takes theirs orders from the session instance
38 of D-Bus.  
39 The use of D-Bus is great because it allows to implement
40 discovery and signaling.
41
42 The dbus session is by default addressed by environment
43 variable *DBUS_SESSION_BUS_ADDRESS*. Using **systemd**
44 variable *DBUS_SESSION_BUS_ADDRESS* is automatically set for
45 user sessions.
46
47 They are listening with the destination name ***org.AGL.afm.[user|system]***
48 at the object of path ***/org/AGL/afm/[user|system]*** on the interface
49 ***org.AGL.afm.[user|system]***  for the below detailed members for the
50 ***afm-system-daemon***:
51
52 - ***install***
53 - ***uninstall***
54
55 And for ***afm-user-daemon***:
56
57 - ***runnables***
58 - ***detail***
59 - ***start***
60 - ***once***
61 - ***terminate***
62 - ***pause***
63 - ***resume***
64 - ***runners***
65 - ***state***
66 - ***install***
67 - ***uninstall***
68
69 D-Bus is mainly used for signaling and discovery.  
70 Its optimized typed protocol is not used except for transmitting
71  only one string in both directions.
72
73 The client and the service are using JSON serialization to
74 exchange data.  
75 Signature of any member of the D-Bus interface is
76 ***string -> string*** for ***JSON -> JSON***.  
77 This is the normal case, if there is an error, current implementation 
78 returns a dbus error that is a string.
79
80 Here are examples using *dbus-send*, here to install an application from a
81 widget file:
82
83 ```bash
84 dbus-send --session --print-reply \
85     --dest=org.AGL.afm.system \
86     /org/AGL/afm/system \
87     org.AGL.afm.system.install 'string:"/tmp/appli.wgt"
88 ```
89
90 And here, to query data on installed applications that can be run:
91
92 ```bash
93 dbus-send --session --print-reply \
94     --dest=org.AGL.afm.user \
95     /org/AGL/afm/user \
96     org.AGL.afm.user.runnables string:true
97 ```
98
99 ### The protocol over D-Bus
100
101 On all following sub-chapters we assume that we talk about either
102 ***afm-system-daemon*** or ***afm-user-daemon***. Method and D-Bus parameters
103 are considered as self-explanatory.
104
105 The D-Bus interface is defined by:
106
107 - **DESTINATION**: org.AGL.afm.[user|system]
108 - **PATH**: /org/AGL/afm/[user|system]
109 - **INTERFACE**: org.AGL.afm.[user|system]
110
111 #### Method org.AGL.afm.system.install
112
113 **Description**: Install an application from a widget file.
114
115 When an application with the same *id* and *version* already exists. Outside of
116 using *force=true* the application is not reinstalled.
117
118 Applications are installed the subdirectories of applications common directory.
119 If *root* is specified, the application is installed under the
120 sub-directories of the *root* defined.
121
122 Note that this methods is a simple accessor method of
123 ***org.AGL.afm.system.install*** from ***afm-system-daemon***.
124
125 After the installation and before returning to the sender,
126 ***afm-system-daemon*** sends a signal ***org.AGL.afm.system.changed***.
127
128 **Input**: The *path* of the widget file to install and, optionally,
129 a flag to *force* reinstallation, and, optionally, a *root* directory.
130
131 Either just a string being the absolute path of the widget file:
132
133 ```bash
134 "/a/path/driving/to/the/widget"
135 ```
136
137 Or an object:
138
139 ```json
140 {
141   "wgt": "/a/path/to/the/widget",
142   "force": false,
143   "root": "/a/path/to/the/root"
144 }
145 ```
146
147 "wgt" and "root" must be absolute paths.
148
149 **output**: An object with the field "added" being the string for
150 the id of the added application.
151
152 ```json
153 {"added":"appli@x.y"}
154 ```
155
156 ---
157
158 #### Method org.AGL.afm.system.uninstall
159
160 **Description**: Uninstall an application from its id.
161
162 Note that this methods is a simple method accessor of
163 ***org.AGL.afm.system.uninstall*** from ***afm-system-daemon***.
164
165 After the uninstallation and before returning to the sender,
166 ***afm-system-daemon*** sends a signal ***org.AGL.afm.system.changed***.
167
168 **Input**: the *id* of the application and optionally the application *root* path.
169
170 Either a string:
171
172 ```bash
173 "appli@x.y"
174 ```
175
176 Or an object:
177
178 ```json
179 {
180   "id": "appli@x.y",
181   "root": "/a/path/to/the/root"
182 }
183 ```
184
185 **output**: the value 'true'.
186
187 ---
188
189 #### Method org.AGL.afm.user.detail
190
191 **Description**: Get details about an application from its id.
192
193 **Input**: the id of the application as below.
194
195 Either just a string:
196
197 ```bash
198 "appli@x.y"
199 ```
200
201 Or an object having the field "id" of type string:
202
203 ```json
204 {"id":"appli@x.y"}
205 ```
206
207 **Output**: A JSON object describing the application containing
208 the fields described below.
209
210 ```json
211 {
212   "id":          string, the application id (id@version)
213   "version":     string, the version of the application
214   "width":       integer, requested width of the application
215   "height":      integer, requested height of the application
216   "name":        string, the name of the application
217   "description": string, the description of the application
218   "shortname":   string, the short name of the application
219   "author":      string, the author of the application
220 }
221 ```
222
223 ---
224
225 #### Method org.AGL.afm.user.runnables
226
227 **Description**: Get the list of applications that can be run.
228
229 **Input**: any valid json entry, can be anything except null.
230
231 **output**: An array of description of the runnable applications.
232 Each item of the array contains an object containing the detail of
233 an application as described above for the method
234 *org.AGL.afm.user.detail*.
235
236 ---
237
238 #### Method org.AGL.afm.user.install
239
240 **Description**: Install an application from its widget file.
241
242 If an application of the same *id* and *version* exists, it is not
243 reinstalled except when *force=true*.
244
245 Applications are installed in the subdirectories of the common directory
246 reserved for applications.
247 If *root* is specified, the application is installed under
248 sub-directories of defined *root*.
249
250 Note that this methods is a simple accessor to the method
251 ***org.AGL.afm.system.install*** of ***afm-system-daemon***.
252
253 After the installation and before returning to the sender,
254 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
255
256 **Input**: The *path* of widget file to be installed. Optionally,
257 a flag to *force* reinstallation and/or a *root* directory.
258
259 Simple form a simple string containing the absolute widget path:
260
261 ```bash
262 "/a/path/driving/to/the/widget"
263 ```
264
265 Or an object:
266
267 ```json
268 {
269   "wgt": "/a/path/to/the/widget",
270   "force": false,
271   "root": "/a/path/to/the/root"
272 }
273 ```
274
275 ***wgt*** and ***root*** MUST be absolute paths.
276
277 **output**: An object containing field "added" to use as application ID.
278
279 ```json
280 {"added":"appli@x.y"}
281 ```
282
283 ---
284
285 #### Method org.AGL.afm.user.uninstall
286
287 **Description**: Uninstall an application from its id.
288
289 Note that this methods is a simple accessor to
290 ***org.AGL.afm.system.uninstall*** method from ***afm-system-daemon***.
291
292 After the uninstallation and before returning to the sender,
293 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
294
295 **Input**: the *id* of the application and, optionally, the path to
296 application *root*.
297
298 Either a string:
299
300 ```bash
301 "appli@x.y"
302 ```
303
304 Or an object:
305
306 ```json
307 {
308   "id": "appli@x.y",
309   "root": "/a/path/to/the/root"
310 }
311 ```
312
313 **output**: the value 'true'.
314
315 ---
316
317 #### Method org.AGL.afm.user.start
318
319 **Description**:
320
321 **Input**: the *id* of the application and, optionally, the
322 start *mode* as below.
323
324 Either just a string:
325
326 ```bash
327 "appli@x.y"
328 ```
329
330 Or an object containing field "id" of type string and
331 optionally a field mode:
332
333 ```json
334 {"id":"appli@x.y","mode":"local"}
335 ```
336
337 The field "mode" is a string equal to either "local" or "remote".
338
339 [Currently the mode is not available in the systemd version]
340
341 **output**: The *runid* of the application launched. *runid* is an integer.
342
343 ---
344
345 #### Method org.AGL.afm.user.once
346
347 **Description**:
348
349 **Input**: the *id* of the application
350
351 Either just a string:
352
353 ```bash
354 "appli@x.y"
355 ```
356
357 Or an object containing field "id" of type string.
358
359 ```json
360 {"id":"appli@x.y"}
361 ```
362
363 **output**: The *state* of the application retrieved or launched.
364 See *org.AGL.afm.user.state* to get a description of the returned
365 object.
366
367 ---
368
369 #### Method org.AGL.afm.user.terminate
370
371 **Description**: Terminates the application attached to *runid*.
372
373 **Input**: The *runid* (an integer) of running instance to terminate.
374
375 **output**: the value 'true'.
376
377 ---
378
379 #### Method org.AGL.afm.user.stop
380
381 Obsolete since 8th November 2016 (2016/11/08).
382 Kept for compatibility.
383
384 Use **org.AGL.afm.user.pause** instead.
385
386 ---
387
388 #### Method org.AGL.afm.user.continue
389
390 Obsolete since 8th November 2016 (2016/11/08).
391 Kept for compatibility.
392
393 Use **org.AGL.afm.user.resume** instead.
394
395 ---
396
397 #### Method org.AGL.afm.user.pause
398
399 [Currently not available in the systemd version]
400
401 **Description**: Pauses the application attached to *runid* until terminate or resume.
402
403 **Input**: The *runid* (integer) of the running instance to pause.
404
405 **output**: the value 'true'.
406
407 ---
408
409 #### Method org.AGL.afm.user.resume
410
411 [Currently not available in the systemd version]
412
413 **Description**: Resumes the application attached to *runid* previously paused.
414
415 **Input**: The *runid* (integer) of the running instance to resume.
416
417 **output**: the value 'true'.
418
419 ---
420
421 #### Method org.AGL.afm.user.state
422
423 **Description**: Get information about a running instance of *runid*.
424
425 **Input**: The *runid* (integer) of the running instance inspected.
426
427 **output**: An object describing instance state.  
428 It contains:
429
430 - the runid (integer)
431 - the pids of the processes as an array starting
432 - with the group leader
433 - the id of the running application (string)
434 - the state of the application (string either: "starting", "running", "paused").
435
436 Example of returned state:
437
438 ```json
439     {
440       "runid": 2,
441       "pids": [ 435, 436 ],
442       "state": "running",
443       "id": "appli@x.y"
444     }
445 ```
446
447 ---
448
449 #### Method org.AGL.afm.user.runners
450
451 **Description**: Get the list of currently running instances.
452
453 **Input**: anything.
454
455 **output**: An array of states, one per running instance, as returned by
456 the method ***org.AGL.afm.user.state***.
457
458 ## Starting **afm daemons**
459
460 ***afm-system-daemon*** and ***afm-user-daemon*** are launched as systemd
461 services attached to system and user respectively.  
462 Normally, service files are locatedat */lib/systemd/system/afm-system-daemon.service* and
463 */usr/lib/systemd/user/afm-user-daemon.service*.
464
465 ### ***afm-system-daemon*** options
466
467 The options for launching **afm-system-daemon** are:
468
469 ```bash
470     -r
471     --root directory
472
473          Set the root application directory.
474
475          Note that the default root directory is defined
476          to be /usr/share/afm/applications (may change).
477
478     -d
479     --daemon
480
481          Daemonizes the process. It is not needed by systemd.
482
483     -q
484     --quiet
485
486          Reduces the verbosity (can be repeated).
487
488     -v
489     --verbose
490
491          Increases the verbosity (can be repeated).
492
493     -h
494     --help
495
496          Prints a short help.
497 ```
498
499 ### ***afm-user-daemon*** options
500
501 The options for launching **afm-user-daemon** are:
502
503 ```bash
504     -a
505     --application directory
506
507          [Currently not available in the systemd version]
508
509          Includes the given application directory to
510          the database base of applications.
511
512          Can be repeated.
513
514     -r
515     --root directory
516
517          [Currently not available in the systemd version]
518
519          Includes root application directory or directories when
520          passing multiple rootdir to
521          applications database.
522
523          Note that default root directory for
524          applications is always added. In current version
525          /usr/share/afm/applications is used as default.
526
527     -m
528     --mode (local|remote)
529
530          [Currently not available in the systemd version]
531
532          Set the default launch mode.
533          The default value is 'local'
534
535     -d
536     --daemon
537
538          Daemonizes the process. It is not needed by systemd.
539
540     -q
541     --quiet
542
543          Reduces the verbosity (can be repeated).
544
545     -v
546     --verbose
547
548          Increases the verbosity (can be repeated).
549
550     -h
551     --help
552
553          Prints a short help.
554 ```
555
556 ## Tasks of **afm-user-daemon**
557
558 ### Maintaining list of applications
559
560 At start **afm-user-daemon** scans the directories containing
561 applications and load in memory a list of available applications
562 accessible by current user.
563
564 When **afm-system-daemon** installs or removes an application.
565 On success it sends the signal *org.AGL.afm.system.changed*.  
566 When receiving such a signal, **afm-user-daemon** rebuilds its
567 applications list.
568
569 **afm-user-daemon** provides the data it collects about
570 applications to its clients.  
571 Clients may either request the full list
572 of available applications or a more specific information about a
573 given application.
574
575 ### Launching application
576
577 **afm-user-daemon** launches application by using systemd.
578 Systemd builds a secure environment for the application
579 before starting it.
580
581 Once launched, running instances of application receive
582 a runid that identify them.  
583 To make interface with systemd evident, the pid is the runid.
584
585 ### Managing instances of running applications
586
587 **afm-user-daemon** manages the list of applications
588 that it launched.
589
590 When owning the right permissions, a client can get the list
591 of running instances and details about a specific
592 running instance.  
593 It can also terminate a given application.
594
595 ### Installing and uninstalling applications
596
597 If the client own the right permissions,
598 **afm-user-daemon** delegates that task
599 to **afm-system-daemon**.
600
601 ## Using ***afm-util***
602
603 The command line tool ***afm-util*** uses dbus-send to send
604 orders to **afm-user-daemon**.  
605 This small scripts allows to send command to ***afm-user-daemon*** either
606 interactively at shell prompt or scriptically.
607
608 The syntax is simple:
609
610 - it accept a command and when requires attached arguments.
611
612 Here is the summary of ***afm-util***:
613
614 - **afm-util runnables      **:  
615   list the runnable widgets installed
616
617 - **afm-util install    wgt **:  
618   install the wgt file
619
620 - **afm-util uninstall  id  **:  
621   remove the installed widget of id
622
623 - **afm-util detail     id  **:  
624   print detail about the installed widget of id
625
626 - **afm-util runners        **:  
627   list the running instance
628
629 - **afm-util start      id  **:  
630   start an instance of the widget of id
631
632 - **afm-util once      id  **:  
633   run once an instance of the widget of id
634
635 - **afm-util terminate  rid **:  
636   terminate the running instance rid
637
638 - **afm-util state      rid **:  
639   get status of the running instance rid
640
641 Here is how to list applications using ***afm-util***:
642
643 ```bash
644     afm-util runnables
645 ```
646
647 [afm-daemons]: pictures/afm-daemons.svg