Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r9539 - main/branches/2.1.2/bin
Date: Fri, 28 Mar 2008 10:21:27
Message-Id: E1JfBi7-0006El-V2@stork.gentoo.org
1 Author: zmedico
2 Date: 2008-03-28 10:21:22 +0000 (Fri, 28 Mar 2008)
3 New Revision: 9539
4
5 Modified:
6 main/branches/2.1.2/bin/emerge-webrsync
7 Log:
8 Merge emerge-webrsync from trunk for bugs #210945 and #130039.
9
10
11 Modified: main/branches/2.1.2/bin/emerge-webrsync
12 ===================================================================
13 --- main/branches/2.1.2/bin/emerge-webrsync 2008-03-28 10:18:08 UTC (rev 9538)
14 +++ main/branches/2.1.2/bin/emerge-webrsync 2008-03-28 10:21:22 UTC (rev 9539)
15 @@ -1,14 +1,41 @@
16 #!/bin/bash
17 -# Copyright 1999-2006 Gentoo Foundation
18 +# Copyright 1999-2008 Gentoo Foundation
19 # Distributed under the terms of the GNU General Public License v2
20 # $Id$
21 # Author: Karl Trygve Kalleberg <karltk@g.o>
22 # Rewritten from the old, Perl-based emerge-webrsync script
23 +# Author: Alon Bar-Lev <alon.barlev@×××××.com>
24 +# Major rewrite from Karl's scripts.
25
26 -type portageq > /dev/null || exit $?
27 +# TODO:
28 +# - all output should prob be converted to e* funcs
29 +# - add support for ROOT
30 +
31 +#
32 +# gpg key import
33 +# KEY_ID=0x7DDAD20D
34 +# gpg --homedir /etc/portage/gnupg --keyserver subkeys.pgp.net --recv-keys $KEY_ID
35 +# gpg --homedir /etc/portage/gnupg --edit-key $KEY_ID trust
36 +#
37 +
38 +# Only echo if in verbose mode
39 +vvecho() { [[ ${do_verbose} -eq 1 ]] && echo "$@" ; }
40 +# Only echo if not in verbose mode
41 +nvecho() { [[ ${do_verbose} -eq 0 ]] && echo "$@" ; }
42 +# warning echos
43 +wecho() { echo "${argv0}: warning: $*" 1>&2 ; }
44 +# error echos
45 +eecho() { echo "${argv0}: error: $*" 1>&2 ; }
46 +
47 +argv0=$0
48 +if ! type portageq > /dev/null ; then
49 + eecho "could not find 'portageq'; aborting"
50 + exit 1
51 +fi
52 eval $(portageq envvar -v FEATURES FETCHCOMMAND GENTOO_MIRRORS \
53 - PORTAGE_BIN_PATH PORTAGE_INST_UID PORTAGE_INST_GID PORTAGE_NICENESS \
54 - PORTAGE_TMPDIR PORTDIR PORTAGE_RSYNC_EXTRA_OPTS http_proxy ftp_proxy)
55 + PORTAGE_BIN_PATH PORTAGE_GPG_DIR \
56 + PORTAGE_NICENESS PORTAGE_RSYNC_EXTRA_OPTS PORTAGE_TMPDIR PORTDIR \
57 + http_proxy ftp_proxy)
58 DISTDIR="${PORTAGE_TMPDIR}/emerge-webrsync"
59 export http_proxy ftp_proxy
60
61 @@ -20,147 +47,346 @@
62
63 source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
64
65 -if [ ! -d $DISTDIR ] ; then
66 - mkdir -p $DISTDIR
67 +do_verbose=0
68 +do_debug=0
69 +
70 +if hasq webrsync-gpg ${FEATURES} ; then
71 + WEBSYNC_VERIFY_SIGNATURE=1
72 +else
73 + WEBSYNC_VERIFY_SIGNATURE=0
74 fi
75 +if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 -a -z "${PORTAGE_GPG_DIR}" ]; then
76 + eecho "please set PORTAGE_GPG_DIR in make.conf"
77 + exit 1
78 +fi
79
80 -cd "$DISTDIR"
81 +do_tar() {
82 + local file=$1; shift
83 + local decompressor
84 + case ${file} in
85 + *.lzma) decompressor="lzcat" ;;
86 + *.bz2) decompressor="bzcat" ;;
87 + *.gz) decompressor="zcat" ;;
88 + *) decompressor="cat" ;;
89 + esac
90 + ${decompressor} "${file}" | tar "$@"
91 + _pipestatus=${PIPESTATUS[*]}
92 + [[ ${_pipestatus// /} -eq 0 ]]
93 +}
94
95 -found=0
96 -if [ "$1" == "-v" ] ; then
97 - wgetops=
98 -else
99 - #this sucks. probably better to do 1> /dev/null
100 - #that said, waiting on the refactoring.
101 - if [ "${FETCHCOMMAND/wget}" != "${FETCHCOMMAND}" ]; then
102 - wgetops="-q"
103 - elif [ "${FETCHCOMMAND/curl}" != "${FETCHCOMMAND}" ]; then
104 - wgetops="-s -f"
105 +get_utc_date_in_seconds() {
106 + date -u +"%s"
107 +}
108 +
109 +get_date_part() {
110 + local utc_time_in_secs="$1"
111 + local part="$2"
112 +
113 + if [[ ${USERLAND} == BSD ]] ; then
114 + date -r ${utc_time_in_secs} -u +"${part}"
115 + else
116 + date -d @${utc_time_in_secs} -u +"${part}"
117 fi
118 -fi
119 +}
120
121 -if type -P md5sum > /dev/null; then
122 - md5_com='md5sum -c "${FILE}.md5sum"'
123 -elif type -P md5 > /dev/null; then
124 - md5_com='[ "$(md5 -q ${FILE})" == "$(cut -d \ -f 1 ${FILE}.md5sum)" ]'
125 -else
126 - echo "warning, unable to do md5 verification of the snapshot!"
127 - echo "no suitable md5/md5sum binary was found!"
128 - md5_com='true'
129 -fi
130 +get_utc_second_from_string() {
131 + local s="$1"
132 + date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s"
133 +}
134
135 +get_portage_timestamp() {
136 + local portage_current_timestamp=0
137 +
138 + if [ -f "${PORTDIR}/metadata/timestamp.x" ]; then
139 + portage_current_timestamp=$(cut -f 1 -d " " "${PORTDIR}/metadata/timestamp.x" )
140 + fi
141 +
142 + echo "${portage_current_timestamp}"
143 +}
144 +
145 +fetch_file() {
146 + local URI="$1"
147 + local FILE="$2"
148 + local opts
149 +
150 + if [ "${FETCHCOMMAND/wget/}" != "${FETCHCOMMAND}" ]; then
151 + opts="--continue $(nvecho -q)"
152 + elif [ "${FETCHCOMMAND/curl/}" != "${FETCHCOMMAND}" ]; then
153 + opts="--continue-at - $(nvecho -s -f)"
154 + else
155 + rm -f "${FILE}"
156 + fi
157 +
158 + vecho "Fetching file ${FILE} ..."
159 + # already set DISTDIR=
160 + eval "${FETCHCOMMAND}" ${opts}
161 + [ -s "${FILE}" ]
162 +}
163 +
164 +check_file_digest() {
165 + local digest="$1"
166 + local file="$2"
167 + local r=1
168 +
169 + vecho "Checking digest ..."
170 +
171 + if type -P md5sum > /dev/null; then
172 + md5sum -c $digest && r=0
173 + elif type -P md5 > /dev/null; then
174 + [ "$(md5 -q $file)" == "$(cut -d \ -f 1 \"$digest\")" ] && r=0
175 + else
176 + eecho "cannot check digest: no suitable md5/md5sum binaries found"
177 + fi
178 +
179 + return "${r}"
180 +}
181 +
182 +check_file_signature() {
183 + local signature="$1"
184 + local file="$2"
185 + local r=1
186 +
187 + if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 ]; then
188 +
189 + vecho "Checking signature ..."
190 +
191 + if type -p gpg > /dev/null; then
192 + gpg --homedir "${PORTAGE_GPG_DIR}" --verify "$signature" "$file" && r=0
193 + else
194 + eecho "cannot check signature: gpg binary not found"
195 + fi
196 + else
197 + r=0
198 + fi
199 +
200 + return "${r}"
201 +}
202 +
203 +get_snapshot_timestamp() {
204 + local file="$1"
205 +
206 + do_tar "${file}" --to-stdout -xf - portage/metadata/timestamp.x | cut -f 1 -d " "
207 +}
208 +
209 sync_local() {
210 - echo Syncing local tree...
211 - if type -P tarsync &> /dev/null; then
212 - # tarsync doesn't take numeric uid/gid so we need to convert them.
213 - local inst_user="$(python -c "import pwd; print pwd.getpwuid(int('${PORTAGE_INST_UID:-0}'))[0]")"
214 - local inst_group="$(python -c "import grp; print grp.getgrgid(int('${PORTAGE_INST_GID:-0}'))[0]")"
215 - if ! tarsync "${FILE}" "${PORTDIR}" -v -s 1 -o ${inst_user} -g ${inst_group} -e /distfiles -e /packages -e /local; then
216 - echo "tarsync failed; tarball is corrupt?"
217 - exit 1;
218 + local file="$1"
219 +
220 + vecho "Syncing local tree ..."
221 +
222 + # tarsync-0.2.1 doesn't seem to support lzma compression.
223 + if [ "${file##*.}" != "lzma" ] && type -P tarsync &> /dev/null; then
224 + if ! tarsync $(vvecho -v) -s 1 -o portage -g portage -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then
225 + eecho "tarsync failed; tarball is corrupt? (${file})"
226 + return 1
227 fi
228 - rm "${FILE}"
229 else
230 - if ! tar jxf $FILE; then
231 - echo "Tar failed to extract the image. Please review the output."
232 - echo "Executed command: tar jxf $FILE"
233 - exit 1
234 + if ! do_tar "${file}" xf -; then
235 + eecho "tar failed to extract the image. tarball is corrupt? (${file})"
236 + rm -fr portage
237 + return 1
238 fi
239 - rm -f $FILE
240 - # Make sure user and group file ownership is ${PORTAGE_INST_UID}:${PORTAGE_INST_GID}
241 - chown -R ${PORTAGE_INST_UID:-0}:${PORTAGE_INST_GID:-0} portage
242 +
243 + # Free disk space
244 + rm -f "${file}"
245 +
246 + chown portage:portage portage &> /dev/null && \
247 + chown -R portage:portage portage
248 cd portage
249 rsync -av --progress --stats --delete --delete-after \
250 - --exclude='/distfiles' --exclude='/packages' \
251 - --exclude='/local' ${PORTAGE_RSYNC_EXTRA_OPTS} . "${PORTDIR%%/}"
252 + --exclude='/distfiles' --exclude='/packages' \
253 + --exclude='/local' ${PORTAGE_RSYNC_EXTRA_OPTS} . "${PORTDIR%%/}"
254 cd ..
255 - echo "cleaning up"
256 - rm -rf portage
257 +
258 + vecho "Cleaning up ..."
259 + rm -fr portage
260 fi
261 +
262 if hasq metadata-transfer ${FEATURES} ; then
263 - echo "transferring metadata/cache"
264 + vecho "Updating cache ..."
265 emerge --metadata
266 fi
267 [ -x /etc/portage/bin/post_sync ] && /etc/portage/bin/post_sync
268 + return 0
269 }
270
271 -echo "Fetching most recent snapshot"
272 +do_snapshot() {
273 + local ignore_timestamp="$1"
274 + local date="$2"
275
276 -declare -i attempts=0
277 -while (( $attempts < 40 )) ; do
278 - attempts=$(( attempts + 1 ))
279 + local r=1
280
281 - # The snapshot for a given day is generated at 01:45 UTC on the following
282 - # day, so the current day's snapshot (going by UTC time) hasn't been
283 - # generated yet. Therefore, always start by looking for the previous day's
284 - # snapshot (for attempts=1, subtract 1 day from the current UTC time).
285 - daysbefore=$(expr $(date -u +"%s") - 86400 \* ${attempts})
286 - if [ "${USERLAND}" = "BSD" ]; then
287 - DATE_ARGS="-r ${daysbefore}"
288 - else
289 - DATE_ARGS="-d @${daysbefore}"
290 + local base_file="portage-${date}.tar"
291 +
292 + local have_files=0
293 + local mirror
294 +
295 + local compressions=""
296 + type lzcat > /dev/null && compressions="${compressions} lzma"
297 + type bzcat > /dev/null && compressions="${compressions} bz2"
298 + type zcat > /dev/null && compressions="${compressions} gz"
299 + if [[ -z ${compressions} ]] ; then
300 + eecho "unable to locate any decompressors (lzcat or bzcat or zcat)"
301 + exit 1
302 fi
303 - day=$(date ${DATE_ARGS} -u +"%d")
304 - month=$(date ${DATE_ARGS} -u +"%m")
305 - year=$(date ${DATE_ARGS} -u +"%Y")
306
307 - FILE_ORIG="portage-${year}${month}${day}.tar.bz2"
308 + for mirror in ${GENTOO_MIRRORS} ; do
309
310 - echo "Attempting to fetch file dated: ${year}${month}${day}"
311 -
312 - got_md5=0
313 + vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
314
315 - if [ ! -e "${FILE_ORIG}.md5sum" ]; then
316 - FILE="${FILE_ORIG}.md5sum"
317 - for i in $GENTOO_MIRRORS ; do
318 - URI="${i}/snapshots/${FILE}"
319 - if (eval "$FETCHCOMMAND $wgetops") && [ -s "${FILE}" ]; then
320 - got_md5=1
321 + for compression in ${compressions} ; do
322 + local file="portage-${date}.tar.${compression}"
323 + local digest="${file}.md5sum"
324 + local signature="${file}.gpgsig"
325 +
326 + if [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] ; then
327 + check_file_digest "${digest}" "${file}" && \
328 + check_file_signature "${signature}" "${file}" && \
329 + have_files=1
330 + fi
331 +
332 + if [ ${have_files} -eq 0 ] ; then
333 + fetch_file "${mirror}/snapshots/${digest}" "${digest}" && \
334 + fetch_file "${mirror}/snapshots/${signature}" "${signature}" && \
335 + fetch_file "${mirror}/snapshots/${file}" "${file}" && \
336 + check_file_digest "${digest}" "${file}" && \
337 + check_file_signature "${signature}" "${file}" && \
338 + have_files=1
339 + fi
340 +
341 + #
342 + # If timestamp is invalid
343 + # we want to try and retrieve
344 + # from a different mirror
345 + #
346 + if [ ${have_files} -eq 1 ]; then
347 +
348 + vecho "Getting snapshot timetasmp ..."
349 + local snapshot_timestamp=$(get_snapshot_timestamp "${file}")
350 +
351 + if [ ${ignore_timestamp} == 0 ]; then
352 + if [ ${snapshot_timestamp} -lt $(get_portage_timestamp) ]; then
353 + wecho "portage is newer than snapshot"
354 + have_files=0
355 + fi
356 + else
357 + local utc_seconds=$(get_utc_second_from_string "${date}")
358 +
359 + #
360 + # Check that this snapshot
361 + # is what it claims to be ...
362 + #
363 + if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \
364 + [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then
365 +
366 + wecho "snapshot timestamp is not in acceptable period"
367 + have_files=0
368 + fi
369 + fi
370 + fi
371 +
372 + if [ ${have_files} -eq 1 ]; then
373 break
374 + else
375 + #
376 + # Remove files and use a different mirror
377 + #
378 + rm -f "${file}" "${digest}" "${signature}"
379 fi
380 done
381 +
382 + [ ${have_files} -eq 1 ] && break
383 + done
384 +
385 + if [ ${have_files} -eq 1 ]; then
386 + sync_local "${file}" && r=0
387 else
388 - got_md5=1
389 + vecho "${date} snapshot was not found"
390 fi
391 - FILE="${FILE_ORIG}"
392 +
393 + rm -f "${file}" "${digest}" "${signature}"
394 + return "${r}"
395 +}
396
397 - if (($got_md5 == 0 )); then
398 - echo " --- No md5sum present on the mirror. (Not yet available.)"
399 - continue
400 - elif [ -s "${FILE}" ]; then
401 - if eval "$md5_com"; then
402 - echo " === snapshot $FILE is correct, using it"
403 - sync_local
404 - echo
405 - echo " === Snapshot has been sync'd"
406 - echo
407 - exit 0
408 - else
409 - rm $FILE
410 +do_latest_snapshot() {
411 + local attempts=-1
412 + local r=1
413 +
414 + vecho "Fetching most recent snapshot ..."
415 +
416 + while (( ${attempts} < 40 )) ; do
417 + local day
418 + local month
419 + local year
420 + local seconds
421 +
422 + attempts=$(( ${attempts} + 1 ))
423 +
424 + utc_attempt=$(expr $(get_utc_date_in_seconds) - 86400 \* ${attempts})
425 +
426 + day=$(get_date_part ${utc_attempt} "%d")
427 + month=$(get_date_part ${utc_attempt} "%m")
428 + year=$(get_date_part ${utc_attempt} "%Y")
429 + utc_midnight=$(get_date_part $(expr ${utc_attempt} - ${utc_attempt} % 86400) "%s")
430 +
431 + if [ ${utc_midnight} -lt $(($(get_portage_timestamp)-86400)) ]; then
432 + wecho "portage content is newer than available snapshots (use --revert option to overide)"
433 + r=0
434 + break
435 fi
436 +
437 + if do_snapshot 0 "${year}${month}${day}"; then
438 + r=0
439 + break;
440 + fi
441 + done
442 +
443 + return "${r}"
444 +}
445 +
446 +usage() {
447 + cat <<-EOF
448 + Usage: $0 [options]
449 +
450 + Options:
451 + --revert=yyyymmdd Revert to snapshot
452 + -q, --quiet Only output errors
453 + -v, --verbose Enable verbose output
454 + -x, --debug Enable debug output
455 + -h, --help This help screen (duh!)
456 + EOF
457 + if [[ -n $* ]] ; then
458 + printf "\nError: %s\n" "$*" 1>&2
459 + exit 1
460 + else
461 + exit 0
462 fi
463 +}
464 +
465 +main() {
466 + local arg
467 + local revert_date
468
469 - for i in $GENTOO_MIRRORS ; do
470 - URI="${i}/snapshots/$FILE"
471 - rm -f "$FILE"
472 - if (eval "$FETCHCOMMAND $wgetops") && [ -s "$FILE" ]; then
473 - if ! eval "$md5_com"; then
474 - echo "md5 failed on $FILE"
475 - rm ${FILE}
476 - continue
477 - else
478 - sync_local
479 - echo
480 - echo " *** Completed websync, please now perform a normal rsync if possible."
481 - echo " Update is current as of the of YYYYMMDD: ${year}${month}${day}"
482 - echo
483 - exit 0
484 - fi
485 - fi
486 + [ ! -d "${DISTDIR}" ] && mkdir -p "${DISTDIR}"
487 + cd "${DISTDIR}"
488
489 + for arg in "$@" ; do
490 + local v=${arg#*=}
491 + case ${arg} in
492 + -h|--help) usage ;;
493 + -q|--quiet) PORTAGE_QUIET=1 ;;
494 + -v|--verbose) do_verbose=1 ;;
495 + -x|--debug) do_debug=1 ;;
496 + --revert=*) revert_date=${v} ;;
497 + *) usage "Invalid option '${arg}'" ;;
498 + esac
499 done
500 -done
501 + [[ ${do_debug} -eq 1 ]] && set -x
502
503 -rm -rf portage
504 + if [[ -n ${revert_date} ]] ; then
505 + do_snapshot 1 "${revert_date}"
506 + else
507 + do_latest_snapshot
508 + fi
509 +}
510
511 -exit 1
512 +main "$@"
513
514 --
515 gentoo-commits@l.g.o mailing list