| Both sides previous revision Previous revision Next revision | Previous revision |
| docs:techref:rpcd [2018/10/28 11:21] – [rpcd: OpenWrt ubus RPC daemon for backend server] stokito | docs:techref:rpcd [2023/10/14 06:08] (current) – update vgaetera |
|---|
| ====== rpcd: OpenWrt ubus RPC daemon for backend server ====== | ====== rpcd: OpenWrt ubus RPC daemon for backend server ====== |
| |
| In OpenWrt we commonly use [[docs:techref:ubus|ubus]] for all kinds of communication. It can provide info from various software as well as request various actions. Nevertheless, not every part of OpenWrt has a daemon that can register itself using ''ubus''. For an example ''uci'' and ''opkg'' are command-line tools without any background process running all the time. | In OpenWrt we commonly use [[docs:techref:ubus|ubus]] for all kinds of communication. It can provide info from various software as well as request various actions. Nevertheless, not every part of OpenWrt has a daemon that can register itself using ''ubus''. For an example ''uci'' and ''opkg'' are command-line tools without any background process running all the time. |
| |
| It would be not efficient to write a daemon for every software like this and run them independently. This is why ''rpcd'' was developed. It’s a tiny daemon with support for plugins using trivial API. It loads library ''%%.so%%'' files and calls init function of each of them. | It would be not efficient to write a daemon for every software like this and run them independently. This is why ''rpcd'' was developed. It’s a tiny daemon with support for plugins using trivial API. It loads library ''%%.so%%'' files and calls init function of each of them. |
| |
| |
| The code is published under [[wp>ISC_license|ISC license]] and can be found via git at [[https://git.openwrt.org/project/rpcd.git]]. | The code is published under [[wp>ISC_license|ISC license]] and can be found via git at [[https://git.openwrt.org/project/rpcd.git]]. |
| |
| ==== Default plugins ==== | ==== Default plugins ==== |
| | There are few small plugins distributed with the ''rpcd'' sources. Two of them (''session'' and ''uci'') are built-in, others are optional and have to be build as separated ''%%.so%%'' libraries. Apart from that there are other projects providing their own plugins. |
| |
| There are few small plugins distributed with the ''rpcd'' sources. Two of them (''session'' and ''uci'') are built-in, others are optional and have to be build as separated ''%%.so%%'' libraries. Apart from that there are other projects providing their own plugins. | |
| ===== plugin executables ===== | ===== plugin executables ===== |
| | It is possible to expose shell script functionality over ubus by using ''rpcd'' plugin executables functionality. Executables stored in ''/usr/libexec/rpcd/'' directory will be run by ''rpcd''. Lets look at the following example: |
| |
| It is possible to expose shell script functionality over ubus by using ''rpcd'' plugin executables functionality. Executables stored in ''/usr/libexec/rpcd/'' directory will be runned by ''rpcd''. Lets look at the following example: | <code bash> |
| | mkdir -p /usr/libexec/rpcd |
| <code> | cat << "EOF" > /usr/libexec/rpcd/foo |
| $ mkdir -p /usr/libexec/rpcd/ | |
| $ cat << EOF > /usr/libexec/rpcd/foo | |
| #!/bin/sh | #!/bin/sh |
| |
| esac | esac |
| EOF | EOF |
| $ chmod +x /usr/libexec/rpcd/foo | chmod +x /usr/libexec/rpcd/foo |
| $ /etc/init.d/rpcd restart | service rpcd restart |
| </code> | </code> |
| |
| This will create new ubus functions which then can be used (after restarting rpcd): | This will create new ubus functions which then can be used (after restarting rpcd): |
| |
| <code> | <code bash> |
| $ ubus -v list foo | $ ubus -v list foo |
| 'foo' @a9482c5b | 'foo' @a9482c5b |
| "toto":{} | "toto":{} |
| "failme":{} | "failme":{} |
| | |
| $ ubus -S call foo bar '{"arg1": true }' | $ ubus -S call foo bar '{"arg1": true }' |
| {{"hello":"world"}} | {{"hello":"world"}} |
| | |
| $ ubus -S call foo toto | $ ubus -S call foo toto |
| {"something":"somevalue"} | {"something":"somevalue"} |
| | |
| $ ubus -S call foo failme | $ ubus -S call foo failme |
| | |
| $ echo $? | $ echo $? |
| 2 | 2 |
| |
| **The actual data is then sent by the ''ubus'' client via ''stdin''.** I.e. if you're testing the script itself, you need to use | **The actual data is then sent by the ''ubus'' client via ''stdin''.** I.e. if you're testing the script itself, you need to use |
| <code> | |
| | <code bash> |
| echo '{"arg1": 42}' | yourscript call yourmethod | echo '{"arg1": 42}' | yourscript call yourmethod |
| </code> | </code> |
| | |
| You //cannot// simply use ''yourscript call yourmethod '{"arg1": 42}''' as you might have expected. | You //cannot// simply use ''yourscript call yourmethod '{"arg1": 42}''' as you might have expected. |
| |
| The method signature is a simple object containing ''key:value'' pairs. The argument type is inferred from the value. If the value is a string (regardless of the contents) it is registered as string, if the value is a bool true or false, its registered as bool, if the value is an integer, it is registered as either int8, int16, int32 or int64 depending on the value i.e. ''"foo": 16'' will be ''INT16'', ''"foo": 64'' will be ''INT64'', ''"foo": 8'' will be ''INT8'' and everything else will be ''INT32''. | The method signature is a simple object containing ''key:value'' pairs. The argument type is inferred from the value. If the value is a string (regardless of the contents) it is registered as string, if the value is a bool true or false, its registered as bool, if the value is an integer, it is registered as either int8, int16, int32 or int64 depending on the value i.e. ''"foo": 16'' will be ''INT16'', ''"foo": 64'' will be ''INT64'', ''"foo": 8'' will be ''INT8'' and everything else will be ''INT32''. |
| |
| It is enough to issue ''/etc/init.d/rpcd reload'' to make it pick up new plugin executables, that way one does not lose active sessions. | It is enough to issue ''service rpcd reload'' to make it pick up new plugin executables, that way one does not lose active sessions. |
| |
| **NOTE:** At least on CC builds, reload is //not// enough, and you must ''restart'' to pickup new plugins and changes to existing plugins. | **NOTE:** At least on CC builds, reload is //not// enough, and you must ''restart'' to pickup new plugins and changes to existing plugins. |
| |