Change the container to be a general inotify container.
This commit is contained in:
@@ -14,10 +14,12 @@ RUN set -x \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
VOLUME ["/media", "/config"]
|
VOLUME ["/config", \
|
||||||
|
"/watch1", "/watch2", "/watch3", "/watch4", "/watch5", "/watch6", "/watch7", "/watch8", "/watch9", "/watch10", \
|
||||||
|
"/watch11", "/watch12", "/watch13", "/watch14", "/watch15", "/watch16", "/watch17", "/watch18", "/watch19", "/watch20"]
|
||||||
|
|
||||||
# Add default config file
|
# Add default config file
|
||||||
ADD sagetv-rescan.conf /root/sagetv-rescan.conf
|
ADD sample.conf /root/sample.conf
|
||||||
|
|
||||||
# Add scripts
|
# Add scripts
|
||||||
ADD start.sh /root/start.sh
|
ADD start.sh /root/start.sh
|
||||||
|
|||||||
133
monitor.sh
Executable file
133
monitor.sh
Executable file
@@ -0,0 +1,133 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
CONFIG_FILE=$1
|
||||||
|
NAME=$(basename $CONFIG_FILE .conf)
|
||||||
|
|
||||||
|
function ts {
|
||||||
|
echo [`date '+%b %d %X' $NAME: `]
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "$(ts) Starting monitor for $CONFIG_FILE"
|
||||||
|
|
||||||
|
tr -d '\r' < $CONFIG_FILE > /tmp/$NAME.conf
|
||||||
|
|
||||||
|
. /tmp/$NAME.conf
|
||||||
|
|
||||||
|
if [[ ! -d "$WATCH_DIR" ]]; then
|
||||||
|
echo "$(ts) WATCH_DIR specified in $CONFIG_FILE must be a directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$SETTLE_DURATION" =~ ^([0-9]{1,2}:){0,2}[0-9]{1,2}$ ]]; then
|
||||||
|
echo "$(ts) SETTLE_DURATION must be defined in $CONFIG_FILE as HH:MM:SS or MM:SS or SS."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$MAX_WAIT_TIME" =~ ^([0-9]{1,2}:){0,2}[0-9]{1,2}$ ]]; then
|
||||||
|
echo "$(ts) MAX_WAIT_TIME must be defined in $CONFIG_FILE as HH:MM:SS or MM:SS or SS."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$MIN_PERIOD" =~ ^([0-9]{1,2}:){0,2}[0-9]{1,2}$ ]]; then
|
||||||
|
echo "$(ts) MIN_PERIOD must be defined in $CONFIG_FILE as HH:MM:SS or MM:SS or SS."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$COMMAND" ]; then
|
||||||
|
echo "$(ts) COMMAND must be defined in $CONFIG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
to_seconds () {
|
||||||
|
readarray elements < <(echo $1 | sed 's/:/\n/g' | tac)
|
||||||
|
|
||||||
|
SECONDS=0
|
||||||
|
POWER=1
|
||||||
|
|
||||||
|
for (( i=0 ; i<${#elements[@]}; i++ )) ; do
|
||||||
|
SECONDS=$(( 10#$SECONDS + 10#${elements[i]} * 10#$POWER ))
|
||||||
|
POWER=$(( 10#$POWER * 60 ))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$SECONDS"
|
||||||
|
}
|
||||||
|
|
||||||
|
SETTLE_DURATION=$(to_seconds $SETTLE_DURATION)
|
||||||
|
MAX_WAIT_TIME=$(to_seconds $MAX_WAIT_TIME)
|
||||||
|
MIN_PERIOD=$(to_seconds $MIN_PERIOD)
|
||||||
|
|
||||||
|
pipe=$(mktemp -u)
|
||||||
|
mkfifo $pipe
|
||||||
|
|
||||||
|
echo "$(ts) Waiting for changes..."
|
||||||
|
inotifywait -m -q --format '%e %f' /media >$pipe &
|
||||||
|
|
||||||
|
last_run_time=0
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
if read RECORD
|
||||||
|
then
|
||||||
|
EVENT=$(echo "$RECORD" | cut -d' ' -f 1)
|
||||||
|
FILE=$(echo "$RECORD" | cut -d' ' -f 2-)
|
||||||
|
|
||||||
|
# echo "$RECORD"
|
||||||
|
# echo " EVENT=$EVENT"
|
||||||
|
# echo " FILE=$FILE"
|
||||||
|
|
||||||
|
if [ "$EVENT" == "CREATE,ISDIR" ]
|
||||||
|
then
|
||||||
|
echo "$(ts) Detected new directory: $FILE"
|
||||||
|
elif [ "$EVENT" == "CLOSE_WRITE,CLOSE" ]
|
||||||
|
then
|
||||||
|
echo "$(ts) Detected new file: $FILE"
|
||||||
|
elif [ "$EVENT" == "MOVED_TO" ]
|
||||||
|
then
|
||||||
|
echo "$(ts) Detected moved file: $FILE"
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Monster up as many events as possible, until we hit the either the settle duration, or the max wait threshold.
|
||||||
|
start_time=$(date +"%s")
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
if read -t $SETTLE_DURATION RECORD
|
||||||
|
then
|
||||||
|
end_time=$(date +"%s")
|
||||||
|
|
||||||
|
if [ $(($end_time-$start_time)) -gt $MAX_WAIT_TIME ]
|
||||||
|
then
|
||||||
|
echo "$(ts) Input directory didn't stabilize after $MAX_WAIT_TIME seconds. Triggering command anyway."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$(ts) Input directory stabilized for $SETTLE_DURATION seconds. Triggering command."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
time_since_last_run=$(($(date +"%s")-$last_run_time))
|
||||||
|
if [ $time_since_last_run -lt $MIN_PERIOD ]
|
||||||
|
then
|
||||||
|
remaining_time=$(($MIN_PERIOD-$time_since_last_run))
|
||||||
|
|
||||||
|
echo "$(ts) Waiting an additional $remaining_time seconds before running command"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process events while we wait for $MIN_PERIOD to expire
|
||||||
|
while [ $time_since_last_run -lt $MIN_PERIOD ]
|
||||||
|
do
|
||||||
|
remaining_time=$(($MIN_PERIOD-$time_since_last_run))
|
||||||
|
|
||||||
|
read -t $remaining_time RECORD
|
||||||
|
|
||||||
|
time_since_last_run=$(($(date +"%s")-$last_run_time))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$(ts) Running command"
|
||||||
|
$COMMAND
|
||||||
|
last_run_time=$(date +"%s")
|
||||||
|
fi
|
||||||
|
done <$pipe
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# After seeing the first event, we don't notify SageTV until we've processed any other events that might be happening.
|
|
||||||
# Otherwise we'll end up notifying SageTV 100 times for the case where someone moves 100 files into the media directory.
|
|
||||||
|
|
||||||
# If we don't see any events for $SETTLE_DURATION time, assume that it's safe to notify SageTV. Format is HH:MM:SS,
|
|
||||||
# with HH and MM optional.
|
|
||||||
SETTLE_DURATION=5
|
|
||||||
|
|
||||||
# However, if we see continuous changes for longer than $MAX_WAIT_TIME with no break of $SETTLE_DURATION or more, then
|
|
||||||
# go ahead and notify SageTV. Otherwise we might be waiting forever for the directory to stop changing. Format is HH:MM:SS,
|
|
||||||
# with HH and MM optional.
|
|
||||||
MAX_WAIT_TIME=05:00
|
|
||||||
|
|
||||||
# This is the command to run to notify SageTV. Replace YOUR_SERVER with a proper IP address. This command assumes that
|
|
||||||
# you've installed the plugin called "sagex-services - SageTV Remote API Services".
|
|
||||||
NOTIFY_COMMAND="wget -nv -O /dev/null --auth-no-challenge \
|
|
||||||
http://sage:frey@YOUR_SERVER:8080/sagex/api?c=RunLibraryImportScan&1="
|
|
||||||
28
sample.conf
Normal file
28
sample.conf
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# This is a sample config file, for notifying a SageTV server running on 192.168.1.102 that changes have occurred to the
|
||||||
|
# media import folder. SageTV will then rescan the folder, adding new media to its library.
|
||||||
|
|
||||||
|
# The directory to watch
|
||||||
|
WATCH_DIR=/dir1
|
||||||
|
|
||||||
|
# If we don't see any events for $SETTLE_DURATION time, assume that it's safe to run the command. Format is HH:MM:SS,
|
||||||
|
# with HH and MM optional.
|
||||||
|
SETTLE_DURATION=5
|
||||||
|
|
||||||
|
# However, if we see a stream of changes for longer than $MAX_WAIT_TIME with no break of $SETTLE_DURATION or more, then
|
||||||
|
# go ahead and run the command. Otherwise we might be waiting forever for the directory to stop changing. Format is
|
||||||
|
# HH:MM:SS, with HH and MM optional.
|
||||||
|
MAX_WAIT_TIME=05:00
|
||||||
|
|
||||||
|
# After running the command, wait at least this long before running it again, even if $SETTLE_DURATION time has passed
|
||||||
|
# after change. This controls the maximum frequency of the command.
|
||||||
|
MIN_PERIOD=10:00
|
||||||
|
|
||||||
|
# This is the command to run when a change is detected. If this command runs quickly and triggers some other
|
||||||
|
# long-running task, you want to be sure that rerunning this command while the long-running task is in progress won't
|
||||||
|
# cause any problems. You can also allow this command to wait until the work is done, which will cause it to naturally
|
||||||
|
# limit its run frequency. (But you might still want to set a longer MIN_PERIOD above in order to prevent back-to-back
|
||||||
|
# execution.)
|
||||||
|
|
||||||
|
# In this example, we call a SageTV remote API to trigger a rescan of the imported media library. The command assumes
|
||||||
|
# that we've installed the plugin called "sagex-services - SageTV Remote API Services".
|
||||||
|
COMMAND="wget -nv -O /dev/null --auth-no-challenge http://sage:frey@192.168.1.102:8080/sagex/api?c=RunLibraryImportScan&1="
|
||||||
111
start.sh
111
start.sh
@@ -1,108 +1,57 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
function ts {
|
function ts {
|
||||||
echo [`date '+%b %d %X'`]
|
echo [`date '+%b %d %X' MASTER:`]
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "$(ts) Starting SageTV-Rescan container"
|
echo "$(ts) Starting master controller"
|
||||||
|
|
||||||
# Search for custom config file, if it doesn't exist, copy the default one
|
if [ -f /config/sample.conf ]; then
|
||||||
if [ ! -f /config/sagetv-rescan.conf ]; then
|
echo "$(ts) /config/sample.conf exists. Rename it, check the settings, then rerun the container. Exiting."
|
||||||
echo "$(ts) Creating config file and exiting. Check the settings, then rerun the container."
|
|
||||||
cp /root/sagetv-rescan.conf /config/sagetv-rescan.conf
|
|
||||||
chmod a+w /config/sagetv-rescan.conf
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tr -d '\r' < /config/sagetv-rescan.conf > /tmp/sagetv-rescan.conf
|
readarray -t CONFIG_FILES < <(ls /config/*.conf)
|
||||||
|
|
||||||
. /tmp/sagetv-rescan.conf
|
# If there is no config file copy the default one
|
||||||
|
if [[ "$CONFIG_FILES" == "" ]]
|
||||||
if [[ ! "$SETTLE_DURATION" =~ ^([0-9]{1,2}:){0,2}[0-9]{1,2}$ ]]; then
|
then
|
||||||
echo "$(ts) SETTLE_DURATION must be defined in sagetv-rescan.conf as HH:MM:SS or MM:SS or SS."
|
echo "$(ts) Creating sample config file. Rename it, check the settings, then rerun the container. Exiting."
|
||||||
|
cp /root/sample.conf /config/sample.conf
|
||||||
|
chmod a+w /config/sample.conf
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! "$MAX_WAIT_TIME" =~ ^([0-9]{1,2}:){0,2}[0-9]{1,2}$ ]]; then
|
PIDS=()
|
||||||
echo "$(ts) MAX_WAIT_TIME must be defined in sagetv-rescan.conf as HH:MM:SS or MM:SS or SS."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$NOTIFY_COMMAND" ]; then
|
for $CONFIG_FILE in "${CONFIG_FILES[@]}"
|
||||||
echo "$(ts) NOTIFY_COMMAND must be defined in sagetv-rescan.conf"
|
do
|
||||||
exit 1
|
echo "$(ts) Launching monitor for $CONFIG_FILE"
|
||||||
elif [ "$NOTIFY_COMMAND" = "YOUR_SERVER" ]; then
|
/root/monitor.sh $CONFIG_FILE &
|
||||||
echo "$(ts) Please replace \"YOUR_SERVER\" in sagetv-rescan.conf"
|
PIDS+=($!)
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
to_seconds () {
|
|
||||||
readarray elements < <(echo $1 | sed 's/:/\n/g' | tac)
|
|
||||||
|
|
||||||
SECONDS=0
|
|
||||||
POWER=1
|
|
||||||
|
|
||||||
for (( i=0 ; i<${#elements[@]}; i++ )) ; do
|
|
||||||
SECONDS=$(( 10#$SECONDS + 10#${elements[i]} * 10#$POWER ))
|
|
||||||
POWER=$(( 10#$POWER * 60 ))
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "$SECONDS"
|
# Sleep for a second to allow the monitors to check their config files
|
||||||
}
|
sleep 1
|
||||||
|
|
||||||
SETTLE_DURATION=$(to_seconds $SETTLE_DURATION)
|
|
||||||
MAX_WAIT_TIME=$(to_seconds $MAX_WAIT_TIME)
|
|
||||||
|
|
||||||
pipe=$(mktemp -u)
|
|
||||||
mkfifo $pipe
|
|
||||||
|
|
||||||
echo "$(ts) Waiting for changes..."
|
|
||||||
inotifywait -m -q --format '%e %f' /media >$pipe &
|
|
||||||
|
|
||||||
while true
|
while true
|
||||||
do
|
do
|
||||||
if read RECORD
|
for ((i = 0; i < ${#PIDS[@]}; i++))
|
||||||
|
do
|
||||||
|
if ps -p ${PIDS[$i]} > /dev/null
|
||||||
then
|
then
|
||||||
EVENT=$(echo "$RECORD" | cut -d' ' -f 1)
|
|
||||||
FILE=$(echo "$RECORD" | cut -d' ' -f 2-)
|
|
||||||
|
|
||||||
# echo "$RECORD"
|
|
||||||
# echo " EVENT=$EVENT"
|
|
||||||
# echo " FILE=$FILE"
|
|
||||||
|
|
||||||
if [ "$EVENT" == "CREATE,ISDIR" ]
|
|
||||||
then
|
|
||||||
echo "$(ts) Detected new directory: $FILE"
|
|
||||||
elif [ "$EVENT" == "CLOSE_WRITE,CLOSE" ]
|
|
||||||
then
|
|
||||||
echo "$(ts) Detected new file: $FILE"
|
|
||||||
elif [ "$EVENT" == "MOVED_TO" ]
|
|
||||||
then
|
|
||||||
echo "$(ts) Detected moved file: $FILE"
|
|
||||||
else
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Monster up as many events as possible, until we hit the either the settle duration, or the max wait threshold.
|
echo "$(ts) Monitor for ${CONFIG_FILES[$i]} has died (PID ${PIDS[$i]}). Killing other monitors and exiting."
|
||||||
start_time=$(date +"%s")
|
|
||||||
|
|
||||||
while true
|
for $PID in "${PIDS[@]}"
|
||||||
do
|
do
|
||||||
if read -t $SETTLE_DURATION RECORD
|
kill -9 $PID >/dev/null 2>&1
|
||||||
then
|
|
||||||
end_time=$(date +"%s")
|
|
||||||
|
|
||||||
if [ $(($end_time-$start_time)) -gt $MAX_WAIT_TIME ]
|
|
||||||
then
|
|
||||||
echo "$(ts) Input directory didn't stabilize after $MAX_WAIT_TIME seconds. Notifying SageTV anyway."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$(ts) Input directory stabilized for $SETTLE_DURATION seconds. Notifying SageTV."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
$NOTIFY_COMMAND
|
exit 2
|
||||||
fi
|
done
|
||||||
done <$pipe
|
|
||||||
|
sleep 60
|
||||||
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user