prometheus-node-exporter-lua: add dawn exporter
[feed/packages.git] / net / keepalived / files / keepalived.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2007-2015 OpenWrt.org
3
4 START=70
5 STOP=01
6
7 USE_PROCD=1
8
9 KEEPALIVED_CONF=/tmp/keepalived.conf
10
11 INDENT_1="\t"
12 INDENT_2="${INDENT_1}${INDENT_1}"
13 INDENT_3="${INDENT_1}${INDENT_1}${INDENT_1}"
14 INDENT_4="${INDENT_1}${INDENT_1}${INDENT_1}${INDENT_1}"
15
16 config_section_open() {
17 local tag="$1"
18 local name="$2"
19
20 printf '%s' "$tag" >> "$KEEPALIVED_CONF"
21 [ -n "$name" ] && printf ' %s' "$name" >> "$KEEPALIVED_CONF"
22 printf ' {\n' >> "$KEEPALIVED_CONF"
23 }
24
25 config_section_close() {
26 printf '}\n\n' >> "$KEEPALIVED_CONF"
27 }
28
29 config_foreach_wrapper() {
30 local section="$1"
31 local function="$1"
32
33 # Convention is that 'function' and 'section' are the same
34 config_foreach "$function" "$section"
35 }
36
37 print_elems_indent() {
38 local config="$1"
39 shift
40 local indent="$1"
41 shift
42
43 [ -z "$indent" ] && indent="$INDENT_1"
44 for opt in "$@"; do
45 local "$opt"
46 local optval
47 local no_val=0
48 if [ "${opt:0:7}" = "no_val_" ]; then
49 opt="${opt:7}"
50 no_val=1
51 fi
52 config_get "$opt" "$config" "$opt"
53 eval optval=\$"$opt"
54 [ -z "$optval" ] && continue
55 printf '%b%s' "$indent" "$opt" >> "$KEEPALIVED_CONF"
56 [ "$no_val" = "0" ] && {
57 local words=0
58 words="$(echo "$optval" | wc -w)"
59 if [ "$words" -gt 1 ]; then
60 printf ' "%s"' "$optval" >> "$KEEPALIVED_CONF"
61 else
62 printf ' %s' "$optval" >> "$KEEPALIVED_CONF"
63 fi
64 }
65 printf '\n' >> "$KEEPALIVED_CONF"
66 done
67 unset optval
68 }
69
70 print_list_indent() {
71 local lst="$1"
72 local indent="$2"
73 local lst_elems
74 [ -z "$indent" ] && indent="$INDENT_1"
75
76 eval lst_elems=\$"$lst"
77 [ -z "$lst_elems" ] && return 0
78
79 printf '%b%s {\n' "$indent" "$lst" >> "$KEEPALIVED_CONF"
80 for e in $lst_elems; do
81 printf '%b%s\n' "${indent}${INDENT_1}" "$e">> "$KEEPALIVED_CONF"
82 done
83 printf '%b}\n' "$indent" >> "$KEEPALIVED_CONF"
84 }
85
86 print_notify() {
87 local type="$1"
88 shift
89 local name="$1"
90 shift
91 for notify in "$@"; do
92 printf '%b%s' "${INDENT_1}" "$notify">> "$KEEPALIVED_CONF"
93 notify="$(echo "$notify" | tr 'a-z' 'A-Z')"
94 printf ' "/bin/busybox env -i ACTION=%s TYPE=%s NAME=%s /sbin/hotplug-call keepalived"\n' "$notify" "$type" "$name" >> "$KEEPALIVED_CONF"
95 done
96 }
97
98 globals() {
99 local notification_email
100
101 printf '%bscript_user root\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
102 printf '%benabled_script_security\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
103
104 config_get notification_email "$1" notification_email
105 print_list_indent notification_email
106
107 print_elems_indent "$1" "$INDENT_1" \
108 notification_email_from \
109 smtp_server \
110 smtp_connect_timeout \
111 router_id \
112 vrrp_mcast_group4 \
113 vrrp_mcast_group6 \
114 vrrp_startup_delay
115 }
116
117 print_ipaddress_indent() {
118 local section="$1"
119 local curr_ipaddr="$2"
120 local indent="$3"
121
122 local address device scope name
123 config_get name "$section" name
124 [ "$name" != "$curr_ipaddr" ] && return 0
125
126 config_get address "$section" address
127 config_get device "$section" device
128 config_get scope "$section" scope
129
130 # Default indent
131 [ -z "$indent" ] && indent="$INDENT_1"
132
133 # If no address exit
134 [ -z "$address" ] && return 0
135
136 if [ -z "$device" ]; then
137 printf '%b%s' "$indent" "$address" >> "$KEEPALIVED_CONF"
138 else
139 # Add IP address/netmask and device
140 printf '%b%s dev %s' "$indent" "$address" "$device">> "$KEEPALIVED_CONF"
141 # Add scope
142 [ -n "$scope" ] && printf ' scope %s' "$scope" >> "$KEEPALIVED_CONF"
143 fi
144
145 printf '\n' >> "$KEEPALIVED_CONF"
146 }
147
148 static_ipaddress() {
149 local address
150 config_get address "$1" address
151 for a in $address; do
152 config_foreach print_ipaddress_indent ipaddress "$a"
153 done
154 }
155
156 print_route_indent() {
157 local section="$1"
158 local curr_route="$2"
159 local indent="$3"
160
161 local name blackhole address src_addr gateway device scope table
162
163 config_get name "$section" name
164 [ "$name" != "$curr_route" ] && return 0
165
166 config_get_bool blackhole "$section" blackhole 0
167 config_get address "$section" address
168 config_get src_addr "$section" src_addr
169 config_get gateway "$section" gateway
170 config_get device "$section" device
171 config_get table "$section" table
172
173 # If no address exit
174 [ -z "$address" ] && return 0
175
176 # Default indent
177 [ -z "$indent" ] && indent="$INDENT_1"
178
179 [ "$blackhole" -gt 0 ] && {
180 printf '%bblackhole %s\n' "$indent" "$address" >> "$KEEPALIVED_CONF"
181 return 0
182 }
183 # Add src addr or address
184 if [ -n "$src_addr" ]; then
185 printf '%bsrc %s %s' "$indent" "$src_addr" "$address" >> "$KEEPALIVED_CONF"
186 else
187 [ -z "$device" ] && return 0
188 printf '%b%s' "$indent" "$address" >> "$KEEPALIVED_CONF"
189 fi
190 # Add route/gateway
191 [ -n "$gateway" ] && printf ' via %s' "$gateway" >> "$KEEPALIVED_CONF"
192 # Add device
193 printf ' dev %s' "$device" >> "$KEEPALIVED_CONF"
194 # Add scope
195 [ -n "$scope" ] && printf ' scope %s' "$scope" >> "$KEEPALIVED_CONF"
196 # Add table
197 [ -n "$table" ] && printf ' table %s' "$table" >> "$KEEPALIVED_CONF"
198 printf '\n' >> "$KEEPALIVED_CONF"
199
200 }
201
202 print_track_elem_indent() {
203 local section="$1"
204 local curr_track_elem="$2"
205 local indent="$3"
206
207 local name value
208 config_get name "$section" name
209 [ "$name" != "$curr_track_elem" ] && return 0
210
211 config_get value "$section" value
212 config_get weight "$section" weight
213
214 [ -z "$value" ] && return 0
215
216 printf '%b%s' "$indent" "$value" >> "$KEEPALIVED_CONF"
217 [ -n "$weight" ] && printf ' weight %s' "$weight" >> "$KEEPALIVED_CONF"
218 printf '\n' >> "$KEEPALIVED_CONF"
219 }
220
221 static_routes() {
222 local route
223 config_get route "$1" route
224 for r in $route; do
225 config_foreach print_route_indent route "$r"
226 done
227 }
228
229 # Count 'vrrp_instance' with the given name ; called by vrrp_instance_check()
230 vrrp_instance_name_count() {
231 local name
232 config_get name "$1" name
233 [ "$name" = "$2" ] && count="$((count + 1))"
234 }
235
236 # Check if there's a 'vrrp_instance' section with the given name
237 vrrp_instance_check() {
238 local count="0"
239 local name="$1"
240 config_foreach vrrp_instance_name_count vrrp_instance "$name"
241 [ $count -gt 0 ] && return 0 || return 1
242 }
243
244 vrrp_sync_group() {
245 local group name
246 local valid_group
247
248 # No name for group, exit
249 config_get name "$1" name
250 [ -z "$name" ] && return 0
251
252 # No members for group, exit
253 config_get group "$1" group
254 [ -z "$group" ] && return 0
255
256 # Check if we have 'vrrp_instance's defined for
257 # each member and remove names with not vrrp_instance defined
258 for m in $group; do
259 vrrp_instance_check "$m" && valid_group="$valid_group $m"
260 done
261 [ -z "$valid_group" ] && return 0
262
263 config_section_open "vrrp_sync_group" "$name"
264
265 group="$valid_group"
266 print_list_indent group
267
268 print_elems_indent "$1" "$INDENT_1" no_val_smtp_alert no_val_global_tracking
269
270 print_notify "GROUP" "$name" notify_backup notify_master \
271 notify_fault notify
272
273 config_section_close
274 }
275
276 vrrp_instance() {
277 local name auth_type auth_pass
278
279 config_get name "$1" name
280 [ -z "$name" ] && return 0
281
282 config_section_open "vrrp_instance" "$name"
283
284 config_get auth_type "$1" auth_type
285 config_get auth_pass "$1" auth_pass
286 [ -n "$auth_type" ] && [ -n "$auth_pass" ] && {
287 printf '%bauthentication {\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
288 printf '%bauth_type %s\n' "${INDENT_2}" "$auth_type" >> "$KEEPALIVED_CONF"
289 printf '%bauth_pass %s\n' "${INDENT_2}" "$auth_pass" >> "$KEEPALIVED_CONF"
290 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
291 }
292
293 print_elems_indent "$1" "$INDENT_1" state interface \
294 mcast_src_ip unicast_src_ip virtual_router_id version priority \
295 advert_int preempt_delay debug \
296 lvs_sync_daemon_interface garp_master_delay garp_master_refresh \
297 garp_master_repeat garp_master_refresh_repeat \
298 no_val_vmac_xmit_base no_val_native_ipv6 no_val_accept \
299 no_val_dont_track_primary no_val_smtp_alert no_val_nopreempt \
300 no_val_use_vmac
301
302 print_notify "INSTANCE" "$name" notify_backup notify_master \
303 notify_fault notify_stop
304
305 # Handle virtual_ipaddress & virtual_ipaddress_excluded lists
306 for opt in virtual_ipaddress virtual_ipaddress_excluded; do
307 config_get "$opt" "$1" "$opt"
308 eval optval=\$$opt
309 [ -z "$optval" ] && continue
310 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
311 for a in $optval; do
312 config_foreach print_ipaddress_indent ipaddress "$a" "$INDENT_2"
313 done
314 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
315 done
316
317 # Handle virtual_routes
318 for opt in virtual_routes; do
319 config_get "$opt" "$1" "$opt"
320 eval optval=\$$opt
321 [ -z "$optval" ] && continue
322 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
323 for r in $optval; do
324 config_foreach print_route_indent route "$r" "$INDENT_2"
325 done
326 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
327 done
328
329 # Handle track_script lists
330 for opt in track_script; do
331 config_get "$opt" "$1" "$opt"
332 eval optval=\$$opt
333 [ -z "$optval" ] && continue
334 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
335 for t in $optval; do
336 printf '%b%s\n' "${INDENT_2}" "$optval" >> "$KEEPALIVED_CONF"
337 done
338 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
339 done
340
341 # Handle track_interface lists
342 for opt in track_interface; do
343 config_get "$opt" "$1" "$opt"
344 eval optval=\$$opt
345 [ -z "$optval" ] && continue
346 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
347 for t in $optval; do
348 config_foreach print_track_elem_indent track_interface "$t" "$INDENT_2"
349 done
350 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
351 done
352
353 # Handle simple lists of strings (with no spaces in between)
354 for opt in unicast_peer; do
355 config_get "$opt" "$1" "$opt"
356 print_list_indent "$opt"
357 done
358 unset optval
359
360 config_section_close
361 }
362
363 vrrp_script() {
364 local name
365
366 config_get name "$1" name
367 [ -z "$name" ] && return 0
368
369 config_section_open "vrrp_script" "$name"
370
371 print_elems_indent "$1" "$INDENT_1" script interval weight fall rise
372
373 config_section_close
374 }
375
376 url() {
377 local url="$2"
378
379 local name path digest
380
381 config_get name "$1" name
382 [ "$url" = "$name" ] || return 0
383
384 config_get path "$1" path
385 config_get digest "$1" digest
386
387 [ -n "$digest" ] && [ -n "$path" ] && {
388 printf '%burl {\n' "${INDENT_3}" >> "$KEEPALIVED_CONF"
389 printf '%bpath %s\n' "${INDENT_4}" "$path" >> "$KEEPALIVED_CONF"
390 printf '%bdigest %s\n' "${INDENT_4}" "$digest" >> "$KEEPALIVED_CONF"
391 printf '%b}\n' "${INDENT_3}" >> "$KEEPALIVED_CONF"
392 }
393 }
394
395 url_list() {
396 config_foreach url url "$1"
397 }
398
399 real_server() {
400 local server="$2"
401
402 local enabled name weight ipaddr port check
403
404 config_get_bool enabled "$1" enabled 1
405 [ "$enabled" -eq 1 ] || return 0
406
407 config_get name "$1" name
408 [ "$server" = "$name" ] || return 0
409
410 config_get weight "$1" weight
411 [ -n "$weight" ] || return 0
412
413 config_get ipaddr "$1" ipaddr
414 config_get port "$1" port
415 config_get check "$1" check
416
417 [ -n "$ipaddr" ] && [ -n "$port" ] && {
418 printf '%breal_server %s %d {\n' "${INDENT_1}" "$ipaddr" "$port" >> "$KEEPALIVED_CONF"
419 printf '%bweight %d\n' "${INDENT_2}" "$weight" >> "$KEEPALIVED_CONF"
420 case "$check" in
421 TCP_CHECK)
422 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
423 print_elems_indent "$1" "$INDENT_3" connect_timeout \
424 connect_port
425 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
426 ;;
427 MISC_CHECK)
428 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
429 print_elems_indent "$1" "$INDENT_3" misc_path
430 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
431 ;;
432 HTTP_GET | SSL_GET)
433 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
434 print_elems_indent "$1" "$INDENT_3" connect_timeout \
435 connect_port nb_get_retry delay_before_retry
436 # Handle url list
437 config_list_foreach "$1" url url_list
438 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
439 ;;
440 esac
441 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
442 }
443 }
444
445 real_server_list() {
446 config_foreach real_server real_server "$1"
447 }
448
449 virtual_server() {
450 local enabled ipaddr port lb_algo sorry_server_ip sorry_server_port
451
452 config_get_bool enabled "$1" enabled 1
453 [ "$enabled" -eq 1 ] || return 0
454
455 config_get ipaddr "$1" ipaddr
456 [ -z "$ipaddr" ] && return 0
457 config_get port "$1" port
458 [ -z "$port" ] && return 0
459
460 config_section_open "virtual_server" "$ipaddr $port"
461
462 print_elems_indent "$1" "$INDENT_1" fwmark delay_loop \
463 lb_kind persistence_timeout persistence_granularity \
464 virtualhost protocol
465
466 config_get lb_algo "$1" lb_algo
467 [ -z "$lb_algo" ] && lb_algo="rr"
468 modprobe ip_vs_${lb_algo} 1>/dev/null 2>&1
469 printf '%blb_algo %s\n' "${INDENT_1}" "${lb_algo}" >> "$KEEPALIVED_CONF"
470
471 config_get sorry_server_ip "$1" sorry_server_ip
472 config_get sorry_server_port "$1" sorry_server_port
473 [ -n "$sorry_server_ip" ] && [ -n "$sorry_server_port" ] && {
474 printf '%bsorry_server %s %s\n' "${INDENT_1}" "$sorry_server_ip" "$sorry_server_port" >> "$KEEPALIVED_CONF"
475 }
476
477 # Handle real_server list
478 config_list_foreach "$1" real_server real_server_list
479
480 config_section_close
481 }
482
483 process_config() {
484 local alt_config_file linkbeat_use_polling
485
486 rm -f "$KEEPALIVED_CONF"
487
488 # First line
489 printf '! Configuration file for keepalived (autogenerated via init script)\n' > "$KEEPALIVED_CONF"
490 printf '! Written %s\n\n' "$(date +'%c')" >> "$KEEPALIVED_CONF"
491
492 [ -f /etc/config/keepalived ] || return 0
493 config_load 'keepalived'
494 config_get alt_config_file globals alt_config_file
495
496 # If "alt_config_file" specified, use that instead
497 [ -n "$alt_config_file" ] && [ -f "$alt_config_file" ] && {
498 rm -f "$KEEPALIVED_CONF"
499 # Symlink "alt_config_file" since it's a bit easier and safer
500 ln -s "$alt_config_file" "$KEEPALIVED_CONF"
501 return 0
502 }
503
504 config_get_bool linkbeat_use_polling globals linkbeat_use_polling 0
505 [ "$linkbeat_use_polling" -gt 0 ] && printf 'linkbeat_use_polling\n\n' >> "$KEEPALIVED_CONF"
506
507 config_section_open "global_defs"
508 config_foreach_wrapper globals
509 config_section_close
510
511 config_section_open "static_ipaddress"
512 config_foreach_wrapper static_ipaddress
513 config_section_close
514
515 config_section_open "static_routes"
516 config_foreach_wrapper static_routes
517 config_section_close
518
519 config_foreach_wrapper vrrp_script
520 config_foreach_wrapper vrrp_sync_group
521 config_foreach_wrapper vrrp_instance
522 config_foreach_wrapper virtual_server
523 return 0
524 }
525
526 service_triggers() {
527 procd_add_reload_trigger "keepalived"
528 }
529
530 reload_service() {
531 process_config
532 #SIGHUP is used by keepalived to do init.d reload
533 procd_send_signal keepalived
534 }
535
536 start_service() {
537 procd_open_instance
538 procd_set_param command /usr/sbin/keepalived
539 procd_append_param command -n # don't daemonize, procd will handle that for us
540 procd_append_param command -f "$KEEPALIVED_CONF"
541
542 process_config
543
544 # set auto respawn behavior
545 procd_set_param respawn
546 procd_close_instance
547 }
548