summaryrefslogtreecommitdiffstats
path: root/mirrorsync
blob: 3b698f210074e5894535a301b1ddb4e875bc1f9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/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.
#

# Find rsync in default path
rsync_run(){
        if command -v rsync >/dev/null; then
                command rsync "$@";
        else
                command -p rsync "$@";
        fi;
}

# 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)

# 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/

# Enterprise repo source
src1="rsync://rpms.remirepo.net/enterprise/"
# Fedora repo source
src2="rsync://rpms.remirepo.net/fedora/"

# Your local path. Change to whatever fits your system.
# $mirrormodule is also used in syslog output.
mirrormodule="Remi"
dst1="/mnt/RepoSync/${mirrormodule}/enterprise"
dst2="/mnt/RepoSync/${mirrormodule}/fedora"

datefile="date"
lockfile="$0.lockfile"
logfile="$0.log"

# 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 /mnt/RepoSync/${mirrormodule}/index.html

# 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
logger -t rsync "Updating ${mirrormodule}"


# Sync src1/dst1 if there are changes
if [[ -n "$checkresult1" ]]; then
    rsync_run "${opts[@]}" "${src1}/" "${dst1}/" >> "$logfile" 2>&1
fi

# Sync src2/dst2 if there are changes
if [[ -n "$checkresult2" ]]; then
    rsync_run "${opts[@]}" "${src2}/" "${dst2}/" >> "$logfile" 2>&1
fi

logger -t rsync "Finished updating ${mirrormodule}"
printf "End: %(%c)T\n" -1 >> "$logfile" 2>&1
rm -f "$lockfile"