[79093] trunk/base
jmr at macports.org
jmr at macports.org
Wed Jun 1 21:32:02 PDT 2011
Revision: 79093
http://trac.macports.org/changeset/79093
Author: jmr at macports.org
Date: 2011-06-01 21:32:01 -0700 (Wed, 01 Jun 2011)
Log Message:
-----------
add support for sync and selfupdate via rsync of tarballs with detached signatures (work in progress)
Modified Paths:
--------------
trunk/base/portmgr/jobs/mprsyncup
trunk/base/src/macports1.0/macports.tcl
trunk/base/src/macports1.0/macports_autoconf.tcl.in
Modified: trunk/base/portmgr/jobs/mprsyncup
===================================================================
--- trunk/base/portmgr/jobs/mprsyncup 2011-06-02 04:25:28 UTC (rev 79092)
+++ trunk/base/portmgr/jobs/mprsyncup 2011-06-02 04:32:01 UTC (rev 79093)
@@ -38,6 +38,8 @@
RM="/bin/rm"
MKDIR="/bin/mkdir"
LN="/bin/ln"
+TAR="/usr/bin/tar"
+OPENSSL="/usr/bin/openssl"
# Paths we'll work on:
ROOT=/var/tmp/macports
@@ -65,6 +67,10 @@
SVNURL=https://svn.macports.org/repository/macports
RELEASE_URL_FILE=config/RELEASE_URL
+# private key to use for signing
+# XXX set real path
+PRIVKEY=""
+
# cleanup up the working copy if it is locked
if [ -f ${TBASE}/.svn/lock ]; then
${CLEANUP} ${TBASE}
@@ -145,3 +151,23 @@
cd trunk
${RM} -rf dports && ${LN} -s ../release/ports dports
fi
+
+# generate and sign tarballs of base and dports
+# the signature always needs to match, so we try to make this look atomic to
+# clients by switching a symlink target
+
+TAR_CURDIR=${RSYNCROOT}/release/tarballs_current
+${MKDIR} -p ${TAR_CURDIR}
+cp -pR ${TAR_CURDIR} ${RSYNCROOT}/release/tarballs_old
+${LN} -sf tarballs_old ${RSYNCROOT}/release/tarballs
+${TAR} -cf ${TAR_CURDIR}/base.tar ${RSYNCROOT}/release/base
+${TAR} -cf ${TAR_CURDIR}/ports.tar --exclude 'PortIndex*' ${RSYNCROOT}/release/ports
+cp -pR ${RSYNCROOT}/release/ports/PortIndex_* ${TAR_CURDIR}
+# XXX needs PRIVKEY to be set above
+#${OPENSSL} dgst -ripemd160 -sign ${PRIVKEY} -out ${TAR_CURDIR}/base.tar.rmd160 ${TAR_CURDIR}/base.tar
+#${OPENSSL} dgst -ripemd160 -sign ${PRIVKEY} -out ${TAR_CURDIR}/ports.tar.rmd160 ${TAR_CURDIR}/ports.tar
+for index in ${TAR_CURDIR}/PortIndex_*/PortIndex; do
+ #${OPENSSL} dgst -ripemd160 -sign ${PRIVKEY} -out ${index}.rmd160 ${index}
+done
+${LN} -sf tarballs_current ${RSYNCROOT}/release/tarballs
+${RM} -rf ${RSYNCROOT}/release/tarballs_old
Modified: trunk/base/src/macports1.0/macports.tcl
===================================================================
--- trunk/base/src/macports1.0/macports.tcl 2011-06-02 04:25:28 UTC (rev 79092)
+++ trunk/base/src/macports1.0/macports.tcl 2011-06-02 04:32:01 UTC (rev 79093)
@@ -1860,7 +1860,7 @@
upvar $filename myfilename
upvar $extension myextension
- if {[regexp {^(?:https?|ftp)://.+/(.+\.(tar\.gz|tar\.bz2))$} $url -> f e]} {
+ if {[regexp {^(?:https?|ftp|rsync)://.+/(.+\.(tar\.gz|tar\.bz2|tar))$} $url -> f e]} {
set myfilename $f
set myextension $e
@@ -1904,7 +1904,7 @@
proc mportsync {{optionslist {}}} {
global macports::sources macports::portdbpath macports::rsync_options tcl_platform
global macports::portverbose
- global macports::autoconf::rsync_path
+ global macports::autoconf::rsync_path macports::autoconf::tar_path macports::autoconf::openssl_path
array set options $optionslist
set numfailed 0
@@ -1956,13 +1956,21 @@
# Where to, boss?
set indexfile [macports::getindex $source]
set destdir [file dirname $indexfile]
+ set is_tarball [_source_is_snapshot $source]
file mkdir $destdir
- # Keep rsync happy with a trailing slash
- if {[string index $source end] != "/"} {
- append source "/"
+
+ if {$is_tarball} {
+ set exclude_option ""
+ # need to do a few things before replacing the ports tree in this case
+ set destdir [file dirname $destdir]
+ } else {
+ # Keep rsync happy with a trailing slash
+ if {[string index $source end] != "/"} {
+ append source "/"
+ }
+ # don't sync PortIndex yet; we grab the platform specific one afterwards
+ set exclude_option "'--exclude=/PortIndex*'"
}
- # don't sync PortIndex yet; we grab the platform specific one afterwards
- set exclude_option "'--exclude=/PortIndex*'"
# Do rsync fetch
set rsync_commandline "${macports::autoconf::rsync_path} ${rsync_options} ${exclude_option} ${source} ${destdir}"
ui_debug $rsync_commandline
@@ -1971,15 +1979,97 @@
incr numfailed
continue
}
+
+ if {$is_tarball} {
+ # verify signature for tarball
+ global macports::archivefetch_pubkeys
+ set rsync_commandline "${macports::autoconf::rsync_path} ${rsync_options} ${exclude_option} ${source}.rmd160 ${destdir}"
+ ui_debug $rsync_commandline
+ if {[catch {system $rsync_commandline}]} {
+ ui_error "Synchronization of the ports tree signature failed doing rsync"
+ incr numfailed
+ continue
+ }
+ set tarball "${destdir}/[file tail $source]"
+ set signature "${tarball}.rmd160"
+ set openssl [findBinary openssl $macports::autoconf::openssl_path]
+ set verified 0
+ foreach pubkey ${macports::archivefetch_pubkeys} {
+ if {![catch {exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature $tarball} result]} {
+ set verified 1
+ ui_debug "successful verification with key $pubkey"
+ break
+ } else {
+ ui_debug "failed verification with key $pubkey"
+ ui_debug "openssl output: $result"
+ }
+ }
+ if {!$verified} {
+ ui_error "Failed to verify signature for ports tree!"
+ incr numfailed
+ continue
+ }
+
+ # extract tarball and move into place
+ set tar [macports::findBinary tar $macports::autoconf::tar_path]
+ file mkdir ${destdir}/tmp
+ set tar_cmd "$tar -C ${destdir}/tmp -xf ${tarball}"
+ ui_debug $tar_cmd
+ if {[catch {system $tar_cmd}]} {
+ ui_error "Failed to extract ports tree from tarball!"
+ incr numfailed
+ continue
+ }
+ # save the local PortIndex data
+ if {[file isfile $indexfile]} {
+ file rename -force $indexfile ${destdir}/tmp/ports/
+ if {[file isfile ${indexfile}.quick]} {
+ file rename -force ${indexfile}.quick ${destdir}/tmp/ports/
+ }
+ }
+ file delete -force ${destdir}/ports
+ file rename ${destdir}/tmp/ports ${destdir}/ports
+ file delete -force ${destdir}/tmp
+ }
+
# now sync the index if the local file is missing or older than a day
if {![file isfile $indexfile] || [expr [clock seconds] - [file mtime $indexfile]] > 86400} {
+ if {$is_tarball} {
+ # chop ports.tar off the end
+ set source [string range $source 0 end-[string length [file tail $source]]]
+ }
set remote_indexfile "${source}PortIndex_${macports::os_platform}_${macports::os_major}_${macports::os_arch}/PortIndex"
set rsync_commandline "${macports::autoconf::rsync_path} ${rsync_options} $remote_indexfile ${destdir}"
ui_debug $rsync_commandline
if {[catch {system $rsync_commandline}]} {
ui_debug "Synchronization of the PortIndex failed doing rsync"
} else {
- mports_generate_quickindex $indexfile
+ set ok 1
+ if {$is_tarball} {
+ set ok 0
+ # verify signature for PortIndex
+ set rsync_commandline "${macports::autoconf::rsync_path} ${rsync_options} ${remote_indexfile}.rmd160 ${destdir}"
+ ui_debug $rsync_commandline
+ if {![catch {system $rsync_commandline}]} {
+ foreach pubkey ${macports::archivefetch_pubkeys} {
+ if {![catch {exec $openssl dgst -ripemd160 -verify $pubkey -signature ${destdir}/PortIndex.rmd160 ${destdir}/PortIndex} result]} {
+ set ok 1
+ ui_debug "successful verification with key $pubkey"
+ break
+ } else {
+ ui_debug "failed verification with key $pubkey"
+ ui_debug "openssl output: $result"
+ }
+ }
+ if {$ok} {
+ # move PortIndex into place
+ file rename -force ${destdir}/PortIndex ${destdir}/ports/
+ }
+ }
+ }
+ if {$ok} {
+ mports_generate_quickindex $indexfile
+ }
}
}
if {[catch {system "chmod -R a+r \"$destdir\""}]} {
@@ -2786,6 +2876,7 @@
proc macports::selfupdate {{optionslist {}} {updatestatusvar ""}} {
global macports::prefix macports::portdbpath macports::libpath macports::rsync_server macports::rsync_dir macports::rsync_options
global macports::autoconf::macports_version macports::autoconf::rsync_path tcl_platform
+ global macports::autoconf::openssl_path macports::autoconf::tar_path
array set options $optionslist
# variable that indicates whether we actually updated base
@@ -2802,8 +2893,18 @@
}
}
+ # are we syncing a tarball? (implies detached signature)
+ set is_tarball 0
+ if {[string range ${rsync_dir} end-3 end] == ".tar"} {
+ set is_tarball 1
+ set mp_source_path [file join $portdbpath sources ${rsync_server} [file dirname ${rsync_dir}]]
+ } else {
+ if {[string index $rsync_dir end] != "/"} {
+ append rsync_dir "/"
+ }
+ set mp_source_path [file join $portdbpath sources ${rsync_server} ${rsync_dir}]
+ }
# create the path to the to be downloaded sources if it doesn't exist
- set mp_source_path [file join $portdbpath sources ${rsync_server} ${rsync_dir}/]
if {![file exists $mp_source_path]} {
file mkdir $mp_source_path
}
@@ -2815,6 +2916,45 @@
return -code error "Error synchronizing MacPorts sources: $result"
}
+ if {$is_tarball} {
+ # verify signature for tarball
+ global macports::archivefetch_pubkeys
+ if { [catch { system "$rsync_path $rsync_options rsync://${rsync_server}/${rsync_dir}.rmd160 $mp_source_path" } result ] } {
+ return -code error "Error synchronizing MacPorts source signature: $result"
+ }
+ set openssl [findBinary openssl $macports::autoconf::openssl_path]
+ set tarball "${mp_source_path}/[file tail $rsync_dir]"
+ set signature "${tarball}.rmd160"
+ set verified 0
+ foreach pubkey ${macports::archivefetch_pubkeys} {
+ if {![catch {exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature $tarball} result]} {
+ set verified 1
+ ui_debug "successful verification with key $pubkey"
+ break
+ } else {
+ ui_debug "failed verification with key $pubkey"
+ ui_debug "openssl output: $result"
+ }
+ }
+ if {!$verified} {
+ return -code error "Failed to verify signature for MacPorts source!"
+ }
+
+ # extract tarball and move into place
+ set tar [macports::findBinary tar $macports::autoconf::tar_path]
+ file mkdir ${mp_source_path}/tmp
+ set tar_cmd "$tar -C ${mp_source_path}/tmp -xf ${tarball}"
+ ui_debug $tar_cmd
+ if {[catch {system $tar_cmd}]} {
+ return -code error "Failed to extract MacPorts sources from tarball!"
+ }
+ file delete -force ${mp_source_path}/base
+ file rename ${mp_source_path}/tmp/base ${mp_source_path}/base
+ file delete -force ${mp_source_path}/tmp
+ # set the final extracted source path
+ set mp_source_path ${mp_source_path}/base
+ }
+
# echo current MacPorts version
ui_msg "MacPorts base version $macports::autoconf::macports_version installed,"
Modified: trunk/base/src/macports1.0/macports_autoconf.tcl.in
===================================================================
--- trunk/base/src/macports1.0/macports_autoconf.tcl.in 2011-06-02 04:25:28 UTC (rev 79092)
+++ trunk/base/src/macports1.0/macports_autoconf.tcl.in 2011-06-02 04:32:01 UTC (rev 79093)
@@ -40,6 +40,7 @@
variable macports_user_dir "~/.macports"
variable macportsuser "@RUNUSR@"
variable open_path "@OPEN@"
+ variable openssl_path "@OPENSSL@"
variable pax_path "@PAX@"
variable rsync_path "@RSYNC@"
variable tar_command "@TAR_CMD@"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110601/ab18fa18/attachment.html>
More information about the macports-changes
mailing list