procd.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. #
  21. # No space separation is done for arrays/tables - use one function argument per command line argument
  22. #
  23. # procd_close_instance():
  24. # Complete the instance being prepared
  25. #
  26. # procd_kill(service, [instance]):
  27. # Kill a service instance (or all instances)
  28. #
  29. . $IPKG_INSTROOT/usr/share/libubox/jshn.sh
  30. _PROCD_SERVICE=
  31. _procd_call() {
  32. local old_cb
  33. json_set_namespace procd old_cb
  34. "$@"
  35. json_set_namespace $old_cb
  36. }
  37. _procd_wrapper() {
  38. while [ -n "$1" ]; do
  39. eval "$1() { _procd_call _$1 \"\$@\"; }"
  40. shift
  41. done
  42. }
  43. _procd_ubus_call() {
  44. local cmd="$1"
  45. ubus call service "$cmd" "$(json_dump)"
  46. json_cleanup
  47. }
  48. _procd_open_service() {
  49. local name="$1"
  50. local script="$2"
  51. _PROCD_SERVICE="$name"
  52. _PROCD_INSTANCE_SEQ=0
  53. json_init
  54. json_add_string name "$name"
  55. [ -n "$script" ] && json_add_string script "$script"
  56. json_add_object instances
  57. }
  58. _procd_close_service() {
  59. json_close_object
  60. _procd_open_trigger
  61. service_triggers
  62. _procd_close_trigger
  63. _procd_ubus_call set
  64. }
  65. _procd_add_array_data() {
  66. while [ -n "$1" ]; do
  67. json_add_string "" "$1"
  68. shift
  69. done
  70. }
  71. _procd_add_array() {
  72. json_add_array "$1"
  73. shift
  74. _procd_add_array_data "$@"
  75. json_close_array
  76. }
  77. _procd_add_table_data() {
  78. while [ -n "$1" ]; do
  79. local var="${1%%=*}"
  80. local val="${1#*=}"
  81. [[ "$1" == "$val" ]] && val=
  82. json_add_string "$var" "$val"
  83. shift
  84. done
  85. }
  86. _procd_add_table() {
  87. json_add_object "$1"
  88. shift
  89. _procd_add_table_data "$@"
  90. json_close_object
  91. }
  92. _procd_open_instance() {
  93. local name="$1"; shift
  94. _PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
  95. name="${name:-instance$_PROCD_INSTANCE_SEQ}"
  96. json_add_object "$name"
  97. }
  98. _procd_open_trigger() {
  99. json_add_array "triggers"
  100. }
  101. _procd_set_param() {
  102. local type="$1"; shift
  103. case "$type" in
  104. env|data)
  105. _procd_add_table "$type" "$@"
  106. ;;
  107. command|netdev|file|respawn)
  108. _procd_add_array "$type" "$@"
  109. ;;
  110. nice)
  111. json_add_int "$type" "$1"
  112. ;;
  113. esac
  114. }
  115. _procd_add_config_trigger() {
  116. json_add_array
  117. _procd_add_array_data "config.change"
  118. json_add_array
  119. _procd_add_array_data "if"
  120. json_add_array
  121. _procd_add_array_data "eq" "package" "$1"
  122. shift
  123. json_close_array
  124. json_add_array
  125. _procd_add_array_data "run_script" "$@"
  126. json_close_array
  127. json_close_array
  128. json_close_array
  129. }
  130. _procd_add_reload_trigger() {
  131. local script=$(readlink "$initscript")
  132. local name=$(basename ${script:-$initscript})
  133. _procd_add_config_trigger $1 /etc/init.d/$name reload
  134. }
  135. _procd_add_reload_trigger() {
  136. local script=$(readlink "$initscript")
  137. local name=$(basename ${script:-$initscript})
  138. _procd_add_config_trigger $1 /etc/init.d/$name reload
  139. }
  140. _procd_append_param() {
  141. local type="$1"; shift
  142. json_select "$type"
  143. case "$type" in
  144. env|data)
  145. _procd_add_table_data "$@"
  146. ;;
  147. command|netdev|file|respawn)
  148. _procd_add_array_data "$@"
  149. ;;
  150. esac
  151. json_select ..
  152. }
  153. _procd_close_instance() {
  154. json_close_object
  155. }
  156. _procd_close_trigger() {
  157. json_close_array
  158. }
  159. _procd_add_instance() {
  160. _procd_open_instance
  161. _procd_set_command "$@"
  162. _procd_close_instance
  163. }
  164. _procd_kill() {
  165. local service="$1"
  166. local instance="$2"
  167. json_init
  168. [ -n "$service" ] && json_add_string name "$service"
  169. [ -n "$instance" ] && json_add_string instance "$instance"
  170. _procd_ubus_call delete
  171. }
  172. _procd_wrapper \
  173. procd_open_service \
  174. procd_close_service \
  175. procd_add_instance \
  176. procd_add_config_trigger \
  177. procd_add_reload_trigger \
  178. procd_open_trigger \
  179. procd_close_trigger \
  180. procd_open_instance \
  181. procd_close_instance \
  182. procd_set_param \
  183. procd_append_param \
  184. procd_kill