blob: df99cc26d7ddc9f81dc69b8c5bf1914a019d6de8 (
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
|
#!/usr/bin/env bash
set -e
#
# This script can maintain file mirror with minimum lag.
# Yet it will not waste resources by running synchronization many times in short period.
#
# We use "marker files" to detect changes in order to trigger synchronization.
# The synchronization may be postponed to avoid synchronizing incomplete source.
#
# With this mechanism we can run this script at very rapid interval (like every minute)
# with minimal overhead since most of the time we just compare few timestamps.
#
# In this example we use rsync, but you can replace rsync with any other program
# that doesn't need to be as efficient as rsync is since it will run only when necessary.
#
# Extra dependencies:
# apt install --no-install-recommends -y curl jq rsync procmail
#
# Configuration:
# export TARGET_PATH=mirror@10.0.0.127:/var/www/...
# export JENKINS_USER="YOUR_USERNAME"
# export JENKINS_TOKEN="API_TOKEN"
# export SYNC_COMMAND='rsync -azv --progress --delete "$sourcePath" "$targetPath"'
#
sourcePath="/home/sentrium/web/dev.packages.vyos.net/public_html/repositories/"
targetPath="/tmp/repositories/"
targetPath=${TARGET_PATH:-$targetPath}
syncCommand='rsync -azv --progress --delete "$sourcePath" "$targetPath"'
syncCommand=${SYNC_COMMAND:-$syncCommand}
# Jenkins configuration.
jenkinsHost="172.17.17.17:8080"
jenkinsHost=${jenkinsHost:-$JENKINS_HOST}
jenkinsUser="$JENKINS_USER"
jenkinsToken="$JENKINS_TOKEN"
jenkinsUrl="http://${jenkinsUser}:${jenkinsToken}@$jenkinsHost"
# Marker files tells us if the source changed by their modification time.
markerFiles=(
"/home/sentrium/web/dev.packages.vyos.net/public_html/repositories/equuleus/dists/equuleus/Release"
"/home/sentrium/web/dev.packages.vyos.net/public_html/repositories/sagitta/dists/sagitta/Release"
)
# Metadata.
workDir="/var/cache/reprepro-mirror"
lastSyncPath="$workDir/lastSync"
lockPath="$workDir/lock"
# Should be synchronization postponed? Return 1 if yes otherwise 0.
function isSynchronizationPostponed {
jenkinsIdle=$(curl -Ss -g --fail-with-body "$jenkinsUrl/computer/api/json" | jq .computer[0].idle)
exitCode=$?
if [ "$exitCode" -ne 0 ]; then
exit $exitCode
fi
if [ "$jenkinsIdle" == "true" ]; then
return 0
fi
return 1
}
# The logic.
if lockfile -0 -r 0 -! "$lockPath" > /dev/null 2>&1; then
echo "Other synchronization is already in progress."
exit 0
fi
function cleanup {
rm -f "$lockPath"
}
trap '(exit 130)' INT; trap '(exit 143)' TERM; trap cleanup EXIT
function formatDate {
echo $(date -d "@$1" "+%Y-%m-%d %H:%M:%S")
}
if ! [ -f "$workDir" ]; then
mkdir -p "$workDir"
fi
lastSync=0
if [ -f "$lastSyncPath" ]; then
lastSync=$(stat -c %Y "$lastSyncPath")
fi
if [ "$1" == "force" ]; then
lastSync=0
fi
lastChange=0
for markerPath in "${markerFiles[@]}"
do
markerTime=$(stat -c %Y "$markerPath")
if [ "$markerTime" -gt "$lastChange" ]; then
lastChange="$markerTime"
fi
done
if [ "$lastChange" == 0 ]; then
>&2 echo "ERROR: unable to detect modification time of ${markerFiles[@]}!"
exit 1
fi
echo "Last change: $(formatDate "$lastChange")"
echo "last sync: $(formatDate "$lastSync")"
if [ "$lastSync" -ge "$lastChange" ]; then
echo "No synchronization required."
exit 0
fi
echo "Synchronization is required."
if ! isSynchronizationPostponed; then
echo "Operation is postponed, please try later."
exit 0
fi
# Synchronize!
eval "$SYNC_COMMAND"
touch "$lastSyncPath"
echo "Done."
|