diff --git a/utils/watchcat/Makefile b/utils/watchcat/Makefile index ed5d808490..db9151d91c 100644 --- a/utils/watchcat/Makefile +++ b/utils/watchcat/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=watchcat PKG_VERSION:=1 -PKG_RELEASE:=25 +PKG_RELEASE:=26 PKG_MAINTAINER:=Daniel F. Dickinson , Dharmik Parmar PKG_LICENSE:=GPL-2.0 @@ -43,6 +43,8 @@ define Package/watchcat/install $(INSTALL_DATA) ./files/watchcat.config $(1)/etc/config/watchcat $(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_BIN) ./files/migrate-watchcat $(1)/etc/uci-defaults/migrate-watchcat + $(INSTALL_DIR) $(1)/lib/functions + $(INSTALL_DATA) ./files/watchcat.sh.functions $(1)/lib/functions/watchcat.sh endef $(eval $(call BuildPackage,watchcat)) diff --git a/utils/watchcat/files/watchcat.init b/utils/watchcat/files/watchcat.init index 5966d4716d..85535199ef 100644 --- a/utils/watchcat/files/watchcat.init +++ b/utils/watchcat/files/watchcat.init @@ -9,6 +9,9 @@ USE_PROCD=1 START=97 STOP=01 +# shellcheck source=/dev/null +. /lib/functions/watchcat.sh + append_string() { varname="$1" add="$2" @@ -142,10 +145,55 @@ config_watchcat() { } start_service() { + # procd expects $1 to be a specific instance + if [ "$2" = "ifup-any" ]; then + logger -p daemon.notice -t "watchcat[$$]" "Restarting due to an interface up with any unresolved interface." + fi + config_load watchcat config_foreach config_watchcat watchcat } -service_triggers() { - procd_add_reload_trigger "watchcat" +# Setup trigger in procd for changes to specified network interface +add_interface_trigger() { + local section="$1" + local ret=1 + local interface mode logical + + config_get mode "$section" mode "ping_reboot" + config_get interface "$section" interface + + # Fix potential typo in mode and provide backward compatibility. + [ "$mode" = "allways" ] && mode="periodic_reboot" + [ "$mode" = "always" ] && mode="periodic_reboot" + [ "$mode" = "ping" ] && mode="ping_reboot" + + # ping_reboot mode and restart_iface mode specific checks + if [ "$mode" = "ping_reboot" ] || [ "$mode" = "restart_iface" ] || [ "$mode" = "run_script" ]; then + [ -n "$interface" ] || return + + logical="$(watchcat_resolve_restart_iface "$interface")" + ret=$? + + if [ -n "$logical" ] && [ "$ret" -eq 0 ]; then + procd_add_interface_trigger "interface.*.up" "$logical" "/etc/init.d/watchcat" "restart" + else + has_failed_interface_resolve="true" + fi + fi +} + +service_triggers() { + local has_failed_interface_resolve="false" + + procd_add_reload_trigger "watchcat" + + config_load watchcat + config_foreach add_interface_trigger watchcat + + if [ "$has_failed_interface_resolve" = "true" ]; then + # PROCD_RELOAD_DELAY is defined in /lib/functions/procd.sh, sourced by /etc/rc.common on the live device + # procd expects parameter after script action (here, restart) to be a specific instance + procd_add_raw_trigger "interface.*.up" "$PROCD_RELOAD_DELAY" "/etc/init.d/watchcat" "restart" "" "ifup-any" + fi } diff --git a/utils/watchcat/files/watchcat.sh b/utils/watchcat/files/watchcat.sh index 2ce9cc358b..589a17331c 100644 --- a/utils/watchcat/files/watchcat.sh +++ b/utils/watchcat/files/watchcat.sh @@ -10,78 +10,7 @@ # shellcheck shell=busybox # shellcheck source=/dev/null -. /lib/network/config.sh -. /lib/functions/network.sh - -# Accept the historical real-device input while also handling @logical -# interface references used by other OpenWrt configs. -watchcat_resolve_ping_iface() { - local iface="$1" - local logical device network - - [ -n "$iface" ] || return 1 - - case "$iface" in - @*) - logical="${iface#@}" - [ -n "$logical" ] || return 1 - if network_get_device device "$logical"; then - printf '%s\n' "$device" - return 0 - fi - printf '%s\n' "$iface" - return 1 - ;; - esac - - network="$(find_config "$iface")" - if [ -n "$network" ]; then - printf '%s\n' "$iface" - return 0 - fi - - if network_get_device device "$iface"; then - printf '%s\n' "$device" - return 0 - fi - - printf '%s\n' "$iface" - return 1 -} - -watchcat_resolve_restart_iface() { - local iface="$1" - local network device - - [ -n "$iface" ] || return 1 - - case "$iface" in - @*) - network="${iface#@}" - [ -n "$network" ] || return 1 - if ! network_get_device device "$network"; then - printf '%s\n' "$network" - return 1 - fi - printf '%s\n' "$network" - return 0 - ;; - esac - - network="$(find_config "$iface")" - if [ -n "$network" ]; then - printf '%s\n' "$network" - return 0 - fi - - if network_get_device device "$iface"; then - printf '%s\n' "$iface" - return 0 - fi - - printf '%s\n' "$iface" - return 1 -} +. /lib/functions/watchcat.sh get_ping_size() { ps=$1 diff --git a/utils/watchcat/files/watchcat.sh.functions b/utils/watchcat/files/watchcat.sh.functions new file mode 100644 index 0000000000..981166a6da --- /dev/null +++ b/utils/watchcat/files/watchcat.sh.functions @@ -0,0 +1,82 @@ +#!/bin/sh +# Shebang line included so editors and shellcheck/shfmt know this contains +# shell code + +# In recent (relevant) versions of shellcheck busybox is a valid shell type +# shellcheck shell=busybox + +# Helper functions for watchcat + +# shellcheck source=/dev/null +. /lib/network/config.sh +. /lib/functions/network.sh + +# Accept the historical real-device input while also handling @logical +# interface references used by other OpenWrt configs. +watchcat_resolve_ping_iface() { + local iface="$1" + local logical device network + + [ -n "$iface" ] || return 1 + + case "$iface" in + @*) + logical="${iface#@}" + [ -n "$logical" ] || return 1 + if network_get_device device "$logical"; then + printf '%s\n' "$device" + return 0 + fi + printf '%s\n' "$iface" + return 1 + ;; + esac + + network="$(find_config "$iface")" + if [ -n "$network" ]; then + printf '%s\n' "$iface" + return 0 + fi + + if network_get_device device "$iface"; then + printf '%s\n' "$device" + return 0 + fi + + printf '%s\n' "$iface" + return 1 +} + +watchcat_resolve_restart_iface() { + local iface="$1" + local network device + + [ -n "$iface" ] || return 1 + + case "$iface" in + @*) + network="${iface#@}" + [ -n "$network" ] || return 1 + if ! network_get_device device "$network"; then + printf '%s\n' "$network" + return 1 + fi + printf '%s\n' "$network" + return 0 + ;; + esac + + network="$(find_config "$iface")" + if [ -n "$network" ]; then + printf '%s\n' "$network" + return 0 + fi + + if network_get_device device "$iface"; then + printf '%s\n' "$iface" + return 0 + fi + + printf '%s\n' "$iface" + return 1 +}