procd.sh 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. # respawn info: array with 3 values $restart_timeout $fail_hreshold $max_fail
  16. # env: environment variable (passed to the process)
  17. # data: arbitrary name/value pairs for detecting config changes (table)
  18. # file: configuration files (array)
  19. # netdev: bound network device (detects ifindex changes)
  20. # limits: resource limits (passed to the process)
  21. # user info: array with 1 values $username
  22. #
  23. # No space separation is done for arrays/tables - use one function argument per command line argument
  24. #
  25. # procd_close_instance():
  26. # Complete the instance being prepared
  27. #
  28. # procd_kill(service, [instance]):
  29. # Kill a service instance (or all instances)
  30. #
  31. . $IPKG_INSTROOT/usr/share/libubox/jshn.sh
  32. _PROCD_SERVICE=
  33. _procd_call() {
  34. local old_cb
  35. json_set_namespace procd old_cb
  36. "$@"
  37. json_set_namespace $old_cb
  38. }
  39. _procd_wrapper() {
  40. while [ -n "$1" ]; do
  41. eval "$1() { _procd_call _$1 \"\$@\"; }"
  42. shift
  43. done
  44. }
  45. _procd_ubus_call() {
  46. local cmd="$1"
  47. [ -n "$PROCD_DEBUG" ] && json_dump >&2
  48. ubus call service "$cmd" "$(json_dump)"
  49. json_cleanup
  50. }
  51. _procd_open_service() {
  52. local name="$1"
  53. local script="$2"
  54. _PROCD_SERVICE="$name"
  55. _PROCD_INSTANCE_SEQ=0
  56. json_init
  57. json_add_string name "$name"
  58. [ -n "$script" ] && json_add_string script "$script"
  59. json_add_object instances
  60. }
  61. _procd_close_service() {
  62. json_close_object
  63. service_triggers
  64. _procd_ubus_call set
  65. }
  66. _procd_add_array_data() {
  67. while [ "$#" -gt 0 ]; do
  68. json_add_string "" "$1"
  69. shift
  70. done
  71. }
  72. _procd_add_array() {
  73. json_add_array "$1"
  74. shift
  75. _procd_add_array_data "$@"
  76. json_close_array
  77. }
  78. _procd_add_table_data() {
  79. while [ -n "$1" ]; do
  80. local var="${1%%=*}"
  81. local val="${1#*=}"
  82. [ "$1" = "$val" ] && val=
  83. json_add_string "$var" "$val"
  84. shift
  85. done
  86. }
  87. _procd_add_table() {
  88. json_add_object "$1"
  89. shift
  90. _procd_add_table_data "$@"
  91. json_close_object
  92. }
  93. _procd_open_instance() {
  94. local name="$1"; shift
  95. _PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
  96. name="${name:-instance$_PROCD_INSTANCE_SEQ}"
  97. json_add_object "$name"
  98. }
  99. _procd_open_trigger() {
  100. json_add_array "triggers"
  101. }
  102. _procd_open_validate() {
  103. json_add_array "validate"
  104. }
  105. _procd_set_param() {
  106. local type="$1"; shift
  107. case "$type" in
  108. env|data|limits)
  109. _procd_add_table "$type" "$@"
  110. ;;
  111. command|netdev|file|respawn|watch)
  112. _procd_add_array "$type" "$@"
  113. ;;
  114. error)
  115. json_add_array "$type"
  116. json_add_string "" "$@"
  117. json_close_array
  118. ;;
  119. nice)
  120. json_add_int "$type" "$1"
  121. ;;
  122. user)
  123. json_add_string "$type" "$1"
  124. ;;
  125. esac
  126. }
  127. _procd_add_interface_trigger() {
  128. json_add_array
  129. _procd_add_array_data "$1"
  130. shift
  131. json_add_array
  132. _procd_add_array_data "if"
  133. json_add_array
  134. _procd_add_array_data "eq" "interface" "$1"
  135. shift
  136. json_close_array
  137. json_add_array
  138. _procd_add_array_data "run_script" "$@"
  139. json_close_array
  140. json_close_array
  141. json_close_array
  142. }
  143. _procd_add_reload_interface_trigger() {
  144. local script=$(readlink "$initscript")
  145. local name=$(basename ${script:-$initscript})
  146. _procd_open_trigger
  147. _procd_add_interface_trigger "interface.*" $1 /etc/init.d/$name reload
  148. _procd_close_trigger
  149. }
  150. _procd_add_config_trigger() {
  151. json_add_array
  152. _procd_add_array_data "$1"
  153. shift
  154. json_add_array
  155. _procd_add_array_data "if"
  156. json_add_array
  157. _procd_add_array_data "eq" "package" "$1"
  158. shift
  159. json_close_array
  160. json_add_array
  161. _procd_add_array_data "run_script" "$@"
  162. json_close_array
  163. json_close_array
  164. json_close_array
  165. }
  166. _procd_add_raw_trigger() {
  167. json_add_array
  168. _procd_add_array_data "$1"
  169. shift
  170. local timeout=$1
  171. shift
  172. json_add_array
  173. json_add_array
  174. _procd_add_array_data "run_script" "$@"
  175. json_close_array
  176. json_close_array
  177. json_add_int "" "$timeout"
  178. json_close_array
  179. }
  180. _procd_add_reload_trigger() {
  181. local script=$(readlink "$initscript")
  182. local name=$(basename ${script:-$initscript})
  183. local file
  184. _procd_open_trigger
  185. for file in "$@"; do
  186. _procd_add_config_trigger "config.change" "$file" /etc/init.d/$name reload
  187. done
  188. _procd_close_trigger
  189. }
  190. _procd_add_validation() {
  191. _procd_open_validate
  192. $@
  193. _procd_close_validate
  194. }
  195. _procd_append_param() {
  196. local type="$1"; shift
  197. local _json_no_warning=1
  198. json_select "$type"
  199. [ $? = 0 ] || {
  200. _procd_set_param "$type" "$@"
  201. return
  202. }
  203. case "$type" in
  204. env|data|limits)
  205. _procd_add_table_data "$@"
  206. ;;
  207. command|netdev|file|respawn|watch)
  208. _procd_add_array_data "$@"
  209. ;;
  210. error)
  211. json_add_string "" "$@"
  212. ;;
  213. esac
  214. json_select ..
  215. }
  216. _procd_close_instance() {
  217. json_close_object
  218. }
  219. _procd_close_trigger() {
  220. json_close_array
  221. }
  222. _procd_close_validate() {
  223. json_close_array
  224. }
  225. _procd_add_instance() {
  226. _procd_open_instance
  227. _procd_set_param command "$@"
  228. _procd_close_instance
  229. }
  230. _procd_kill() {
  231. local service="$1"
  232. local instance="$2"
  233. json_init
  234. [ -n "$service" ] && json_add_string name "$service"
  235. [ -n "$instance" ] && json_add_string instance "$instance"
  236. _procd_ubus_call delete
  237. }
  238. procd_open_data() {
  239. local name="$1"
  240. json_set_namespace procd __procd_old_cb
  241. json_add_object data
  242. }
  243. procd_close_data() {
  244. json_close_object
  245. json_set_namespace $__procd_old_cb
  246. }
  247. _procd_set_config_changed() {
  248. local package="$1"
  249. json_init
  250. json_add_string type config.change
  251. json_add_object data
  252. json_add_string package "$package"
  253. json_close_object
  254. ubus call service event "$(json_dump)"
  255. }
  256. procd_add_mdns_service() {
  257. local service proto port
  258. service=$1; shift
  259. proto=$1; shift
  260. port=$1; shift
  261. json_add_object "${service}_$port"
  262. json_add_string "service" "_$service._$proto.local"
  263. json_add_int port "$port"
  264. [ -n "$1" ] && {
  265. json_add_array txt
  266. for txt in $@; do json_add_string "" $txt; done
  267. json_select ..
  268. }
  269. json_select ..
  270. }
  271. procd_add_mdns() {
  272. procd_open_data
  273. json_add_object "mdns"
  274. procd_add_mdns_service $@
  275. json_close_object
  276. procd_close_data
  277. }
  278. uci_validate_section()
  279. {
  280. local _package="$1"
  281. local _type="$2"
  282. local _name="$3"
  283. local _result
  284. local _error
  285. shift; shift; shift
  286. _result=`/sbin/validate_data "$_package" "$_type" "$_name" "$@" 2> /dev/null`
  287. _error=$?
  288. eval "$_result"
  289. [ "$_error" = "0" ] || `/sbin/validate_data "$_package" "$_type" "$_name" "$@" 1> /dev/null`
  290. return $_error
  291. }
  292. _procd_wrapper \
  293. procd_open_service \
  294. procd_close_service \
  295. procd_add_instance \
  296. procd_add_raw_trigger \
  297. procd_add_config_trigger \
  298. procd_add_interface_trigger \
  299. procd_add_reload_trigger \
  300. procd_add_reload_interface_trigger \
  301. procd_add_interface_reload \
  302. procd_open_trigger \
  303. procd_close_trigger \
  304. procd_open_instance \
  305. procd_close_instance \
  306. procd_open_validate \
  307. procd_close_validate \
  308. procd_set_param \
  309. procd_append_param \
  310. procd_add_validation \
  311. procd_set_config_changed \
  312. procd_kill