Merge lp:~ara/ubuntu/lucid/ubuntu-qa-tools/fix_537941 into lp:~ubuntu-branches/ubuntu/lucid/ubuntu-qa-tools/lucid

Proposed by Ara Pulido
Status: Merged
Merged at revision: not available
Proposed branch: lp:~ara/ubuntu/lucid/ubuntu-qa-tools/fix_537941
Merge into: lp:~ubuntu-branches/ubuntu/lucid/ubuntu-qa-tools/lucid
Diff against target: 995 lines (+557/-389)
4 files modified
debian/changelog (+10/-0)
debian/control (+7/-3)
dl-ubuntu-test-iso/dl-ubuntu-test-iso (+538/-384)
setup.py (+2/-2)
To merge this branch: bzr merge lp:~ara/ubuntu/lucid/ubuntu-qa-tools/fix_537941
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Review via email: mp+21222@code.launchpad.net

Description of the change

  * dl-ubuntu-test-iso is failing to download lucid images (LP: #537941)
  * Fixes some lintian errors due to script naming
  * debian/control:
    - Removed dependency with python-dev
    - Added two existing scripts to the description of the package

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Good work!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'bugs-mailinglist/ml-fixes-report.py' => 'bugs-mailinglist/ml-fixes-report'
2=== renamed file 'bugs-mailinglist/ml-team-fixes-report.py' => 'bugs-mailinglist/ml-team-fixes-report'
3=== modified file 'debian/changelog'
4--- debian/changelog 2009-07-14 08:43:29 +0000
5+++ debian/changelog 2010-03-12 09:50:29 +0000
6@@ -1,3 +1,13 @@
7+ubuntu-qa-tools (0.1.4.1) lucid; urgency=low
8+
9+ * dl-ubuntu-test-iso is failing to download lucid images (LP: #537941)
10+ * Fixes some lintian errors due to script naming
11+ * debian/control:
12+ - Removed dependency with python-dev
13+ - Added two existing scripts to the description of the package
14+
15+ -- Ara Pulido <ara@ubuntu.com> Fri, 12 Mar 2010 10:05:58 +0100
16+
17 ubuntu-qa-tools (0.1.4) karmic; urgency=low
18
19 * Added three new scripts:
20
21=== modified file 'debian/control'
22--- debian/control 2009-02-11 11:27:52 +0000
23+++ debian/control 2010-03-12 09:50:29 +0000
24@@ -4,11 +4,11 @@
25 Maintainer: Ubuntu MOTU Developers <ubuntu-motu@lists.ubuntu.com>
26 Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-bugcontrol/ubuntu-qa-tools/packaging
27 Vcs-Browser: http://codebrowse.launchpad.net/~ubuntu-bugcontrol/ubuntu-qa-tools/packaging/changes
28-Build-Depends: cdbs (>= 0.4.49), debhelper (>= 6), python-all-dev (>= 2.4)
29+Build-Depends: cdbs (>= 0.4.49), debhelper (>= 6), python-all
30 Build-Depends-Indep: python-central (>= 0.5)
31 XS-Python-Version: >= 2.5
32 Homepage: https://launchpad.net/ubuntu-qa-tools/
33-Standards-Version: 3.8.0
34+Standards-Version: 3.8.4
35
36 Package: ubuntu-qa-tools
37 Architecture: all
38@@ -27,10 +27,14 @@
39 .
40 * check-needs-packaging - checks for bugs that require new packaging
41 * body-searching - search bugs with a particular text
42- * count-senders - quantity of messages sent by individuals to the bug mailinglist
43+ * count-senders - quantity of messages sent by individuals
44+ to the bug mailinglist
45 * tagged-bugs - search for tagged bugs in Launchpad
46 * triager-query - search for actions of a particular triager
47 * dl-ubuntu-test-iso - downloads ISOs for testing using rsync
48 * iso-ripper - rips debs out of downloaded isos
49 * debian-bug-search - searches the Debian bug tracking system
50 * hugday - simplifies participating on ubuntu hugdays
51+ * ml-fixes-report - searches fixes in a bug mailing list
52+ * ml-team-fixes-report - searches fixes by team
53+
54
55=== modified file 'dl-ubuntu-test-iso/dl-ubuntu-test-iso'
56--- dl-ubuntu-test-iso/dl-ubuntu-test-iso 2009-07-14 08:43:29 +0000
57+++ dl-ubuntu-test-iso/dl-ubuntu-test-iso 2010-03-12 09:50:29 +0000
58@@ -1,384 +1,538 @@
59-#!/bin/sh
60-#
61-# Download, with rsync, Ubuntu ISO images for testing them.
62-# This will use a lot of bandwidth and disk space.
63-#
64-# You can put a configuration file (~/.dl-ubuntu-test-iso)
65-# and set some variables to limit what will be downloaded.
66-# See sample values below.
67-#
68-# * ARCHS: what architectures to download
69-# * FLAVORS: what flavors of Ubuntu? Ubuntu itself, Kubuntu, etc
70-# * VARIANTS: for each flavor, what variants? desktop (= live cd)?
71-# alternate cd?
72-# * OPTS: options for rsync
73-#
74-# You can get sample configuration files at /usr/share/doc/ubuntu-qa-tools/examples/
75-#
76-# This is based on a script by davmor2 on #ubuntu-testing. Modified and
77-# rewritten to be more easily extensible by Lars Wirzenius. Further
78-# abuse was perpetrated by Steve Beattie. This is probably
79-# too simple to be covered by copyright, but if not:
80-#
81-# Copyright 2008, 2009 Canonical Ltd.
82-# Licensed under the GNU General Public License, version 3.
83-
84-set -e
85-
86-ISOROOT="${HOME}/iso"
87-BASEURL="rsync://cdimage.ubuntu.com/cdimage"
88-RELEASES="karmic hardy"
89-ARCHS="i386 amd64"
90-FLAVORS="ubuntu kubuntu edubuntu xubuntu ubuntu-server"
91-FLAVORS="$FLAVORS ubuntustudio mythbuntu"
92-VARIANTS="desktop alternate server addon dvd"
93-EXCLUDE=""
94-OPTS="-zthhP"
95-QUIET="false"
96-NO_ACT=no
97-VERIFY="true"
98-BUILD="current"
99-
100-RSYNC=rsync
101-ISOINFO=/usr/bin/isoinfo
102-WGET=/usr/bin/wget
103-CURL=/usr/bin/curl
104-CURRENT_RELEASE="karmic"
105-VERSIONS="false"
106-CONFIGFILE="${HOME}/.dl-ubuntu-test-iso"
107-
108-if [ -e "${CONFIGFILE}" ]
109-then
110- . ${CONFIGFILE}
111-elif [ -e "${ISOROOT}/iso.cfg" ]
112-then
113- echo "******"
114- echo "****** ${ISOROOT}/iso.cfg is deprecated, please use ${CONFIGFILE} instead"
115- echo "******"
116- . "${ISOROOT}/iso.cfg"
117-fi
118-
119-setup_dir()
120-{
121- local dir=$1
122-
123- [ -d "$dir" ] || mkdir $dir
124- cd $dir
125-}
126-
127-setup_dir $ISOROOT
128-
129-die()
130-{
131- echo "$@" 1>&2
132- exit 1
133-}
134-
135-no_act()
136-{
137- [ "$NO_ACT" = yes ]
138-}
139-
140-debugify_commands()
141-{
142- RSYNC="echo $RSYNC"
143- ISOINFO="echo $ISOINFO"
144-}
145-
146-wantflavor()
147-{
148- echo " $FLAVORS " | grep " $1 " > /dev/null &&
149- echo " $EXCLUDE " | grep -v " $1 " > /dev/null
150-}
151-
152-wantvariant()
153-{
154- echo " $VARIANTS " | grep " $1 " > /dev/null
155-}
156-
157-wantarch()
158-{
159- local arch="$1"
160- shift
161- echo " $@ " | grep " $arch " > /dev/null
162-}
163-
164-# Dead code, kept around for historical raisins
165-#isold()
166-#{
167-# if [ ! -e "$1" ]
168-# then
169-# return 0
170-# else
171-# local mtime=$(stat --printf='%Y\n' "$1")
172-# local old=$(date --date="$MINAGE" +%s)
173-# [ "$mtime" -lt "$old" ]
174-# fi
175-#}
176-# end dead code
177-
178-isquiet()
179-{
180- [ "$QUIET" = "true" ]
181-}
182-
183-doverify()
184-{
185- [ "$VERIFY" = "true" ]
186-}
187-
188-doversions()
189-{
190- [ "$VERSIONS" = "true" ]
191-}
192-
193-computepath()
194-{
195- local flavor="$1"
196- local release="$2"
197- local dir="$3"
198-
199- local releasepath=""
200- local flavorpath=""
201- if [ "$CURRENT_RELEASE" != "$release" ]
202- then
203- releasepath="$release/"
204- fi
205-
206- if [ "$flavor" != "ubuntu" ]
207- then
208- flavorpath="$flavor/"
209- fi
210-
211- echo "${flavorpath}${releasepath}${dir}"
212-}
213-
214-has_joliet()
215-{
216- local iso="$1"
217- ! isoinfo -d -i "${iso}" | grep -q "^NO Joliet"
218-}
219-
220-report_versions()
221-{
222- local dir=$1
223-
224- if [ ! -x ${ISOINFO} ]
225- then
226- echo "Please install the isoinfo package in order to report iso versions"
227- echo "(On ubuntu, 'sudo apt-get install genisoimage' will get it."
228- exit 1
229- fi
230-
231- find $dir -name "*.iso" -print | while read isoname
232- do
233- # all ubuntu cds should be joliet, but if non-joliet ones are
234- # stored in the tree as well, it's nice to not report errors due
235- # to that.
236- if has_joliet ${isoname}
237- then
238- DISKINFO=$(${ISOINFO} -J -x "/.disk/info" -i ${isoname} || true)
239- DISKTYPE=$(${ISOINFO} -J -x "/.disk/cd_type" -i ${isoname} || true)
240- fi
241- echo "$isoname ${DISKINFO} ${DISKTYPE}"
242- done
243-}
244-
245-# returns boolean if file exists remotely
246-remote_file_exists()
247-{
248- local url=$(echo "$1" | sed -e 's/rsync/http/')
249- if [ -x "${WGET}" ]
250- then
251- ${WGET} -q --spider "${url}"
252- elif [ -x "${CURL}" ]
253- then
254- # meh, curl, why are you a pain?
255- local code=$(${CURL} -s -I --write-out "%{http_code}\n" "${url}" | tail -1)
256- [ "${code}" = "200" ]
257- else
258- return 0
259- fi
260-}
261-
262-get()
263-{
264- local flavor="$1"
265- local dir="$2"
266- shift 2
267-
268- local output=""
269- if isquiet
270- then
271- output="> /dev/null"
272- fi
273-
274- for variant in "$@"
275- do
276- if wantflavor "$flavor" && wantvariant "$variant"
277- then
278- [ -d "$flavor" ] || mkdir "$flavor"
279- for arch in $ARCHS
280- do
281- for release in $RELEASES
282- do
283- if wantarch "$arch" "$ARCHS"
284- then
285- local iso="$release-$variant-$arch.iso"
286- local path="$(computepath $flavor $release $dir)"
287- local md5sum="MD5SUMS.$release-$variant"
288- local remote_path="$BASEURL/$path/$iso"
289- if ! remote_file_exists "${remote_path}"
290- then
291- isquiet || echo "Skipping $release $flavor $variant $arch: not on server"
292- else
293- isquiet || echo "Synching $release $flavor $variant $arch ($path/$iso)"
294- if no_act
295- then
296- :
297- # echo "(Not really running rsync because of NO_ACT)"
298- else
299- $RSYNC $OPTS "${remote_path}" "$flavor/$iso" || true
300- doverify && $RSYNC $OPTS "$BASEURL/$path/MD5SUMS" "$flavor/$md5sum" || true
301- fi
302- if doverify
303- then
304- if [ -f "$flavor/$md5sum" ]
305- then
306- local FILEMD5SUM="$(grep "$iso" "$flavor/$md5sum" | sed -e "s/\($iso\)/$flavor\/\\1/")"
307- isquiet || echo -n "Verifying $iso... "
308- eval "echo \"$FILEMD5SUM\" | md5sum -c - $output" || true
309- else
310- isquiet || echo "No checksum file available for $iso, skipping verification"
311- fi
312- fi
313- fi
314- fi
315- done
316- done
317- fi
318- done
319-}
320-
321-print_help()
322-{
323- echo "
324- ./dl-ubuntu-test-iso [options]
325-
326-You may use the following options:
327-
328- -n, --no-act
329- Do everything, except don't actually run rsync. You can use this
330- to test configuration settings, etc.
331-
332- --debug
333- Similar to --no-act, but echos the actual rsync commands, as you
334- might expect, this is useful for debugging the script or
335- configurations
336-
337- -P Run rsync with the -P option, to get progress reporting.
338-
339- --only flavor, --flavor flavor
340- Only download a specific flavor of Ubuntu. Only the last
341- --only option applies. (You can also set FLAVORS in the
342- configuration file.) --only should probably be considered
343- depricated.
344-
345- --exclude flavor
346- Do not download a specific flavor of Ubuntu. You can use this
347- option multiple times, and none of the specified flavors will be
348- downloaded. (You can also set EXCLUDE in the configuration
349- file.)
350-
351- --release release
352- Only download a specific release target of Ubuntu. Only the last
353- --release option applies. (You can also set RELEASES in the
354- configuration file.) \"hardy\" is the earliest release target
355-
356- --bwlimit kbpslimit
357- Rate limit rsync download to a limit in KBytes/second.
358- "
359-}
360-
361-TEMP=`getopt -o nPqh --long no-act,help,force,debug,quiet,no-verify,versions,only:,exclude:,release:,flavor:,bwlimit:,build: -- "$@"`
362-eval set -- "$TEMP"
363-
364-while true
365-do
366- case "$1" in
367- -n|--no-act) NO_ACT=yes; shift ;;
368- --debug) debugify_commands ; shift;;
369- -q|--quiet) QUIET=true; shift ;;
370- -P) OPTS="$OPTS -P"; shift ;;
371- --only|--flavor) FLAVORS="$2"; shift 2;;
372- --exclude) EXCLUDE="$EXCLUDE $2"; shift 2;;
373- --release) RELEASES="$2"; shift 2;;
374- --bwlimit) OPTS="$OPTS --bwlimit=$2"; shift 2;;
375- --build) BUILD="$2"; shift 2;;
376- --no-verify) VERIFY="FALSE"; shift ;;
377- --versions) VERSIONS="true"; shift ;;
378- -h|--help) print_help ; die ;;
379- --) shift; break ;;
380- *) die "Internal error while parsing command line"
381- esac
382-done
383-
384-if isquiet
385-then
386- OPTS="$OPTS -q"
387-fi
388-
389-isquiet || cat << eof
390-BASEURL=$BASEURL
391-RELEASES=$RELEASES
392-ARCHS=$ARCHS
393-FLAVORS=$FLAVORS
394-VARIANTS=$VARIANTS
395-EXCLUDE=$EXCLUDE
396-OPTS=$OPTS
397-NO_ACT=$NO_ACT
398-VERIFY=$VERIFY
399-BUILD=$BUILD
400-ISOROOT=$ISOROOT
401-QUIET=$QUIET
402-
403-eof
404-
405-if doversions
406-then
407- report_versions $ISOROOT
408- exit 0
409-fi
410-
411-get ubuntu daily-live/${BUILD} desktop
412-get ubuntu daily/${BUILD} alternate
413-get ubuntu dvd/${BUILD} dvd
414-
415-get ubuntu-server daily/${BUILD} server
416-
417-get kubuntu daily-live/${BUILD} desktop
418-get kubuntu daily/${BUILD} alternate
419-get kubuntu dvd/${BUILD} dvd
420-
421-# deprecated, not enabled by default
422-get kubuntu-kde4 daily-live/${BUILD} desktop
423-get kubuntu-kde4 daily/${BUILD} alternate
424-
425-get edubuntu daily/${BUILD} addon
426-
427-get xubuntu daily-live/${BUILD} desktop
428-get xubuntu daily/${BUILD} alternate
429-
430-get ubuntustudio daily/${BUILD} alternate
431-
432-__ARCHS=$ARCHS
433-# deprecated, not enabled by default
434-ARCHS=i386 get jeos daily/${BUILD} jeos
435-ARCHS=${__ARCHS}
436-
437-# deprecated, not enabled by default
438-get gobuntu daily/${BUILD} alternate
439-
440-# alternate deprecated, should probably be removed
441-get mythbuntu daily/${BUILD} alternate
442-get mythbuntu daily-live/${BUILD} desktop
443+#!/usr/bin/python
444+from __future__ import with_statement # This isn't required in Python 2.6, but must be in the beginning and thus can't be conditional
445+
446+import httplib
447+import urllib2
448+from time import strptime
449+from datetime import datetime, timedelta
450+from optparse import OptionParser
451+from os import environ
452+import hashlib
453+import os
454+import re
455+import subprocess
456+import sys
457+import stat
458+
459+current_release = 'lucid'
460+releasedict = {}
461+releasedict['hardy'] = []
462+releasedict['intrepid'] = []
463+releasedict['jaunty'] = []
464+releasedict['karmic'] = []
465+releasedict['lucid'] = []
466+
467+#allreleases = ['hardy', 'intrepid']
468+allarchs = ['i386', 'amd64', 'lpia', 'armel']
469+
470+default = {}
471+default['archs'] = ['i386', 'amd64']
472+default['variants'] = ['desktop', 'alternate', 'dvd']
473+default['build'] = 'current'
474+default['host'] = 'cdimage.ubuntu.com'
475+default['releases'] = ['hardy', 'lucid']
476+default['isoroot'] = environ['HOME'] + '/iso/'
477+
478+zsync_binary = '/usr/bin/zsync'
479+
480+class Flavor:
481+ def __init__(self, name, use_prefix=True, releases=default['releases'],
482+ variants=default['variants'], archs=default['archs']):
483+ self.name = name
484+ self.prefix = None
485+ if use_prefix:
486+ self.prefix = name
487+ self.dir = dir
488+ self.releases = releases
489+ self.variants = variants
490+ self.archs = archs
491+ for r in releases:
492+ releasedict[r].append(self)
493+ flavors[name] = self
494+
495+def my_log(x):
496+ print x
497+
498+## HTML Header, defines CSS and header image ##
499+def printHeader():
500+ print """
501+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
502+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
503+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
504+<head>
505+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
506+ <title>Daily ISO Tracker</title>
507+ <style type="text/css">
508+ body { background: #FFFFFF; color: black; }
509+ a { text-decoration: none; }
510+ table.head { border-style: none none; }
511+ table.head td { text-align: center; padding-left: 10px; padding-right: 10px}
512+ table.body { background: #efe1c3; border-collapse: collapse; border-style: solid solid;
513+ border-width: 3px; margin-bottom: 3ex; empty-cells: show; }
514+ table.body th { text-align: left; border-style: none none dotted none;
515+ border-width: 1px; padding-right: 10px; }
516+ table.body td { text-align: left; border-style: none none dotted none;
517+ border-width: 1px; padding-right: 10px; }
518+ a { color: blue; }
519+ a.verified { color: green; font-weight: bold; }
520+ a.testing { color: blue; }
521+ pre { white-space: pre-wrap; }
522+ </style>
523+</head>
524+<body>
525+<table class="head">
526+ <tr><td width="30%"><a href="http://www.ubuntu.com/"><img src="http://www.ubuntu.com/themes/ubuntu07/images/ubuntulogo.png" border="0" hspace="0" vspace="0" alt="Ubuntu"></a></td>
527+ <td><h1>Daily ISO Tracker</h1></td></tr>
528+</table>
529+"""
530+
531+## Print footer ##
532+def printFooter():
533+ time = datetime.datetime.utcnow()
534+ print "<p>Last Updated (UTC): %s by <a href=\"https://code.launchpad.net/~sbeattie/sru-tools/sru-buglist\">sru_buglist</a>" % time.ctime()
535+ print "written by <a href=\"mailto:sbeattie@ubuntu.com\">Steve Beattie</a>.</p>"
536+ print "</body></html>"
537+
538+def dumpHeaders(headers):
539+ for header, value in headers:
540+ print header + ': ' + value
541+
542+unit_names = {"year" : ("year", "years"),
543+ "month" : ("month", "months"),
544+ "week" : ("week", "weeks"),
545+ "day" : ("day", "days"),
546+ "hour" : ("hour", "hours"),
547+ "minute" : ("minute", "minutes"),
548+ "second" : ("second", "seconds")}
549+
550+def seconds_in_units(seconds):
551+ """
552+ Returns a tuple containing the most appropriate unit for the
553+ number of seconds supplied and the value in that units form.
554+
555+ >>> seconds_in_units(7700)
556+ (2, 'hour')
557+ """
558+
559+ unit_limits = [("year", 365 * 24 * 3600),
560+ ("month", 30 * 24 * 3600),
561+ ("week", 7 * 24 * 3600),
562+ ("day", 24 * 3600),
563+ ("hour", 3600),
564+ ("minute", 60)]
565+
566+ for unit_name, limit in unit_limits:
567+ if seconds >= limit:
568+ amount = int(round(float(seconds) / limit))
569+ return amount, unit_name
570+ return seconds, "second"
571+
572+def stringify_timedelta(td):
573+ """
574+ Converts a timedelta into a nicely readable string.
575+
576+ >>> td = timedelta(days = 77, seconds = 5)
577+ >>> print readable_timedelta(td)
578+ two months
579+ """
580+ seconds = td.days * 3600 * 24 + td.seconds
581+ amount, unit_name = seconds_in_units(seconds)
582+
583+ str_unit = unit_names[unit_name][1]
584+ if amount == 1:
585+ str_unit = unit_names[unit_name][0]
586+ return "%d %s" % (amount, str_unit)
587+
588+def parseDate(date):
589+ return datetime.strptime(date, "%a, %d %b %Y %H:%M:%S %Z")
590+
591+def create_dir(path):
592+ # XXX: make this more defensive. Sigh.
593+ try:
594+ stat = os.stat(path)
595+ except OSError, e:
596+ os.makedirs(path)
597+
598+def read_config(pathname):
599+ '''Read the config file, using shell syntax for backwards
600+ compatability.'''
601+ if not os.path.exists(pathname):
602+ return None
603+
604+ shell_vars = ['ISOROOT', 'RELEASES', 'FLAVORS', 'VARIANTS', 'EXCLUDE',
605+ 'OPTS', 'QUIET', 'NO_ACT', 'VERIFY', 'BUILD', 'BASEURL', 'ARCHS']
606+ command = ". %s; " %(pathname)
607+ for var in shell_vars:
608+ command += 'if [ ! -z "$%s" ] ; then echo %s=$%s; fi ; ' %(var, var, var)
609+ p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
610+ out, err = p.communicate()
611+
612+ config = dict()
613+ for line in re.split('\n', out):
614+ l = re.split('=', line)
615+ if not len(l) == 2:
616+ continue
617+ if l[0] in ['RELEASES', 'FLAVORS', 'VARIANTS', 'EXCLUDE']:
618+ l[1] = l[1].lower()
619+ config[str.lower(l[0])] = l[1]
620+ return config
621+
622+def computepath(wanted, flavor, release, variant):
623+ path = '/'
624+ if flavor.prefix:
625+ path += flavor.prefix + '/'
626+ if release != current_release:
627+ path += release + '/'
628+ path += '%s/%s/' %(variantpaths[variant], wanted['build'])
629+ return path
630+
631+def get_status(uri, host, conn=None):
632+ close = False
633+ result = False, None
634+ if not conn:
635+ conn = httplib.HTTPConnection(host)
636+ conn.set_debuglevel(0)
637+ close = True
638+ conn.request("HEAD", uri)
639+ response = conn.getresponse()
640+ if response.status == 200:
641+ modified = response.getheader('last-modified')
642+ age = datetime.utcnow() - parseDate(modified)
643+ result = True, stringify_timedelta(age)
644+ else:
645+ result = False, response.reason
646+ response.read()
647+ if close:
648+ conn.close()
649+ return result
650+
651+def check_status(wanted, config):
652+ conn = httplib.HTTPConnection(config.host)
653+ conn.set_debuglevel(0)
654+ for count, image in enumerate(image_factory(wanted)):
655+ release, flavor, variant, arch = image
656+ isoname = release + '-' + variant + '-' + arch + '.iso'
657+ path = computepath(wanted, flavor, release, variant)
658+ uri = path + isoname
659+ #print 'Result for ' + uri + ': ' + str(response.status)
660+ rc, msg = get_status(uri + '.zsync', config.host, conn=conn)
661+ print 'Result for ' + isoname + '.zsync: ' + msg
662+ rc, msg = get_status(uri, config.host, conn=conn)
663+ print 'Result for ' + isoname + ': ' + msg
664+ conn.close()
665+
666+def _do_download(config, source, target):
667+ result = True
668+ conn = None
669+ out = None
670+
671+ try:
672+ conn = urllib2.urlopen('http://' + config.host + source)
673+ out = open(target, 'w')
674+ for data in conn:
675+ out.write(data)
676+ except IOError:
677+ result = False
678+ finally:
679+ if conn:
680+ conn.close()
681+ if out:
682+ out.close()
683+ return result
684+
685+def _do_zsync(config, meta, src, target):
686+ command = [zsync_binary, '-k', meta, '-o', target,
687+ 'http://%s/%s' %(config.host, src)]
688+ if config.quiet:
689+ command.insert(1, '-q')
690+ if config.no_act or config.debug:
691+ if config.debug:
692+ print ' '.join(command)
693+ return True
694+
695+ rc = 0
696+ interrupted = False
697+ try:
698+ rc = subprocess.call(command)
699+ # trap external SIGINT death
700+ if rc > 128 and rc % 128 == signal.SIGINT:
701+ interrupted = True
702+ except KeyboardInterrupt:
703+ interrupted = True
704+ finally:
705+ if os.path.exists(target + '.zs-old'):
706+ os.remove(target + '.zs-old')
707+ if (interrupted or rc != 0) and os.path.exists(target + '.part'):
708+ os.rename(target + '.part', target)
709+ if os.path.exists(target):
710+ os.chmod(target, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
711+ if interrupted:
712+ raise KeyboardInterrupt
713+ return rc == 0
714+
715+def do_zsync(config, destination, uri, isoname):
716+ zsync_uri = uri + '.zsync'
717+ zsync_iso = destination + '/' + isoname
718+ zsync_local = destination + '/'
719+ # hide zsync files when not mirroring tree structure
720+ if not config.mirror:
721+ zsync_local += '.'
722+ zsync_local += isoname + '.zsync'
723+ available, msg = get_status(zsync_uri, config.host)
724+ if not available:
725+ config._log("control file does not exist, skipping zsync: " + msg)
726+ return False
727+
728+ # when config.build is set, we could be grabbing an iso older in
729+ # time than what we have now. zsync only updates it's local copy
730+ # of the meta data if the remote version is dated newer, so we
731+ # manually rsync the version we want.
732+ if config.build != default['build']:
733+ rc = _do_rsync(config, zsync_uri, zsync_local)
734+
735+ return _do_zsync(config, zsync_local, zsync_uri, zsync_iso)
736+
737+
738+def _do_rsync(config, source, target):
739+ command = ['/usr/bin/rsync', '-zthP', 'rsync://%s/cdimage%s' %(config.host, source), target]
740+ if len(config.bwlimit) > 0:
741+ command.insert(2, '--bwlimit=' + config.bwlimit)
742+ if config.quiet:
743+ command.insert(2, '-q')
744+ if config.no_act or config.debug:
745+ if config.debug:
746+ print ' '.join(command)
747+ return True
748+ rc = subprocess.call(command)
749+ return rc == 0
750+
751+def do_rsync(config, destination, uri, isoname):
752+ rsync_local = destination + '/' + isoname
753+ #rc = cmd(['/usr/bin/zsync', '-o', zsync_local, 'http://cdimages.ubuntu.com/' + zsync_uri])
754+ return _do_rsync(config, uri, rsync_local)
755+
756+def lookup_hash(path, host):
757+ hash_table = {
758+ "SHA256" : hashlib.sha256,
759+ "SHA1" : hashlib.sha1,
760+ "MD5" : hashlib.md5,
761+ }
762+ conn = httplib.HTTPConnection(host)
763+ conn.set_debuglevel(0)
764+ for alg in hash_table.keys():
765+ uri = path + alg + 'SUMS'
766+ available, msg = get_status(uri, host, conn=conn)
767+ if available:
768+ conn.close()
769+ return alg, hash_table[alg]
770+ conn.close()
771+ return None, None
772+
773+def do_verify(config, destination, hashsuffix, path, iso):
774+ alg, hashfunc = lookup_hash(path, config.host)
775+ if not alg:
776+ return False
777+
778+ uri = path + alg + "SUMS"
779+ if config.mirror:
780+ local = destination + '/' + alg + "SUMS"
781+ else:
782+ local = destination + '/' + alg + "SUMS" + hashsuffix
783+ rc = _do_download(config, uri, local)
784+ if not rc:
785+ return False
786+
787+ digest = None
788+ with open(local) as f:
789+ for line in f:
790+ if iso in line:
791+ digest = re.split('\s+', line)[0]
792+ break
793+
794+ if not digest:
795+ return False
796+
797+ m = hashfunc()
798+ fd = os.open(destination + '/' + iso, os.O_RDONLY)
799+ data = os.read(fd, 16 * 256 * 256)
800+ while len(data):
801+ m.update(data)
802+ data = os.read(fd, 16 * 256 * 256)
803+ os.close(fd)
804+ result = m.hexdigest()
805+ #print digest + ' ' + iso
806+ #print result + ' ' + iso
807+
808+ return digest == result
809+
810+def iso_download(wanted, config):
811+ saved_cwd = os.getcwd()
812+ create_dir(wanted['isoroot'])
813+ os.chdir(wanted['isoroot'])
814+
815+ for count, image in enumerate(image_factory(wanted)):
816+ release, flavor, variant, arch = image
817+ isoname = release + '-' + variant + '-' + arch + '.iso'
818+ hashsuffix = "." + release + '-' + variant
819+ path = computepath(wanted, flavor, release, variant)
820+ if config.mirror:
821+ destination = path[1:-1]
822+ else:
823+ destination = flavor.name
824+ create_dir(destination)
825+ uri = path + isoname
826+ #print 'Result for ' + uri + ': ' + str(response.status)
827+
828+ config._log("Syncing %s %s %s %s" %(release, flavor.name, variant, arch))
829+ available, msg = get_status(uri, config.host)
830+ if not available:
831+ config._log("iso unavailable from server, skipping: " + msg)
832+ continue
833+
834+ if not (config.use_zsync and do_zsync(config, destination, uri, isoname)):
835+ do_rsync(config, destination, uri, isoname)
836+ if config.do_verify:
837+ config._log("Verifying " + destination + '/' + isoname)
838+ if not (config.debug or config.no_act):
839+ if do_verify(config, destination, hashsuffix, path, isoname):
840+ config._log("Verification succeeded")
841+ else:
842+ config._log("!!! Verification failed !!!")
843+
844+ os.chdir(saved_cwd)
845+
846+def dump_info(wanted):
847+ for count, image in enumerate(image_factory(wanted)):
848+ release, flavor, variant, arch = image
849+ print "%s %s %s %s %s" %(release, flavor.name, variant, arch, variantpaths[variant])
850+
851+def image_factory(wanted):
852+ for release in releasedict.keys():
853+ if release not in wanted['releases']:
854+ continue
855+ for flavor in releasedict[release]:
856+ if flavor.name not in wanted['flavors']:
857+ continue
858+ for variant in flavor.variants:
859+ if variant not in wanted['variants']:
860+ continue
861+ for arch in flavor.archs:
862+ if arch not in wanted['archs']:
863+ continue
864+ yield (release, flavor, variant, arch)
865+ #print "%s %s %s %s %s" %(release, flavor.name, variant, arch, variantpaths[variant])
866+
867+def merge_config(cval, file, default, value):
868+ ret = None
869+ if len(cval) > 0:
870+ ret = cval
871+ elif file and value in file.keys() and len(file[value]) > 0:
872+ ret = file[value]
873+ elif value in default.keys():
874+ ret = default[value]
875+ return ret
876+
877+def main():
878+ global releasedict, current_release, variantpaths, flavors
879+
880+ config = {}
881+ wanted = {}
882+ flavors = {}
883+ variantpaths = {}
884+ variantpaths['desktop'] = 'daily-live'
885+ variantpaths['alternate'] = 'daily'
886+ variantpaths['jeos'] = 'daily'
887+ variantpaths['dvd'] = 'dvd'
888+ variantpaths['server'] = 'daily'
889+ variantpaths['addon'] = 'daily'
890+ variantpaths['usb'] = 'daily'
891+ variantpaths['netbook-remix'] = 'daily-live'
892+ variantpaths['netbook'] = 'daily-live'
893+ variantpaths['moblin-remix'] = 'daily-live'
894+
895+ Flavor('ubuntu', use_prefix=False)
896+ Flavor('ubuntu-server', variants=['server'])
897+ Flavor('kubuntu')
898+ Flavor('kubuntu-kde4', releases=['hardy'], variants=['desktop', 'alternate'])
899+ Flavor('edubuntu', variants=['addon', 'dvd'])
900+ Flavor('xubuntu', variants=['desktop', 'alternate'])
901+ Flavor('ubuntustudio', variants=['alternate'])
902+ Flavor('jeos', releases=['hardy'], variants=['jeos'], archs=['i386'])
903+ Flavor('gobuntu', releases=['hardy'], variants=['alternate'])
904+ Flavor('mythbuntu', variants=['desktop'])
905+ Flavor('ubuntu-mid', variants=['usb'], archs=['lpia'])
906+ Flavor('ubuntu-netbook', variants=['netbook'], archs=['i386'])
907+ Flavor('kubuntu-netbook', variants=['netbook'], archs=['i386'])
908+ Flavor('ubuntu-moblin-remix', variants=['moblin-remix'], archs=['i386'])
909+
910+ default['variants'] = variantpaths.keys()
911+ default['flavors'] = flavors.keys()
912+
913+ parser = OptionParser()
914+ parser.add_option('-n', '--no-act', default=False, action='store_true', dest='no_act', help='compute everything but don\'t actually download')
915+ parser.add_option('-d', '--debug', default=False, action='store_true')
916+ parser.add_option('-q', '--quiet', default=False, action='store_true', help='suppress output except errors')
917+ parser.add_option('-P', '--progress', default=False, action='store_true', help='display a progress meter while downloading')
918+ parser.add_option('--only', '--flavor', action='append', default=[], dest='flavor', help='select specific flavor to download; multiple --flavor args can be passed')
919+ parser.add_option('--exclude', '--exclude-flavor', action='append', default=[], dest='exclude_flavor')
920+ parser.add_option('--release', '--only-release', action='append', default=[], dest='release')
921+ parser.add_option('--variant', '--only-variant', action='append', default=[], dest='variant')
922+ parser.add_option('--exclude-variant', action='append', default=[], dest='exclude_variant')
923+ parser.add_option('--arch', '--only-arch', action='append', default=[], dest='arch')
924+ parser.add_option('--bwlimit', default='', action="store", type="string", help='rate limit rsync download to BWLIMIT in KBytes/second')
925+ parser.add_option('--build', default=default['build'], action="store", type="string")
926+ parser.add_option('--no-verify', default=True, action="store_false", dest='do_verify', help='skip comparison against published checksums')
927+ parser.add_option('--no-zsync', default=True, action="store_false", dest='use_zsync', help="don't use zsync to download")
928+ #parser.add_option('--versions', default=False, action='store_true')
929+ parser.add_option('--isoroot', default='', action='store', type='string', help='local directory root to store isos; default is %s' %(default['isoroot']))
930+ parser.add_option('--config', default=environ['HOME'] + '/.dl-ubuntu-test-iso', action='store', type='string',
931+ help='choose alternate config file location, default is %default')
932+ parser.add_option('--host', default=default['host'], action='store', type='string', help='mirror to pull images from; default is %s' %(default['host']))
933+ parser.add_option('--mirror', default=False, action='store_true', dest='mirror', help='mirror tree structure from cdimages')
934+
935+ config, args = parser.parse_args()
936+ if len(args) != 0:
937+ parser.error("incorrect number of arguments")
938+ file_cfg = read_config(config.config)
939+
940+ wanted['flavors'] = merge_config(config.flavor, file_cfg, default, 'flavors')
941+ if len(config.exclude_flavor) > 0:
942+ wanted['flavors'] = filter(lambda x: x not in config.exclude_flavor, wanted['flavors'])
943+
944+ wanted['releases'] = merge_config(config.release, file_cfg, default, 'releases')
945+ wanted['variants'] = merge_config(config.variant, file_cfg, default, 'variants')
946+ if len(config.exclude_variant) > 0:
947+ wanted['variants'] = filter(lambda x: x not in config.exclude_variant, wanted['variants'])
948+ wanted['build'] = merge_config(config.build, file_cfg, default, 'build')
949+ wanted['isoroot'] = merge_config(config.isoroot, file_cfg, default, 'isoroot')
950+
951+ wanted['archs'] = merge_config(config.arch, file_cfg, default, 'archs')
952+
953+ if not config.no_act and file_cfg != None and 'no_act' in file_cfg.keys():
954+ config.no_act = ('true' == file_cfg['no_act'].lower())
955+
956+ if config.do_verify and file_cfg != None and 'verify' in file_cfg.keys():
957+ config.no_act = ('true' == file_cfg['verify'].lower())
958+
959+ if config.quiet:
960+ config._log = lambda x: x
961+ else:
962+ config._log = my_log
963+
964+ if config.use_zsync and not os.path.exists(zsync_binary):
965+ config._log("Warning! zsync is not installed, falling back to rsync")
966+ config.use_zsync = False
967+
968+ if config.use_zsync and len(config.bwlimit) > 0:
969+ config._log("Warning! zsync does not support bandwidth limiting")
970+
971+ #print file_cfg
972+ #print config
973+ #print wanted
974+ #dump_info(wanted, config)
975+ #check_status(wanted, config)
976+ iso_download(wanted, config)
977+
978+if __name__ == "__main__":
979+ main()
980+
981
982=== modified file 'setup.py'
983--- setup.py 2009-07-14 08:43:29 +0000
984+++ setup.py 2010-03-12 09:50:29 +0000
985@@ -20,8 +20,8 @@
986 'bugs-mailinglist/count-senders',
987 'bugs-mailinglist/tagged-bugs',
988 'bugs-mailinglist/triager-query',
989- 'bugs-mailinglist/ml-team-fixes-report.py',
990- 'bugs-mailinglist/ml-fixes-report.py',
991+ 'bugs-mailinglist/ml-team-fixes-report',
992+ 'bugs-mailinglist/ml-fixes-report',
993 'bugs-mailinglist/new-bug-description-search',
994 'bugtrackers/debian-bug-search',
995 'dl-ubuntu-test-iso/dl-ubuntu-test-iso',

Subscribers

People subscribed via source and target branches

to all changes: