Skip to content

Commit

Permalink
feat(rrh)!: Upload recordings via SFTP
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Completed recordings will be uploaded via SFTP to an
SSH/SFTP server instead of moving them to a destination directory.
  • Loading branch information
paraenggu committed Jan 9, 2024
1 parent 7ab786c commit aa2d07f
Showing 1 changed file with 55 additions and 23 deletions.
78 changes: 55 additions & 23 deletions bin/raar-record-handler.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,34 @@
# Description:
# This script uses inotifywatch to listen for a close_write event on a given
# watch directory, containing recording files. The script assumes, that a
# recording has finished on such an event and moves the file to the given
# destination directory.
# Before moving the recording file to its final location, the script determines
# recording has finished on such an event and uploads the file using SFTP to
# its final destination.
#
# Before uploading the recording file to its final location, the script determines
# the duration of the recording and adds it to the final file name.
#
# If the archival was successful, the script sends the last successful
# recording timestamp to a Zabbix monitoring system with the help of the
# zabbix_sender tool.
#
# The script is intended to be used together with the rotter recording tool
# and RAAR.
#
# Usage:
# raar-record-handler.sh <WATCH-DIRECTORY> <DESTINATION-DIRECTORY>
# raar-record-handler.sh <WATCH-DIRECTORY> <SFTP-DESTINATION> <SSH-PRIVATE-KEY>
#
# Example:
# raar-record-handler.sh "/var/lib/rotter/raar" \
# "sftp://user-01@archiv.example.com/upload" \
# "/var/lib/rotter/.ssh/my-ssh-key.id_ed25519"
#

# Check if all required external commands are available
for cmd in ffprobe \
inotifywait \
mv \
printf \
sftp \
zabbix_sender
do
command -v "${cmd}" >/dev/null 2>&1 || {
Expand All @@ -59,7 +68,8 @@ do
done

watchDir="$1"
destDir="$2"
sftpDestination="$2"
sshPrivateKey="$3"

if test -z "${watchDir}"; then
echo "Missing watch directory as the first parameter" >&2
Expand All @@ -71,18 +81,34 @@ if ! test -d "${watchDir}"; then
exit 2
fi

if test -z "${destDir}"; then
echo "Missing destination directory as the second parameter" >&2
if test -z "${sftpDestination}"; then
echo "Missing SFTP destination as the second parameter" >&2
exit 1
fi

if test -z "${sshPrivateKey}"; then
echo "Missing SSH private key as the third parameter" >&2
exit 1
fi

if ! test -d "${destDir}"; then
echo "Destination directory does not exist" >&2
if ! test -r "${sshPrivateKey}"; then
echo "SSH private key does not exist or is not readable" >&2
exit 2
fi


# Initial test if the SFTP connection works
if ! sftp -i "${sshPrivateKey}" -b - \
"${sftpDestination}" <<< "pwd" > /dev/null
then
echo "Unable to establish SFTP connection to '${sftpDestination}'" >&2
echo "with SSH private key '${sshPrivateKey}'" >&2
exit 3
fi


echo "Watching for new records in ${watchDir}"
echo "Recordings will be moved to ${destDir}"
echo "Recordings will be uploaded to ${sftpDestination}"

# The minimum size a recording must have to trigger an archival
minFileSize="$(( 20 * 1048576 ))" # 20 MiB
Expand Down Expand Up @@ -137,23 +163,29 @@ do

echo "Setting final recording file name to: ${finalFileName}"

tmpPath="${destDir}/.${finalFileName}.tmp"
destPath="${destDir}/${finalFileName}"

# Move the file to a temporary location in a first step. This prevents the
# archive from importing an unfinished file, in case the source and
# destination are located on different file systems (which leads to a copy
# instead of a move operation)
echo "Moving ${sourcePath} to ${tmpPath}"
if ! mv "${sourcePath}" "${tmpPath}"; then
echo "Moving ${sourcePath} to ${tmpPath} failed" >&2
# Upload the recording with a tempoary filename in a first step.
# This prevents the archive from importing an incomplete file, in
# case the upload is interrupted or still in progress.
# Afterwards rename (move) it to the final file name, which should
# be an atomic opperation as the files are on the same filesystem.
tmpFileName=".${finalFileName}.tmp"
echo "Uploading ${sourcePath} to ${sftpDestination}/${finalFileName}"

printf "%s\n" \
"put ${sourcePath} ${tmpFileName}" \
"chmod 660 ${tmpFileName}" \
"rename ${tmpFileName} ${finalFileName}" | \
sftp -i "${sshPrivateKey}" -b - "${sftpDestination}"

if test $? -ne 0; then
echo "Uploading ${sourcePath} to ${sftpDestination}/${finalFileName} failed" >&2
continue
fi

echo "Moving ${tmpPath} to ${destPath}"
if ! mv "${tmpPath}" "${destPath}"; then
echo "Moving ${tmpPath} to ${destPath} failed" >&2
continue
echo "Removing local recording file '${sourcePath}'"
if ! rm -f "${sourcePath}"; then
echo "Removing local recording file '${sourcePath}' failed" >&2
fi

echo "${eventFileName} successfully archived to ${destPath}"
Expand Down

0 comments on commit aa2d07f

Please sign in to comment.