From 69b588f1aba3e6843167e3f06d663511ff7daeaf Mon Sep 17 00:00:00 2001 From: Mason James Date: Wed, 12 Oct 2022 13:05:45 +1300 Subject: [PATCH] Bug 31729: Enable automatic filesystem refresh in Plack to test (on KTD) - install inotify-tools $ sudo apt install inotify-tools - apply patch $ git bz apply 31729 - manually install files and set perms $ cd /kohadevbox/koha $ sudo cp debian/scripts/koha-plack /usr/sbin $ sudo cp debian/scripts/koha-watcher /usr/sbin $ sudo chmod 755 /usr/sbin/koha-plack $ sudo chmod 755 /usr/sbin/koha-watcher - restart, with --watch arg $ sudo koha-plack --restart --watch kohadev - observe koha-watch process $ ps -ef | grep koha-watcher | grep -v grep | wc -l 3 - modify some perl files in watched dir $ echo `date` > /kohadevbox/koha/xxx.pl $ echo `date` > /kohadevbox/koha/xxx.pm - see HUP/inotify messages in log file $ tail -f /var/log/koha/kohadev/plack-watcher.log CLOSE_WRITE,CLOSE event on /kohadevbox/koha/xxx.pl CLOSE_WRITE,CLOSE event on /kohadevbox/koha/xxx.pm koha-plack reloaded - add syntax error to file in watched dir $ echo `date` > /kohadevbox/koha/C4/Context.pm - see HUP/inotify messages in log file $ tail -f /var/log/koha/kohadev/plack-watcher.log CLOSE_WRITE,CLOSE event on /kohadevbox/koha/C4/Context.pm koha-plack failed! sleeping 2 secs koha-plack failed! sleeping 3 secs koha-plack failed! sleeping 4 secs ... koha-plack failed! sleeping 10 secs - fix syntax error in file in watched dir $ git checkout /kohadevbox/koha/C4/Context.pm - see HUP/inotify messages in log file $ tail -f /var/log/koha/kohadev/plack-watcher.log CLOSE_WRITE,CLOSE event on /kohadevbox/koha/C4/Context.pm koha-plack reloaded ok - stop koha-plack $ sudo koha-plack --stop kohadev - observe no koha-watch process $ ps -ef | grep koha-watcher | grep -v grep | wc -l 0 Signed-off-by: Pascal Uphaus Signed-off-by: Thomas Klausner Signed-off-by: Lari Strand --- debian/control.in | 1 + debian/koha-common.install | 1 + debian/scripts/koha-plack | 48 ++++++++++- debian/scripts/koha-watcher | 166 ++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100755 debian/scripts/koha-watcher diff --git a/debian/control.in b/debian/control.in index 0f5c1e491c..9ed3917c74 100644 --- a/debian/control.in +++ b/debian/control.in @@ -23,6 +23,7 @@ Depends: ${misc:Depends}, ${koha:Depends}, daemon, debconf, idzebra-2.0, + inotify-tools, memcached, mysql-client | virtual-mysql-client, perl-doc, diff --git a/debian/koha-common.install b/debian/koha-common.install index 2b8c0f4646..48939e0cf6 100644 --- a/debian/koha-common.install +++ b/debian/koha-common.install @@ -34,6 +34,7 @@ debian/scripts/koha-sitemap usr/sbin debian/scripts/koha-translate usr/sbin debian/scripts/koha-upgrade-schema usr/sbin debian/scripts/koha-upgrade-to-3.4 usr/sbin +debian/scripts/koha-watcher usr/sbin debian/scripts/koha-worker usr/sbin debian/scripts/koha-z3950-responder usr/sbin debian/scripts/koha-zebra usr/sbin diff --git a/debian/scripts/koha-plack b/debian/scripts/koha-plack index 6fe1860268..9006168349 100755 --- a/debian/scripts/koha-plack +++ b/debian/scripts/koha-plack @@ -62,8 +62,12 @@ $scriptname -h|--help --debugger-path Specify the path for the debugger library --quiet|-q Make the script quiet about non existent instance names (useful for calling from another scripts). + --watch|-w Enable automatic reload to starman/plack when a file + is modified (intended for development use) --help|-h Display this help message + --preserve-watcher used internally, doesn't have any user-level use + EOF } @@ -131,6 +135,11 @@ start_plack() # Go back to the original dir cd "$current_dir" + # start watcher + if [ "${watch}" = "yes" ]; then + start_watcher "$instancename" + fi + else log_daemon_msg "Error: Plack already running for ${instancename}" log_end_msg 1 @@ -142,28 +151,36 @@ stop_plack() local instancename=$1 local PIDFILE="/var/run/koha/${instancename}/plack.pid" + local WATCHFILE="/var/run/koha/${instancename}/watcher.pid" + + if [ -f "$WATCHFILE" ] && [ "$preserve_watcher" == "no" ] ; then + stop_watcher "$instancename" + fi if is_plack_running ${instancename}; then log_daemon_msg "Stopping Plack daemon for ${instancename}" - if start-stop-daemon --pidfile ${PIDFILE} --user="${instancename}-koha" --stop --retry=QUIT/30/KILL/5; then + if start-stop-daemon --pidfile "${PIDFILE}" --user="${instancename}-koha" --stop --retry=QUIT/30/KILL/5; then log_end_msg 0 else log_end_msg 1 fi + else log_daemon_msg "Error: Plack not running for ${instancename}" log_end_msg 1 fi } + restart_plack() { local instancename=$1 local PIDFILE="/var/run/koha/${instancename}/plack.pid" + echo restart_plack if is_plack_running ${instancename}; then stop_plack $instancename && start_plack $instancename else @@ -294,6 +311,26 @@ disable_plack() fi } +start_watcher() +{ + local instancename=$1 + local PIDFILE="/var/run/koha/${instancename}/watcher.pid" + + start-stop-daemon --pidfile "${PIDFILE}" --start --background \ + --make-pidfile --startas /usr/sbin/koha-watcher \ + -- -d "$KOHA_HOME" "${instancename}" +} + +stop_watcher() +{ + local instancename="$1" + local PIDFILE="/var/run/koha/${instancename}/watcher.pid" + local PID=$(cat "$PIDFILE") + + start-stop-daemon --ppid "${PID}" --stop -v + rm "$PIDFILE" +} + check_env_and_warn() { local apache_version_ok="no" @@ -331,6 +368,7 @@ _check_and_fix_perms() local instance=$1 local files="/var/log/koha/${instance}/plack.log \ + /var/log/koha/${instance}/plack-watcher.log \ /var/log/koha/${instance}/plack-error.log" for file in ${files} @@ -401,6 +439,8 @@ _do_instance() { STARMAN=$(which starman) op="" quiet="no" +watch="no" +preserve_watcher="no" debug_mode="no" debugger_key="" debugger_location="localhost:9000" @@ -415,6 +455,12 @@ while [ $# -gt 0 ]; do -q|--quiet) quiet="yes" shift ;; + -w|--watch) + watch="yes" + shift ;; + --preserve-watcher) + preserve_watcher="yes" + shift ;; --start) set_action "start" shift ;; diff --git a/debian/scripts/koha-watcher b/debian/scripts/koha-watcher new file mode 100755 index 0000000000..a6c8ef6680 --- /dev/null +++ b/debian/scripts/koha-watcher @@ -0,0 +1,166 @@ +#!/bin/bash +# +# koha-watcher -- restart starman/plack when a file is modified. +# Copyright 2022 Mason James +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +set -e +#set -x + +usage() +{ + local scriptname=$(basename "$0") + + cat <> "$tmpfile" + done; +} + +# restart plack, and check for failure +_restart_plack() { + + if [ ! -e "$pidfile" ] ; then + # if plack is not running, then start with no --watch arg + # (koha-watcher is already running) + koha-plack --start "$instance" + else + # else just HUP it, as its quicker + kill -s HUP $( cat "$pidfile" ) + fi + + # wait 3 long secs for children to start... (yawn) + sleep 3 + + # compare child PIDs after 1 sec; + # if they are different, plack children failed to start + CHILD_PIDS_1=$( pgrep -P $( cat "$pidfile") | tr -d '\n' ) + sleep 1 + CHILD_PIDS_2=$( pgrep -P $( cat "$pidfile") | tr -d '\n' ) + + if [ "$CHILD_PIDS_1" != "$CHILD_PIDS_2" ] ; then + FAIL=1 + else + FAIL=0 + fi +} + +# main reload loop +_reload_loop() { + + # note: it's possible for a user to run 'koha-plack --start' on a + # broken repo. in this situation, we can't know that koha-plack's child + # PIDs are failing to start until we test a reload. so setting FAIL=1 + # on start forces this initial test + FAIL=1 + + # maximum number of seconds to sleep on reload failure. + # 10 secs seems to be a good value, to help reduce system load + MAXSLEEP=10 + + # default number of seconds for sleep loop + SLEEP=1 + + while true ; do + # don't attempt a restart while git is busy + if [ ! -e "${dir}/.git/index.lock" ]; then + + # attempt reload if dir has changed, or previous plack failed + if [ -e "$tmpfile" ] || [ $FAIL -eq 1 ]; then + + # remove tmpfile after restart was triggered + # and add last line of $tmpfile to logfile (#nospam!) + if [ -e "$tmpfile" ]; then + tail -1 "$tmpfile" >> "$logfile" + rm "$tmpfile" + fi + + _restart_plack + + if [ "$FAIL" -eq 1 ] ; then + # stop failing plack from continuously restarting during + # sleep loop, so CPU does not thrash + koha-plack --stop --preserve-watcher "$instance" + + # add 1 secs for every fail, until $MAXSLEEP + if (( SLEEP < MAXSLEEP )) ; then + (( SLEEP++ )) + fi + echo "koha-plack failed! sleeping $SLEEP secs" >> $logfile + else + # plack started ok, so reset sleep loop to 1 sec + SLEEP=1 + FAIL=0 + echo "koha-plack reloaded ok" >> $logfile + fi + fi + + fi # git lock + + sleep $SLEEP + + # useful for debugging $SLEEP value + # echo "sleeping $SLEEP secs" >> $logfile + + done; +} + +# run _reload_loop() in subshell +_reload_loop & +_watch_dir + +exit 0 -- 2.30.2