-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathmprsyncup
executable file
·277 lines (244 loc) · 9.06 KB
/
mprsyncup
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#!/bin/sh
####
# Script to checkout/update base sources from both master and the current
# release tag (as determined by the base/config/RELEASE_URL file) and a ports
# tree from master, and then export and sync all of them to the
# ${RSYNCROOT} location, wherefrom the rsync modules are fed to the `sync'
# and `selfupdate' routines in port(1). Read the base/portmgr/rsync.repos
# file for more information on both the necessary rsync modules and filesystem
# level paths, which this script bootstraps.
#
# Whatever server uses this script to mirror the MacPorts rsync repositories
# should simply adapt the ${RSYNCROOT} path variable as necessary (keeping it
# in sync with the equally named variable in base/portmgr/rsync.repos) and
# install it on cron/launchd with a suitable periodicity, previously discussed
# with the portmgr@ team ([email protected]). Repositories
# themselves are detailed & served by base/portmgr/rsync.repos, as stated above
# (that is, no manual intervention what-so-ever is needed, other than installing
# this script and adding the repositories detailed in base/portmgr/rsync.repos
# to a local rsyncd.conf file).
#
# Lastly, it is required of every 3rd party mirrors to keep track of this script
# and the base/portmgr/rsync.repos file and always maintain local copies in as
# close sync as possible.
#
#
# Updated by [email protected]
####
set -e
set -x
# Paths we'll work on:
ROOT=/var/tmp/macports
PREFIX=${ROOT}/opt/local
GITROOT=/var/tmp/macports
TBASE=${GITROOT}/trunk/base
RBASE=${GITROOT}/release/base
PORTS=${GITROOT}/release/ports
CONTRIB=${GITROOT}/release/contrib
RSYNCROOT=/rsync/macports
MPTOOLSPREFIX=/opt/local
MPBIN=${MPTOOLSPREFIX}/bin
# Commands we need. For options to be substituted correctly, these must
# not be substituted within double quotes. Thus, there must not be any
# globbing characters, and the command itself must not contain spaces.
GIT="${MPBIN}/git"
RSYNC="${MPBIN}/rsync -q"
RM="/bin/rm"
MKDIR="/bin/mkdir"
MV="${MPBIN}/gmv"
LN="/bin/ln"
TAR="/usr/bin/tar"
OPENSSL="/usr/bin/openssl"
AWK="/usr/bin/awk"
STAT="${MPBIN}/gstat"
GZIP="${MPBIN}/gzip"
BASENAME="/usr/bin/basename"
TCLSH="${PREFIX}/bin/port-tclsh"
PORTINDEX="${PREFIX}/bin/portindex"
PORTINDEX2JSON="${CONTRIB}/portindex2json/portindex2json.tcl"
PATH=${PREFIX}/bin:/bin:/usr/bin:/usr/sbin:${MPBIN}
# Platforms we generate indexes for. This is intentionally split on
# whitespace later.
PLATFORMS="8_powerpc 8_i386 9_powerpc 9_i386 10_i386 11_i386 12_i386 13_i386 14_i386 15_i386 16_i386 17_i386 18_i386 19_i386 20_i386 20_arm 21_i386 21_arm 22_i386 22_arm 23_i386 23_arm 24_i386 24_arm"
# Sources information:
BASEURL=https://github.com/macports/macports-base.git
PORTSURL=https://github.com/macports/macports-ports.git
CONTRIBURL=https://github.com/macports/macports-contrib.git
RELEASE_URL_FILE=config/RELEASE_URL
# private key to use for signing
# XXX set real path
PRIVKEY=""
#
# Functions
#
hardlink() {
SOURCE="$1"
TARGET="$2"
[ -f "${SOURCE}" ] && [ -f "${TARGET}" ] && [ "$(${STAT} -c %i "${SOURCE}")" = "$(${STAT} -c %i "${TARGET}")" ] && return
printf "Hard linking %s to %s\n" "${SOURCE}" "${TARGET}"
TMPTARGET="${ROOT}"/"${TARGET##*/}".$$
${LN} "${SOURCE}" "${TMPTARGET}"
${MV} "${TMPTARGET}" "${TARGET}"
}
sign() {
[ -z "${PRIVKEY}" ] && return
for FILE in "$@"; do
printf "Signing %s\n" "${FILE}"
${OPENSSL} dgst -ripemd160 -sign "${PRIVKEY}" -out "${FILE}.rmd160" "${FILE}"
done
}
#
# Update trunk/base
#
if [ -d "${TBASE}/.git" ]; then
${GIT} -C "${TBASE}" pull -q
${GIT} -C "${TBASE}" fetch --tags
else
${GIT} clone -q "${BASEURL}" "${TBASE}"
fi
${MKDIR} -p "${RSYNCROOT}/trunk/base"
${RSYNC} -aIC --delete "${TBASE}/" "${RSYNCROOT}/trunk/base"
#
# Update release/base
#
read -r RELEASE_URL < "${TBASE}/${RELEASE_URL_FILE}"
if [ -z "${RELEASE_URL}" ]; then
echo "no RELEASE_URL specified in git master, bailing out!"
exit 1
fi
hardlink "${RSYNCROOT}/trunk/base/${RELEASE_URL_FILE}" "${RSYNCROOT}/distfiles/MacPorts/$(${BASENAME} ${RELEASE_URL_FILE})"
RBASE_CHANGED=1
if [ -d "${RBASE}/.git" ]; then
cd "${RBASE}"
${GIT} fetch --tags
RBASE_OLD_REV="$(${GIT} rev-parse HEAD)"
${GIT} checkout -q "$(${BASENAME} ${RELEASE_URL})"
RBASE_NEW_REV="$(${GIT} rev-parse HEAD)"
[ "${RBASE_OLD_REV}" = "${RBASE_NEW_REV}" ] && RBASE_CHANGED=0
else
${GIT} clone -q "${TBASE}" "${RBASE}"
${GIT} -C "${RBASE}" checkout -q "$(${BASENAME} ${RELEASE_URL})"
fi
${MKDIR} -p "${RSYNCROOT}/release/base"
${RSYNC} -aIC --delete "${RBASE}/" "${RSYNCROOT}/release/base"
#
# Update release/ports
#
PORTS_CHANGED=1
if [ -d "${PORTS}/.git" ]; then
cd "${PORTS}"
PORTS_OLD_REV="$(${GIT} rev-parse HEAD)"
${GIT} pull -q
PORTS_NEW_REV="$(${GIT} rev-parse HEAD)"
[ "${PORTS_OLD_REV}" = "${PORTS_NEW_REV}" ] && PORTS_CHANGED=0
else
${GIT} clone -q --depth 1 "${PORTSURL}" "${PORTS}"
PORTS_NEW_REV="$(${GIT} rev-parse HEAD)"
fi
#
# Update release/contrib
#
if [ -d "${CONTRIB}"/.git ]; then
cd "${CONTRIB}"
${GIT} pull -q
else
${GIT} clone -q "${CONTRIBURL}" "${CONTRIB}"
fi
if [ "${RBASE_CHANGED}" -eq 1 ]; then
PORTS_CHANGED=1
(
# build MP in a private location for indexing
cd "${RBASE}"
./configure \
--prefix="${PREFIX}" \
--with-install-group="$(id -gn)" \
--with-install-user="$(id -un)"
make clean
JOBS=1
if [ "$(uname -s)" = "Darwin" ]; then
JOBS="$(sysctl -n hw.activecpu)"
fi
make -j"$JOBS"
make install
make distclean
)
fi
if [ "${PORTS_CHANGED}" -eq 1 ]; then
(
# generate platform-specific indexes
cd "${PORTS}"
# Intentionally split PLATFORMS on whitespace.
for PLATFORM in $PLATFORMS; do
INDEX="PortIndex_darwin_${PLATFORM}"
${PORTINDEX} -p "macosx_${PLATFORM}" -o "${INDEX}" \
| ${AWK} '{ print "Updating " idx ":\t" $0 }' idx="$INDEX" \
| expand -t 40,48,56,64,72,80
done
# generate json for each platform-specific index
for PLATFORM in $PLATFORMS; do
INDEX="PortIndex_darwin_${PLATFORM}"
${TCLSH} "${PORTINDEX2JSON}" "${INDEX}"/PortIndex --info commit="${PORTS_NEW_REV}" > "${INDEX}"/PortIndex.json
done
)
fi
${MKDIR} -p "${RSYNCROOT}/release/ports"
${RSYNC} -aIC --delete "${PORTS}/" "${RSYNCROOT}/release/ports"
#
# Update trunk/dports
#
cd "${RSYNCROOT}"
if [ ! -L trunk/dports ]; then
cd trunk
${RM} -rf dports && ${LN} -s ../release/ports dports
fi
#
# Update release/tarballs
#
# Generate and sign tarballs of base and ports and the PortIndex files.
if [ "${RBASE_CHANGED}" -eq 1 ]; then
${TAR} -C "${RSYNCROOT}"/release/ -cf "${ROOT}"/base.tar base
sign "${ROOT}"/base.tar
fi
if [ "${PORTS_CHANGED}" -eq 1 ]; then
${TAR} --exclude 'PortIndex*/PortIndex.json' -C "${RSYNCROOT}"/release/ -czf "${ROOT}"/ports.tar.gz ports
${TAR} --exclude 'PortIndex*' -C "${RSYNCROOT}"/release/ -cf "${ROOT}"/ports.tar ports
for INDEX_DIR in "${RSYNCROOT}"/release/ports/PortIndex_*; do
INDEX_LINK_DIR="${ROOT}"/"${INDEX_DIR##*/}"
${MKDIR} -p "${INDEX_LINK_DIR}"
hardlink "${INDEX_DIR}"/PortIndex "${INDEX_LINK_DIR}"/PortIndex
done
sign "${ROOT}"/ports.tar "${ROOT}"/PortIndex_*/PortIndex
if [ -x "${GZIP}" ]; then
${GZIP} --best --keep --rsyncable --suffix .gz-rsync "${ROOT}"/ports.tar
sign "${ROOT}"/ports.tar.gz-rsync
fi
fi
# Tarballs used to be a symlink to the real directory tarballs_current.
# Clean up this situation if found. This should only happen once.
[ -L "${RSYNCROOT}"/release/tarballs ] && ${RM} -f "${RSYNCROOT}"/release/tarballs
[ -d "${RSYNCROOT}"/release/tarballs_current ] && ${MV} "${RSYNCROOT}"/release/tarballs_current "${RSYNCROOT}"/release/tarballs
# Replace files on rsync server as quickly as possible.
# This is not atomic but doing it atomically is difficult.
${MKDIR} -p "${RSYNCROOT}"/release/tarballs "${RSYNCROOT}"/distfiles
if [ "${RBASE_CHANGED}" -eq 1 ]; then
${MV} "${ROOT}"/base.tar* "${RSYNCROOT}"/release/tarballs
fi
if [ "${PORTS_CHANGED}" -eq 1 ]; then
${MV} "${ROOT}"/ports.tar.gz "${RSYNCROOT}"/release
hardlink "${RSYNCROOT}"/release/ports.tar.gz "${RSYNCROOT}"/distfiles/ports.tar.gz
if [ -f "${ROOT}"/ports.tar.gz-rsync ]; then
${MV} "${ROOT}"/ports.tar.gz-rsync "${ROOT}"/ports.tar.gz
${MV} "${ROOT}"/ports.tar.gz-rsync.rmd160 "${ROOT}"/ports.tar.gz.rmd160
fi
${MV} "${ROOT}"/ports.tar* "${RSYNCROOT}"/release/tarballs
for INDEX_DIR in "${RSYNCROOT}"/release/ports/PortIndex_*; do
INDEX_LINK_DIR="${RSYNCROOT}/release/tarballs/${INDEX_DIR##*/}"
${MKDIR} -p "${INDEX_LINK_DIR}"
hardlink "${INDEX_DIR}"/PortIndex "${INDEX_LINK_DIR}"/PortIndex
hardlink "${INDEX_DIR}"/PortIndex.quick "${INDEX_LINK_DIR}"/PortIndex.quick
hardlink "${ROOT}"/"${INDEX_DIR##*/}"/PortIndex.rmd160 "${INDEX_LINK_DIR}"/PortIndex.rmd160
done
${RM} -rf "${ROOT}"/PortIndex_*
fi
printf "Done\n"