summaryrefslogtreecommitdiffstats
path: root/mirrorsync
diff options
context:
space:
mode:
Diffstat (limited to 'mirrorsync')
-rw-r--r--mirrorsync147
1 files changed, 147 insertions, 0 deletions
diff --git a/mirrorsync b/mirrorsync
new file mode 100644
index 0000000..4661877
--- /dev/null
+++ b/mirrorsync
@@ -0,0 +1,147 @@
+#!/bin/env bash
+#
+# mirrorsync - Synchronize a local mirror of Remi's RPMS Repository
+# By: Tyler Todd <ttodd@jurassicinnovations.com>
+# Version: 20240805.01
+#
+# The latest version of this script can be found at:
+# https://git.remirepo.net/cgit/tools/helpers.git/plain/mirrorsync
+#
+# Inspired from Rocky Linux Mirror Sync:
+# https://github.com/rocky-linux/rocky-tools
+#
+# Copyright (c) 2021 Rocky Enterprise Software Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+# Please use a mirror geographically close to you for initial sync,
+# or if you are hosting a private mirror (not publicly available).
+#
+# Note that local mirrors may be faster
+# Running rsync from the main "rsync://rpms.remirepo.net" requires
+# the source IPv4 and IPv6 addresses to be allowed by Remi. Please contact
+# Remi at remi@remirepo.net to get the process started.
+#
+# A complete list of mirrors can be found at
+# https://rpms.remirepo.net/
+
+##### TO BE ADAPTED TO YOUR CONFIGURATION #####
+# sync from primary mirror only allowed to official mirrors
+src="rsync://rpms.remirepo.net"
+# Your local path. Change to whatever fits your system.
+dst=/mnt/RepoSync
+# $mirrormodule is also used in syslog output.
+# ${dst}/${mirrormodule}/enterprise MUST exists
+# ${dst}/${mirrormodule}/fedora MUST exists
+mirrormodule="Remi"
+# You can change v to q if you do not want detailed logging
+# You may also add additional excludes if you don't want to provide certain
+# repositories or architectures.
+opts=(-avSH --exclude="*.~tmp~" --delete-delay --delay-updates)
+##### END OF TO BE ADAPTED #####
+
+# Enterprise repo
+src1="${src}/enterprise"
+dst1="${dst}/${mirrormodule}/enterprise"
+# Fedora repo
+src2="${src}/fedora"
+dst2="${dst}/${mirrormodule}/fedora"
+
+datefile="date"
+lockfile="$0.lockfile"
+logfile="$0.log"
+
+# Find rsync in default path
+rsync_run(){
+ if command -v rsync >/dev/null; then
+ command rsync "$@";
+ else
+ command -p rsync "$@";
+ fi;
+}
+
+if [ ! -d ${dst1} ]; then
+ echo "${dst1} directory does not exist"
+ exit 1
+fi
+if [ ! -d ${dst2} ]; then
+ echo "${dst2} directory does not exist"
+ exit 1
+fi
+# Always pull the index.html to ensure the latest. curl/wget would still use same bandiwdth to check if the page changed even
+# if we aren't going to save a new copy
+wget https://rpms.remirepo.net/index.html -O ${dst}/${mirrormodule}/index.html >> "$logfile" 2>&1
+
+# Check if the datefile has changed on upstream mirror
+# and exit cleanly if it is still the same
+
+#Enterprise repo check
+checkresult1=$(rsync_run --no-motd --dry-run --out-format="%n" "${src1}/${datefile}" "${dst1}/${datefile}")
+#Fedora repo check
+checkresult2=$(rsync_run --no-motd --dry-run --out-format="%n" "${src2}/${datefile}" "${dst2}/${datefile}")
+
+# If both dates haven't changed, exit
+if [[ -z "$checkresult1" && -z "$checkresult2" ]]; then
+ printf "%s unchanged. Not updating at %(%c)T\n" "$datefile" -1 >> "$logfile" 2>&1
+ logger -t rsync "Not updating ${mirrormodule}: ${datefile} unchanged."
+ exit 0
+fi
+
+# Check for existing lockfile to avoid multiple simultaneously running syncs
+# If lockfile exists but process is dead continue anyway
+if [[ -e "$lockfile" ]] && ! kill -0 "$(< "$lockfile")" 2>/dev/null; then
+ printf "Warning: lockfile exists but process dead, continuing.\n" >> "$logfile" 2>&1
+ logger -t rsync "Warning: lockfile exists but process dead, continuing with updating ${mirrormodule}."
+ rm -f "$lockfile"
+elif [[ -e "$lockfile" ]]; then
+ printf "Update already in progress at %(%c)T\n" -1 >> "$logfile" 2>&1
+ logger -t rsync "Not updating ${mirrormodule}: already in progress."
+ exit 1
+fi
+
+# The actual syncing part
+printf '%s\n' "$$" > "$lockfile"
+printf "Started update at %(%c)T\n" -1 >> "$logfile" 2>&1
+
+# Sync src1/dst1 if there are changes
+if [[ -n "$checkresult1" ]]; then
+ logger -t rsync "Updating ${mirrormodule} for ${dst1}"
+ if rsync_run "${opts[@]}" "${src1}/" "${dst1}/" >> "$logfile" 2>&1; then
+ logger -t rsync "Succeed updating ${mirrormodule}"
+ else
+ logger -t rsync "Failed updating ${mirrormodule} see ${logfile}"
+ rm -f ${dst1}/${datefile}
+ fi
+fi
+
+# Sync src2/dst2 if there are changes
+if [[ -n "$checkresult2" ]]; then
+ logger -t rsync "Updating ${mirrormodule} for ${dst2}"
+ if rsync_run "${opts[@]}" "${src2}/" "${dst2}/" >> "$logfile" 2>&1; then
+ logger -t rsync "Succeed updating ${mirrormodule}"
+ else
+ logger -t rsync "Failed updating ${mirrormodule} see ${logfile}"
+ rm -f ${dst2}/${datefile}
+ fi
+fi
+
+printf "End: %(%c)T\n" -1 >> "$logfile" 2>&1
+rm -f "$lockfile"