procd: add a small script that handles config reloads until configd is ready
[openwrt/staging/dedeckeh.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_open_trigger
71 service_triggers
72 _procd_close_trigger
73 _procd_ubus_call set
74 }
75
76 _procd_add_array_data() {
77 while [ -n "$1" ]; do
78 json_add_string "" "$1"
79 shift
80 done
81 }
82
83 _procd_add_array() {
84 json_add_array "$1"
85 shift
86 _procd_add_array_data "$@"
87 json_close_array
88 }
89
90 _procd_add_table_data() {
91 while [ -n "$1" ]; do
92 local var="${1%%=*}"
93 local val="${1#*=}"
94 [[ "$1" == "$val" ]] && val=
95 json_add_string "$var" "$val"
96 shift
97 done
98 }
99
100 _procd_add_table() {
101 json_add_object "$1"
102 shift
103 _procd_add_table_data "$@"
104 json_close_object
105 }
106
107 _procd_open_instance() {
108 local name="$1"; shift
109
110 _PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
111 name="${name:-instance$_PROCD_INSTANCE_SEQ}"
112 json_add_object "$name"
113 }
114
115 _procd_open_trigger() {
116 json_add_array "triggers"
117 }
118
119 _procd_set_param() {
120 local type="$1"; shift
121
122 case "$type" in
123 env|data)
124 _procd_add_table "$type" "$@"
125 ;;
126 command|netdev|file)
127 _procd_add_array "$type" "$@"
128 ;;
129 nice)
130 json_add_int "$type" "$1"
131 ;;
132 esac
133 }
134
135 _procd_add_config_trigger() {
136 json_add_array
137 _procd_add_array_data "config.change"
138
139 json_add_array
140 _procd_add_array_data "if"
141
142 json_add_array
143 _procd_add_array_data "eq" "package" "$1"
144 shift
145 json_close_array
146
147 json_add_array
148 _procd_add_array_data "run_script" "$@"
149 json_close_array
150
151 json_close_array
152
153 json_close_array
154 }
155
156 _procd_append_param() {
157 local type="$1"; shift
158
159 json_select "$type"
160 case "$type" in
161 env|data)
162 _procd_add_table_data "$@"
163 ;;
164 command|netdev|file)
165 _procd_add_array_data "$@"
166 ;;
167 esac
168 json_select ..
169 }
170
171 _procd_close_instance() {
172 json_close_object
173 }
174
175 _procd_close_trigger() {
176 json_close_array
177 }
178
179 _procd_add_instance() {
180 _procd_open_instance
181 _procd_set_command "$@"
182 _procd_close_instance
183 }
184
185 _procd_kill() {
186 local service="$1"
187 local instance="$2"
188
189 json_init
190 [ -n "$service" ] && json_add_string name "$service"
191 [ -n "$instance" ] && json_add_string instance "$instance"
192 _procd_ubus_call delete
193 }
194
195 _procd_wrapper \
196 procd_open_service \
197 procd_close_service \
198 procd_add_instance \
199 procd_add_config_trigger \
200 procd_open_trigger \
201 procd_close_trigger \
202 procd_open_instance \
203 procd_close_instance \
204 procd_set_param \
205 procd_append_param \
206 procd_kill