From f749bd72375d33932b9381d35e6446b18430e484 Mon Sep 17 00:00:00 2001 From: Roger Date: Wed, 13 Aug 2014 21:37:44 -0500 Subject: [PATCH] watchcat: add with myself as maintainer Signed-off-by: Roger D rogerdammit@gmail.com --- utils/watchcat/Makefile | 44 +++++++++ utils/watchcat/files/initd_watchcat | 108 +++++++++++++++++++++ utils/watchcat/files/uci_defaults_watchcat | 10 ++ utils/watchcat/files/watchcat.sh | 69 +++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 utils/watchcat/Makefile create mode 100644 utils/watchcat/files/initd_watchcat create mode 100644 utils/watchcat/files/uci_defaults_watchcat create mode 100644 utils/watchcat/files/watchcat.sh diff --git a/utils/watchcat/Makefile b/utils/watchcat/Makefile new file mode 100644 index 000000000..03d4ed983 --- /dev/null +++ b/utils/watchcat/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (C) 2010 segal.di.ubi.pt +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=watchcat +PKG_VERSION:=1 +PKG_RELEASE:=5 + +PKG_MAINTAINER:=Roger D + +include $(INCLUDE_DIR)/package.mk + +define Package/watchcat + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Enable the configuration of programed reboots +endef + +define Package/watchcat/description +Allows to configure a periodically reboot, or after loosing internet connectivity. Configured trough UCI /etc/config/system. +endef + +define Package/watchcat/conffiles +/etc/config/system +endef + +define Build/Compile +endef + +define Package/watchcat/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/initd_watchcat $(1)/etc/init.d/watchcat + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/watchcat.sh $(1)/usr/bin/watchcat.sh + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/uci_defaults_watchcat $(1)/etc/uci-defaults/50-watchcat +endef + +$(eval $(call BuildPackage,watchcat)) diff --git a/utils/watchcat/files/initd_watchcat b/utils/watchcat/files/initd_watchcat new file mode 100644 index 000000000..36e353f5f --- /dev/null +++ b/utils/watchcat/files/initd_watchcat @@ -0,0 +1,108 @@ +#!/bin/sh /etc/rc.common + +START=97 + +PIDFILE="/tmp/run/watchcat" + +append_string() { + local varname="$1"; local add="$2"; local separator="${3:- }"; local actual + eval "actual=\$$varname" + + new="${actual:+$actual$separator}$add" + eval "$varname=\$new" +} + +timetoseconds() { + local time=$1 + unset seconds + + { [ "$time" -ge 1 ] 2> /dev/null && seconds="$time"; } || \ + { [ "${time%s}" -ge 1 ] 2> /dev/null && seconds="${time%s}"; } || \ + { [ "${time%m}" -ge 1 ] 2> /dev/null && seconds=$((${time%m}*60)); } || \ + { [ "${time%h}" -ge 1 ] 2> /dev/null && seconds=$((${time%h}*3600)); } || \ + { [ "${time%d}" -ge 1 ] 2> /dev/null && seconds=$((${time%d}*86400)); } +} + +load_watchcat() { + config_get period $1 period + config_get mode $1 mode "allways" + config_get pinghosts $1 pinghosts "8.8.8.8" + config_get pingperiod $1 pingperiod + config_get forcedelay $1 forcedelay "0" + + error="" + + timetoseconds "$period" + period="$seconds" + [ "$period" -ge 1 ] \ + || append_string "error" 'period is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; " + [ "$mode" = "allways" -o "$mode" = "ping" ] \ + || append_string "error" "mode must be 'allways' or 'ping'" "; " + [ -n "$pinghosts" -o "$mode" = "allways" ] \ + || append_string "error" "pinghosts must be set when in 'ping' mode" "; " + [ "$mode" = "ping" ] && { + if [ -n "$pingperiod" ] + then + timetoseconds "$pingperiod" + pingperiod="$seconds" + if [ "$pingperiod" -ge 0 ] + then + [ "$pingperiod" -le "$period" ] \ + || append_string "error" "pingperiod must be less than period" "; " + else + append_string "error" 'pingperiod is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; " + fi + else + pingperiod="$((period/20))" + fi + } + [ "$pingperiod" -lt "$period" -o "$mode" = "allways" ] \ + || append_string "error" "pingperiod is not recognized" "; " + [ "$forcedelay" -ge 0 ] \ + || append_string "error" "forcedelay must be a integer greater or equal than 0, where 0 means disabled" "; " + + [ -n "$error" ] && { logger -p user.err -t "watchcat" "reboot program $1 not started - $error"; return; } + + if [ "$mode" = "allways" ] + then + /usr/bin/watchcat.sh "allways" "$period" "$forcedelay" & + logger -p user.info -t "wathchat" "started task (mode=$mode;period=$period;forcedelay=$forcedelay)" + else + /usr/bin/watchcat.sh "period" "$period" "$forcedelay" "$pinghosts" "$pingperiod" & + logger -p user.info -t "wathchat" "started task (mode=$mode;period=$period;pinghosts=$pinghosts;pingperiod=$pingperiod;forcedelay=$forcedelay)" + fi + + echo $! >> "${PIDFILE}.pids" +} + +stop() { + if [ -f "${PIDFILE}.pids" ] + then + logger -p user.info -t "watchcat" "stopping all tasks" + + while read pid + do + kill "$pid" + done < "${PIDFILE}.pids" + + rm "${PIDFILE}.pids" + + logger -p user.info -t "watchcat" "all tasks stopped" + else + logger -p user.info -t "watchcat" "no tasks running" + fi +} + +start() { + [ -f "${PIDFILE}.pids" ] && stop + + config_load system + if [ -n "$(uci show system.@watchcat[0])" ] # at least one watchcat section exists + then + logger -p user.info -t "watchcat" "starting all tasks" + config_foreach load_watchcat watchcat + logger -p user.info -t "watchcat" "all tasks started" + else + logger -p user.info -t "watchcat" "no tasks defined" + fi +} diff --git a/utils/watchcat/files/uci_defaults_watchcat b/utils/watchcat/files/uci_defaults_watchcat new file mode 100644 index 000000000..49def81eb --- /dev/null +++ b/utils/watchcat/files/uci_defaults_watchcat @@ -0,0 +1,10 @@ +#!/bin/sh + +uci -q show system.@watchcat[0] || { + uci add system watchcat + uci set system.@watchcat[0].period=6h + uci set system.@watchcat[0].mode=ping + uci set system.@watchcat[0].pinghosts=8.8.8.8 + uci set system.@watchcat[0].forcedelay=30 + uci commit +} diff --git a/utils/watchcat/files/watchcat.sh b/utils/watchcat/files/watchcat.sh new file mode 100644 index 000000000..ee9b6bdfa --- /dev/null +++ b/utils/watchcat/files/watchcat.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +mode="$1" + +shutdown_now() { + local forcedelay="$1" + + reboot & + + [ "$forcedelay" -ge 1 ] && { + sleep "$forcedelay" + + echo b > /proc/sysrq-trigger # Will immediately reboot the system without syncing or unmounting your disks. + } +} + +watchcat_allways() { + local period="$1"; local forcedelay="$2" + + sleep "$period" && shutdown_now "$forcedelay" +} + +watchcat_ping() { + local period="$1"; local forcedelay="$2"; local pinghosts="$3"; local pingperiod="$4" + + time_now="$(cat /proc/uptime)" + time_now="${time_now%%.*}" + time_lastcheck="$time_now" + time_lastcheck_withinternet="$time_now" + + while true + do + # account for the time ping took to return. With a ping time of 5s, ping might take more than that, so it is important to avoid even more delay. + time_now="$(cat /proc/uptime)" + time_now="${time_now%%.*}" + time_diff="$((time_now-time_lastcheck))" + + [ "$time_diff" -lt "$pingperiod" ] && { + sleep_time="$((pingperiod-time_diff))" + sleep "$sleep_time" + } + + time_now="$(cat /proc/uptime)" + time_now="${time_now%%.*}" + time_lastcheck="$time_now" + + for host in "$pinghosts" + do + if ping -c 1 "$host" &> /dev/null + then + time_lastcheck_withinternet="$time_now" + else + time_diff="$((time_now-time_lastcheck_withinternet))" + logger -p daemon.info -t "watchcat[$$]" "no internet connectivity for $time_diff seconds. Reseting when reaching $period" + fi + done + + time_diff="$((time_now-time_lastcheck_withinternet))" + [ "$time_diff" -ge "$period" ] && shutdown_now "$forcedelay" + + done +} + + if [ "$mode" = "allways" ] + then + watchcat_allways "$2" "$3" + else + watchcat_ping "$2" "$3" "$4" "$5" + fi