kiekus/kiekus

80 lines
2.7 KiB
Bash
Executable File

#!/bin/sh
set -e
usage() {
echo "usage: $0 [-h] -c CONFIG | DEST"
}
while getopts hc: opt; do
case "$opt" in
c) cfgfile="$OPTARG";;
h) usage; exit 0;;
?) usage; exit 255;;
esac
done
shift $(($OPTIND - 1))
dest="$1"; shift || true
# read configuration
eval "$(kiekconf \
${cfgfile:+-c "$cfgfile"} \
devtype=blk \
devargs= \
devsuffix= \
destproto=lftp \
dest="$dest" \
statedir=/tmp/kiekstate.$$ \
logfilename="$(basename "$0".log)" \
prehook= \
posthook= \
)"
[ -n "$dest" ] || { echo "kiekus: error: no dest specified in config or arguments"; usage; exit 255; }
iso8601_to_touch() {
printf "%s\n" "$1" | sed -E -e 's/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}).*/\1\2\3\4\5.\6/g'
}
mkdir -p "$statedir"
eval "kiekmon-$devtype $devargs" | while read -r line; do (
read -r rmcmd <<EOF
$(printf "%s\n" "$line" | rp-get rm_command)
EOF
trap 'exit $?' INT TERM ERR
trap 'code=$?; set +e; [ -z "$posthook" ] || eval "$posthook"; eval "$rmcmd"; exit $code' EXIT
{ read -r srcproto; read -r device; } <<EOF
$(printf "%s\n" "$line" | rp-get protocol)
$(printf "%s\n" "$line" | rp-get .)
EOF
[ -z "$prehook" ] || eval "$prehook"
# determine destination directory and last upload timestamp
destdir="$dest/$(date +"%Y%m%d")"
kiekpull-$destproto "$dest" "$logfilename" | kiekpush-file "$statedir" || true
if [ -f "$statedir/$logfilename" ]; then
lastts=$(date -r "$statedir/$logfilename" +"%Y-%m-%dT%H:%I:%S")
else
# best-effort
lastts="$(kieklist-$destproto "$dest" | rp-filter '.= | endswith("/")' | rp-filter '.= != "../"' | rp-sort -r . | rp-get timestamp | head -n 1)"
fi
# get source file listing and filter it
files="$(kieklist-$srcproto "$device$devsuffix" | rp-filter "timestamp= > \"$lastts\"")"
filenames="$(printf "%s\n" "$files" | rp-get . | grep -v -e '^./$' -e '^../$')"
[ -f "$statedir/$logfilename" ] && filenames=$(printf "%s\n" "$filenames" | grep -vF -f "$statedir/$logfilename")
# pull from source and push into destination
if [ -n "$filenames" ]; then
lastts="$(printf "%s\n" "$files" | rp-get timestamp | sort -r | head -n 1)"
kiekpull-$srcproto "$device$devsuffix" $filenames | kiekpush-$destproto "$destdir" | while read -r line; do
printf "%s\n" "$line" >> "$statedir/$logfilename"
done
fi
# update logfile timestamp, upload logfile
if [ -n "$filenames" ] || ! [ -f "$statedir/$logfilename" ]; then
touch -t $(iso8601_to_touch "$lastts") "$statedir/$logfilename"
kiekpull-file "$statedir" "$logfilename" | kiekpush-$destproto "$dest"
fi
) || true; done