b706b1e97d3d57176f489597409690aa04f0a3c6
[openwrt.git] / package / system / procd / files / procd.sh
1 # procd API:
2 #
3 # procd_open_service(name, [script]):
4 #   Initialize a new procd command message containing a service with one or more instances
5 #
6 # procd_close_service()
7 #   Send the command message for the service
8 #
9 # procd_open_instance([name]):
10 #   Add an instance to the service described by the previous procd_open_service call
11 #
12 # procd_set_param(type, [value...])
13 #   Available types:
14 #     command: command line (array).
15 #     env: environment variable (passed to the process)
16 #     data: arbitrary name/value pairs for detecting config changes (table)
17 #     file: configuration files (array)
18 #     netdev: bound network device (detects ifindex changes)
19 #
20 #   No space separation is done for arrays/tables - use one function argument per command line argument
21 #
22 # procd_close_instance():
23 #   Complete the instance being prepared
24 #
25 # procd_kill(service, [instance]):
26 #   Kill a service instance (or all instances)
27 #
28
29 . $IPKG_INSTROOT/usr/share/libubox/jshn.sh
30
31 _PROCD_SERVICE=
32
33 _procd_call() {
34         local old_cb
35
36         json_set_namespace procd old_cb
37         "$@"
38         json_set_namespace $old_cb
39 }
40
41 _procd_wrapper() {
42         while [ -n "$1" ]; do
43                 eval "$1() { _procd_call _$1 \"\$@\"; }"
44                 shift
45         done
46 }
47
48 _procd_ubus_call() {
49         local cmd="$1"
50
51         ubus call service "$cmd" "$(json_dump)"
52         json_cleanup
53 }
54
55 _procd_open_service() {
56         local name="$1"
57         local script="$2"
58
59         _PROCD_SERVICE="$name"
60         _PROCD_INSTANCE_SEQ=0
61
62         json_init
63         json_add_string name "$name"
64         [ -n "$script" ] && json_add_string script "$script"
65         json_add_object instances
66 }
67
68 _procd_close_service() {
69         json_close_object
70         _procd_ubus_call set
71 }
72
73 _procd_add_array_data() {
74         while [ -n "$1" ]; do
75                 json_add_string "" "$1"
76                 shift
77         done
78 }
79
80 _procd_add_array() {
81         json_add_array "$1"
82         shift
83         _procd_add_array_data "$@"
84         json_close_array
85 }
86
87 _procd_add_table_data() {
88         while [ -n "$1" ]; do
89                 local var="${1%%=*}"
90                 local val="${1#*=}"
91                 [[ "$1" == "$val" ]] && val=
92                 json_add_string "$var" "$val"
93                 shift
94         done
95 }
96
97 _procd_add_table() {
98         json_add_object "$1"
99         shift
100         _procd_add_table_data "$@"
101         json_close_object
102 }
103
104 _procd_open_instance() {
105         local name="$1"; shift
106
107         _PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
108         name="${name:-instance$_PROCD_INSTANCE_SEQ}"
109         json_add_object "$name"
110 }
111
112 _procd_open_trigger() {
113         json_add_array "triggers"
114 }
115
116 _procd_set_param() {
117         local type="$1"; shift
118
119         case "$type" in
120                 env|data)
121                         _procd_add_table "$type" "$@"
122                 ;;
123                 command|netdev|file)
124                         _procd_add_array "$type" "$@"
125                 ;;
126                 nice)
127                         json_add_int "$type" "$1"
128                 ;;
129         esac
130 }
131
132 _procd_add_config_trigger() {
133         json_add_array
134         _procd_add_array_data "config.change"
135
136         json_add_array
137         _procd_add_array_data "if"
138
139         json_add_array
140         _procd_add_array_data "eq" "package" "$1"
141         shift
142         json_close_array
143
144         json_add_array
145         _procd_add_array_data "run_script" "$@"
146         json_close_array
147
148         json_close_array
149
150         json_close_array
151 }
152
153 _procd_append_param() {
154         local type="$1"; shift
155
156         json_select "$type"
157         case "$type" in
158                 env|data)
159                         _procd_add_table_data "$@"
160                 ;;
161                 command|netdev|file)
162                         _procd_add_array_data "$@"
163                 ;;
164         esac
165         json_select ..
166 }
167
168 _procd_close_instance() {
169         json_close_object
170 }
171
172 _procd_close_trigger() {
173         json_close_array
174 }
175
176 _procd_add_instance() {
177         _procd_open_instance
178         _procd_set_command "$@"
179         _procd_close_instance
180 }
181
182 _procd_kill() {
183         local service="$1"
184         local instance="$2"
185
186         json_init
187         [ -n "$service" ] && json_add_string name "$service"
188         [ -n "$instance" ] && json_add_string instance "$instance"
189         _procd_ubus_call delete
190 }
191
192 _procd_wrapper \
193         procd_open_service \
194         procd_close_service \
195         procd_add_instance \
196         procd_add_config_trigger \
197         procd_open_trigger \
198         procd_close_trigger \
199         procd_open_instance \
200         procd_close_instance \
201         procd_set_param \
202         procd_append_param \
203         procd_kill