Jessica James
4 years ago
1 changed files with 199 additions and 0 deletions
@ -0,0 +1,199 @@ |
|||
#!/bin/bash |
|||
|
|||
ENABLE_DEBUG_LOGS=true |
|||
ENABLE_ERROR_LOGS=true |
|||
ENABLE_DISCORD_LOGS=true |
|||
ENABLE_DISCORD_ERROR_LOGS=false |
|||
ENABLE_FILE_LOGS=true |
|||
|
|||
# Source in user profile in case this is a non-interactive thingy; consider separating into a different thing |
|||
source "$HOME/.profile" |
|||
|
|||
if [ -z "${script_locks_path}" ]; then |
|||
echo "ERROR: script_locks_path undefined! You can define this in your user profile." |
|||
exit |
|||
fi |
|||
|
|||
if [ -z "${patches_root_path}" ]; then |
|||
echo "ERROR: patches_root_path undefined! You can define this in your user profile." |
|||
exit |
|||
fi |
|||
|
|||
if [ -z "${patches_data_path}" ]; then |
|||
echo "ERROR: patches_data_path undefined! You can define this in your user profile." |
|||
exit |
|||
fi |
|||
|
|||
if [ -z "$updaterepos_webhook_url" ]; then |
|||
echo "WARNING: updaterepos_webhook_url undefined! Nothing will be logged to discord/webhook." |
|||
ENABLE_DISCORD_LOGS=false |
|||
fi |
|||
|
|||
if [ -z "$error_webhook_url" ]; then |
|||
echo "WARNING: error_webhook_url undefined! LOGERR will not be logged to discord/webhook." |
|||
ENABLE_DISCORD_ERROR_LOGS=false |
|||
fi |
|||
|
|||
mkdir -p "${script_locks_path}" |
|||
lockfile="${script_locks_path}/updaterepos.lock" |
|||
{ |
|||
if ! flock -n 9 |
|||
then |
|||
exit 1 |
|||
fi |
|||
|
|||
#LOG_DIR="${script_logs_path}/updaterepos" |
|||
LOG_DIR="${patches_root_path%/}/logs" |
|||
LOG_FILE="${LOG_DIR%/}/updaterepos.log" |
|||
UPTODATE_FILE="${LOG_DIR}/UpToDate.txt" |
|||
UPDATED_FILE="${LOG_DIR}/Updated.txt" |
|||
UPDATEFAILED_FILE="${LOG_DIR}/UpdateFailed.txt" |
|||
|
|||
# Ensure log and lock dirs exist |
|||
mkdir -p "$LOG_DIR" |
|||
|
|||
# Cleanup previous runs |
|||
rm "$UPTODATE_FILE" "$UPDATED_FILE" "$UPDATEFAILED_FILE" "$LOG_FILE" |
|||
|
|||
set -o pipefail |
|||
|
|||
# Log a message to a webhook URL in Discord format |
|||
# @param $1 URL to log to |
|||
# @param $2 Username to log as |
|||
# @param $3 Message to log |
|||
DISCORD_LOG() { |
|||
WEBHOOK_URL=$1 |
|||
USERNAME=$2 |
|||
shift |
|||
shift |
|||
|
|||
curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"${USERNAME}\", \"embeds\": [ { \"description\": \"${@}\"}]}" "${WEBHOOK_URL}" |
|||
} |
|||
|
|||
# Log message to both console and Discord |
|||
# @param $1 Whether or not to log this message to discord |
|||
# @param $2 Whether or not to log this message to log file |
|||
# $param $3 Message to log |
|||
PRINT_LOG() { |
|||
LOG_TO_DISCORD=$1 |
|||
LOG_TO_FILE=$2 |
|||
shift |
|||
shift |
|||
|
|||
echo "${@}" |
|||
|
|||
if $LOG_TO_DISCORD; then |
|||
DISCORD_LOG "$updaterepos_webhook_url" "Patch" "$@" |
|||
fi |
|||
|
|||
if $LOG_TO_FILE; then |
|||
echo "$@" >> ${LOG_FILE} |
|||
fi |
|||
} |
|||
|
|||
LOGMSG() { |
|||
PRINT_LOG $ENABLE_DISCORD_LOGS $ENABLE_FILE_LOGS "$@" |
|||
} |
|||
|
|||
LOGDBG() { |
|||
if $ENABLE_DEBUG_LOGS; then |
|||
PRINT_LOG false $ENABLE_FILE_LOGS "$@" |
|||
fi |
|||
} |
|||
|
|||
LOGERR() { |
|||
if $ENABLE_ERROR_LOGS; then |
|||
PRINT_LOG false $ENABLE_FILE_LOGS "$@" |
|||
fi |
|||
|
|||
if $ENABLE_DISCORD_ERROR_LOGS; then |
|||
DISCORD_LOG "${error_webhook_url}" "Patch" "$@" |
|||
fi |
|||
} |
|||
|
|||
# Syncs a single mirror |
|||
SYNCMIRRORTHREAD() { |
|||
ADDRESS=$(echo "${2}" | awk -F@ '{print $2}' | awk -F: '{print $1}') |
|||
LOG_FILE=${LOG_FILE}.${ADDRESS}.log |
|||
rm "$LOG_FILE" |
|||
|
|||
RSYNC_OUT=$(rsync -rptDhiz --timeout=30 --delete --delete-excluded ${3} -e "ssh -p ${1}" "${patches_data_path}/" ${2} | tee -a ${LOG_FILE}) |
|||
RSYNC_STATUS=$? |
|||
if [ ${RSYNC_STATUS} -eq 0 ] |
|||
then |
|||
# Success |
|||
if [[ -z "${RSYNC_OUT}" ]] |
|||
then |
|||
# Success and no updates |
|||
LOGDBG "${ADDRESS} is already up to date" |
|||
echo -n "${ADDRESS} " >> "$UPTODATE_FILE" |
|||
else |
|||
# Success and updated |
|||
LOGMSG "Finished sync to: ${ADDRESS}" |
|||
echo -n "${ADDRESS} " >> "$UPDATED_FILE" |
|||
fi |
|||
|
|||
else |
|||
# Failed |
|||
LOGERR "Failed to sync to: ${ADDRESS} (status code ${RSYNC_STATUS})" |
|||
echo -n "${ADDRESS} " >> "$UPDATEFAILED_FILE" |
|||
fi |
|||
} |
|||
|
|||
# Kicks off a full sync to a background thread |
|||
SYNCMIRROR() { |
|||
SYNCMIRRORTHREAD "$@" & |
|||
let "++pidlen" |
|||
pids[${pidlen}]=$! |
|||
} |
|||
|
|||
# Read in and sync each mirror |
|||
mirror_list=$(grep -vE "[[:space:]]*#" "${patches_root_path}/updaterepos.targets") |
|||
|
|||
while read -r line |
|||
do |
|||
# File in format: 'PORT PATH' |
|||
ssh_port=$(echo "$line" | awk '{ print $1 }') |
|||
ssh_path=$(echo "$line" | awk '{ print $2 }') |
|||
exclude_from=$(echo "$line" | awk '{ print $3 }') |
|||
|
|||
if [[ ! -z $exclude_from ]]; then |
|||
exclude_from="--exclude-from=${patches_root_path}/${exclude_from}" |
|||
fi |
|||
|
|||
SYNCMIRROR "$ssh_port" "$ssh_path" "$exclude_from" |
|||
done < <(echo "$mirror_list") |
|||
|
|||
# wait for all pids |
|||
for pid in ${pids[*]}; do |
|||
wait $pid |
|||
done |
|||
|
|||
# Read in outputs |
|||
if [[ -f $UPTODATE_FILE ]]; then |
|||
UPTODATE="$(cat ${UPTODATE_FILE})" |
|||
fi |
|||
|
|||
if [[ -f $UPDATED_FILE ]]; then |
|||
UPDATED="$(cat ${UPDATED_FILE})" |
|||
fi |
|||
|
|||
if [[ -f $UPDATEFAILED_FILE ]]; then |
|||
UPDATEFAILED="$(cat ${UPDATEFAILED_FILE})" |
|||
fi |
|||
|
|||
# We're done syncing; log/notify |
|||
if [[ -z ${UPDATED} ]]; then |
|||
LOGDBG "No patch repos successfully updated" |
|||
|
|||
if [[ ! -z ${UPDATEFAILED} ]]; then |
|||
LOGERR "No patch repos updated; repos failed to update: ${UPDATEFAILED}" |
|||
fi |
|||
|
|||
elif [[ ! -z ${UPDATEFAILED} ]]; then |
|||
LOGERR "The following repos are now up to date: ${UPDATED}; repos failed to update: ${UPDATEFAILED}; repos already up-to-date: ${UPTODATE}" |
|||
else |
|||
LOGMSG "All patch repos are now up to date; repos already up-to-date: ${UPTODATE}" |
|||
fi |
|||
|
|||
} 9>"$lockfile" |
Loading…
Reference in new issue