libamxrt
0.4.2
Ambiorix Run Time Library
|
Using this library it will be easy to create an ambiorix application with an eventloop.
This library provides the full implementation of the Ambiorix Run Time and is used by the amxrt application.
This library provides:
All the necessary details are available in the Doxygen-based documentation for the latest release, which is a static website served via GitLab Pages using automated CI job.
You could install all tools needed for testing and developing on your local machine, but it is easier to just use a pre-configured environment. Such an environment is already prepared for you as a docker container.
Install docker
Docker must be installed on your system.
If you have no clue how to do this here are some links that could help you:
Make sure you user id is added to the docker group:
``` sudo usermod -aG docker $USER ```
Fetch the container image
To get access to the pre-configured environment, all you need to do is pull the image and launch a container.
Pull the image:
```bash docker pull registry.gitlab.com/soft.at.home/docker/oss-dbg:latest ```
Before launching the container, you should create a directory which will be shared between your local machine and the container.
```bash mkdir -p ~/amx_project/libraries/ ```
Launch the container:
```bash docker run -ti -d –name oss-dbg –restart always –cap-add=SYS_PTRACE –sysctl net.ipv6.conf.all.disable_ipv6=1 -e "USER=$USER" -e "UID=$(id -u)" -e "GID=$(id -g)" -v ~/amx_project/:/home/$USER/amx_project/ registry.gitlab.com/soft.at.home/docker/oss-dbg:latest ```
If you are using vpn, you need to add --dns 192.168.16.10 --dns 192.168.16.11
to the docker run command.
The -v
option bind mounts the local directory for the ambiorix project in the container, at the exact same place. The -e
options create environment variables in the container. These variables are used to create a user name with exactly the same user id and group id in the container as on your local host (user mapping).
You can open as many terminals/consoles as you like:
```bash docker exec -ti –user $USER oss-dbg /bin/bash ```
Dependency graph - libraries needed by libamxrt. For graph simplicity direct dependencies which are also an indirect dependency are not shown.
graph TD; libamxrt-->libamxo libamxrt-->libamxj libamxrt-->libevent libamxrt-->libcap-ng
libamxp-->libamxc libamxd-->libamxp libamxo-->libamxs libamxs-->libamxb libamxb-->libamxd libamxj-->libamxc
Clone the git repository
To be able to build it, you need the source code. So open the directory just created for the ambiorix project and clone this library in it (on your local machine).
```bash cd ~/amx_project/libraries/ git clone git@g:prpl-foundation/components/ambiorix/libraries/libamxrt.git ``` itla b.com
Install dependencies
Although the container will contain all tools needed for building, it does not contain the libraries needed for building libamxrt
. To be able to build libamxrt
you need libamxc
. This library can be installed in the container.
```bash sudo apt update sudo apt install libamxc libamxj libamxp libamxd libamxb libamxs libamxo libevent libcap-ng-dev ```
Note that some of the components are allready preinstalled in the container.
Build it
When using the internal gitlab, you must define an environment variable VERSION_PREFIX
before building.
```bash export VERSION_PREFIX="master_" ```
After the variable is set, you can build the package.
```bash cd ~/amx_project/libraries/libamxrt make ```
You can install your own compiled version easily in the container by running the install target.
From within the container you can create packages.
The packages generated are:
You can copy these packages and extract/install them.
For ubuntu or debian distributions use dpkg:
No extra components are needed for testing libamxrt
.
You can run the tests by executing the following command.
Or this command if you also want the coverage tests to run:
The coverage target will generate coverage reports using gcov and gcovr.
A summary for each file (*.c files) is printed in your console after the tests are run. A HTML version of the coverage reports is also generated. These reports are available in the output directory of the compiler used. Example: using native gcc When the output of gcc -dumpmachine
is x86_64-linux-gnu
, the HTML coverage reports can be found at ~/amx_project/libraries/libamxrt/output/x86_64-linux-gnu/coverage/report.
You can easily access the reports in your browser. In the container start a python3 http server in background.
Use the following url to access the reports http://<IP ADDRESS OF YOUR CONTAINER>:8080/libraries/libamxrt/output/<MACHINE>/coverage/report
You can find the ip address of your container by using the ip
command in the container.
Example:
in this case the ip address of the container is 172.17.0.7
. So the uri you should use is: http://172.17.0.7:8080/libraries/libamxrt/output/x86_64-linux-gnu/coverage/report/
The amxrt
library already provides defaults for most configuration options. All these run-time configuration options can be changed using the config
section in the ODL files and most of them can be set using the commandline arguments.
The defaults configuration options provided by libamxrt
can be dumped to stdout using amxrt -d
, all options are printed in alhabetical order:
uris
. If one of the connections fail, an error is printed to stderr. At least one connection must be available.uris
list and will be connected to when auto-connect
is set to true.auto-detect
is set to true, this directory or directores will be scanned and all valid back-end implementations found are added to the option backend
.auto-detect
option and backend-dir
option are set this list is filled automatically.app:start
event is triggered. Default is false.-d
. When an error occurs during start-up this option is set and the current
configuration is dumped to stdout. extensions-dir: (string) Directory where data model extensions can be stored in odl format. These extension odls will be loaded in alphabetical order after all other (definition) odl are loaded but before the entry-points are called or post-includes are loaded.import
is encountered in the ODL file. Extra directories can be added using commandline option -L
.include
keyword is encountered in the ODL files and it does not contain an absolute path, the include file is searched in these include directories, in the order specified. Extra include directories can be added to the list with the commandline option -I
amxrt
will open the system log (syslog) and can write messages to it.amxrt
the name of the symbolic link is used as the name
option.name
configuration option).-o
) all paths are prefixed with this string. This option is mainly used for debugging reasons.odl
format to store persistent data. If another format is needed, a module (plug-in) is needed that can support the needed format.-R
or --requires
extra objects can be added to the list. When the list is not empty, the Ambiorix run-time will wait until all objects in the list are available before calling the entry points and triggering the event app:start
.When in odl files configuration options are specified (in config
section) the values specified in the odl file are taken. Using the -F
or --forced-option
, you can force a specific value for a configuration option from command line. The forced options
can not be overwritten by odl files.
NOTE
In odl files theconfig
sections are scoped and are only valid in the odl file where they are defined, and in all odl files that are included in that file after theconfig
section. If the file where theconfig
section is defined is included by another odl file (the parent odl file), the parent will not see these values for the config options, unless the config options was declared withglobal
—
Using the command line option -R
or --requires
object paths can be added to the list of required objects. These objects are mostly provided by other processes and it is possible that these objects are not yet available. Ambiorix run-time will wait until all objects in the required
list are available before calling any entry-point and triggering the event app:start
. The data model of your application will not be registered to the bus systems until all required
objects are available.
When the command line option -D
or configuration option daemon
is set, the run-time will daemonize itself even if not all required objects are available.
When all required objects are available, the requires
array is reset to an empty array.
The Ambiorix run-time can store persistent data in ODL
format save files.
By default no persistent data is saved. To enable this on configuration a table must be added to the configuration section of your main ODL file.
The ODL
storage format is only active when the storage-type
configuration option is set to odl
.
All ODL persistent storage options must be set in the odl
and can be divided in 3 logical parts:
>NOTE
>When using include
in the ODL
files to load the previously saved files, these settings should not be used. >
odl.directory
are loaded.ODL
files are found or exist, the defaults will be loaded defined by this configuration option.amxrt
will save the persistent data at exit.amxrt
will save the persistent data when the data has been changed.Using above example the Ambiorix run-time (amxrt
) will save all persistent
objects and parameters (they must have the persistent
attribute) to a file with the name ${name}.odl
in the directory specified with odl.directory
option. The save will be done when the application exits and only when odl.dm-save
is set to true.
When odl.dm-save-on-changed is set, changes are saved immediatly after the datamodel did not receive changes in odl.dm-save-delay time to the file and not only when the applications exits.
When persistent data changes and not other changes occur for at least odl.dm-save-delay
the persistent data is saved.
libamxrt is capable to drop user privileges and capabilities.
By default all capabilities are dropped unless otherwise configured. The user and group will be retained unless otherwise configured.
NOTE Initially the process amxrt (and libamxrt) didn't drop any capabilites or was not able to drop user privileges. This behavior is not good in respect to security. This behavior is kept until 01/09/2023, from then by default all capabilities will be dropped. This will provide time to update the configuration of services and applications that are using libamxrt (or the amxrt process).
—
The user and group to which the process must switch after initializing can be configured with:
The set of capabilities that must be kept can be specified in a list:
The list must contain the names of the capabilities that needs to be kept or the identifier of that capability. The name of the capabilities must match the definitions in linux/capabiliy.h
with or without the CAP_
prefix. The string case is ignored (lower and upper case is allowed).
When only user/group switching is needed but all capabilities must be kept set:
Example:
This example config will switch to user webui
and group webui
and drops all capabilities except CAP_CHOWN
(chown
)
More information about capabilities can be found at manpage Capabilities
NOTE
Capabilities can only be dropped and not added.
—
By calling the function amxrt
an ambiorix runtime is created. It will parse the command line arguments using the default ambiorix command line arguments:
After parsing the command line arguments, it will load the ambiorix backends, looks for well known unix domain sockets (ubus, pcb, ....) and connectes to them.
Loads the odl files, that are provided after the command line options, or loads the odl file that matches the application's name (by default /etc/amx/<appname>/<appname>.odl
).
Creates and starts the event-loop.
The above code will follow this initialization flow:
flowchart LR subgraph part1[Config Initialization] ci1[read environment vars]-->ci2[set default dirs]-->ci3[parse command line arguments]-->ci4[load odl files] ci4-->ci5{auto detect?} ci5 -- yes --> ci6[scan backend dirs] ci6 --> ci7 ci5 -- no --> ci7[load backends] end subgraph part2[Connection Initialization] ci8{auto detect?} ci8 -- yes --> ci9[fetch known uris] ci8 -- no --> ci10{auto connect?} ci9 --> ci10 ci10 -- yes --> ci11[connect] --> ci12[create listen sockets] ci10 -- no --> ci13[apply process settings] ci12 --> ci13[apply process settings] ci13 --> ci14[create eventloop] end subgraph part3[Register Or Wait] rw1{Has required\nobjects?} rw1 -- yes --> rw2(start eventloop) rw1 -- no --> rw5 rw2 --> rw3(wait for objects
...) rw3 ---> rw4{all required\nobjects available?} rw4 -- no --> rw3 rw4 -- yes --> rw5[register datamodel] end subgraph part4[Start plug-in] sp1[invoke entry points] --> sp2[start synchronization contexts] sp2 --> sp3[send app:start event] sp3 --> sp4(start eventloop\nif not started yet) end part1 --> part2 --> part3 --> part4
Optionally extra command line arguments (options) and an option handler function can be added.
Alternativly you could just use the amxrt app, which implements exactly the above.
Still easy to use, but with the possibility to do other actions in between.
The example below will create a data model provider application. This implementation provides the default implementation of the amxrt
function.
If you need to create a data model client application (that is an application that doesn't provide a data model), you can remove the following calls:
amxrt_load_odl_files
amxrt_register_or_wait
In this case this library can not help you. Look at the other ambiorix libraries and use the functions you need.