summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@vader.jdub.homelinux.org>2007-05-18 16:04:11 -0500
committerJosh Boyer <jwboyer@vader.jdub.homelinux.org>2007-05-18 16:04:11 -0500
commit9cc309ee34e3b9b40ffa0bc262d0a221fb0974c4 (patch)
tree54badfa69083968e3beef217f2f49497461ac646 /scripts
parentc08d7cea8ec3f41eca25efde37a63f3b907372eb (diff)
downloadreleng-9cc309ee34e3b9b40ffa0bc262d0a221fb0974c4.tar.gz
releng-9cc309ee34e3b9b40ffa0bc262d0a221fb0974c4.tar.xz
releng-9cc309ee34e3b9b40ffa0bc262d0a221fb0974c4.zip
Add initial upgradecheck port. It could do alot of things smarter.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/upgradecheck/README5
-rw-r--r--scripts/upgradecheck/upgradecheck-core+extras.conf21
-rwxr-xr-xscripts/upgradecheck/upgradecheck.py291
3 files changed, 317 insertions, 0 deletions
diff --git a/scripts/upgradecheck/README b/scripts/upgradecheck/README
new file mode 100644
index 0000000..e9f6c4d
--- /dev/null
+++ b/scripts/upgradecheck/README
@@ -0,0 +1,5 @@
+To generate an upgrade check report, run this:
+
+sudo ./upgradecheck.py -c upgradecheck-core+extras.conf -n -w -x
+
+If you want to include packages they may be missing from F7 repos but are in F6 repos, add a -m parameter to the above.
diff --git a/scripts/upgradecheck/upgradecheck-core+extras.conf b/scripts/upgradecheck/upgradecheck-core+extras.conf
new file mode 100644
index 0000000..966bb39
--- /dev/null
+++ b/scripts/upgradecheck/upgradecheck-core+extras.conf
@@ -0,0 +1,21 @@
+[main]
+metadata_expire=0
+keepcache=0
+reposdir=
+
+[FC6]
+name=FC6
+baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/6/source/SRPMS/
+
+[F7]
+name=F7
+baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/development/source/SRPMS/
+
+[FC6-updates]
+name=FC6-updates
+baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/updates/6/SRPMS/
+
+[FE6]
+name=FE6
+baseurl=http://download.fedora.redhat.com/pub/fedora/linux/extras/6/SRPMS/
+#baseurl=file:///srv/rpmbuild/extras/tree/extras/6/SRPMS/
diff --git a/scripts/upgradecheck/upgradecheck.py b/scripts/upgradecheck/upgradecheck.py
new file mode 100755
index 0000000..7b5c1f2
--- /dev/null
+++ b/scripts/upgradecheck/upgradecheck.py
@@ -0,0 +1,291 @@
+#!/usr/bin/python -t
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import os
+import sys
+import sets
+import yum
+import koji
+import yum.Errors
+from yum.misc import getCacheDir
+from optparse import OptionParser
+from rpmUtils.miscutils import compareEVR
+import smtplib
+from email.MIMEText import MIMEText
+import datetime
+import re
+import rpmUtils.arch
+
+if sys.hexversion < 0x020300F0:
+ sys.stderr.write("%s: Sorry, Python >= 2.3 required.\n" % sys.argv[0])
+ sys.exit(1)
+
+mail_from = "buildsys@fedoraproject.org"
+mail_to = "fedora-maintainers@redhat.com"
+mail_subject = "Package EVR problems in FC+FE %s" % datetime.date.today()
+smtp_server = None
+
+# Add wanted distributions to "dists". Values should be numbers (as strings),
+# and all repos containing that number in their id's will be associated with
+# the corresponding distro version. For example, repo id "foo9bar" will be
+# associated with distro "9".
+dists = ('4', '5', '6', '7')
+
+# Architectures to operate on.
+archs = rpmUtils.arch.getArchList('src')
+
+# False positive workarounds until obsoletes processing is implemented
+# (not really doable as long as we operate on SRPMS): per-package tuples of
+# known good paths
+known_good = {
+# 'koffice': (('FL3-updates', 'FE4'),
+# ('FL3-updates', 'FE5'),
+# ('FL3-updates', 'FE6'),
+# ('FL3-updates', 'FE7'),
+# ),
+ }
+
+# Where to checkout owners/owners.list
+ownersworkdir = '/srv/extras-push/work'
+
+
+def parseArgs():
+ usage = "usage: %s [options (see -h)]" % sys.argv[0]
+ parser = OptionParser(usage=usage)
+ parser.add_option("-c", "--config", default='/etc/yum.conf',
+ help='config file to use (defaults to /etc/yum.conf)')
+ parser.add_option("-t", "--tempcache", default=False, action="store_true",
+ help="Use a temp dir for storing/accessing yum-cache")
+ parser.add_option("-d", "--cachedir", default='',
+ help="custom directory for storing/accessing yum-cache")
+ parser.add_option("-q", "--quiet", default=False, action="store_true",
+ help="quiet (no output to stderr)")
+ parser.add_option("-n", "--nomail", default=False, action="store_true",
+ help="do not send mail, just output the results")
+ parser.add_option("-w", "--noowners", default=False, action="store_true",
+ help="do not do owners.list processing")
+ parser.add_option("-x", "--nextonly", default=False, action="store_true",
+ help="check next dist version only for each package, "
+ "not all newer ones")
+ parser.add_option("-m", "--missing", default=False, action="store_true",
+ help="check for packages missing in newer repos")
+ (opts, args) = parser.parse_args()
+ return (opts, args)
+
+class MySolver(yum.YumBase):
+ def __init__(self, arch = None, config = "/etc/yum.conf"):
+ yum.YumBase.__init__(self)
+
+ self.arch = arch
+ self.doConfigSetup(fn = config)
+ if hasattr(self.repos, 'sqlite'):
+ self.repos.sqlite = False
+ self.repos._selectSackType()
+
+ def readMetadata(self):
+ self.doRepoSetup()
+ self.doSackSetup(archs)
+ for repo in self.repos.listEnabled():
+ self.repos.populateSack(which=[repo.id])
+
+ def log(self, value, msg):
+ pass
+
+def evrstr(evr):
+ return evr and "%s:%s-%s" % evr or "(missing)"
+
+def koji_get_info(name, report, tags=["dist-fc7", "f7-final", "dist-fc7-updates-candidate"]):
+ koji_server = "http://koji.fedoraproject.org/kojihub"
+ koji_session = koji.ClientSession(koji_server, {})
+ fmt = " %(nvr)-40s %(tag_name)-20s %(owner_name)s"
+
+ for tag in tags:
+ pkg = koji_session.getLatestBuilds(tag, package=name);
+ output = [ fmt % x for x in pkg ]
+ for line in output:
+ report.append(line)
+
+def main():
+ (opts, cruft) = parseArgs()
+
+ if opts.noowners:
+ owners = {}
+ else:
+ sys.path.append('/srv/extras-push/work/extras-repoclosure')
+ from PackageOwners import PackageOwners
+ owners = PackageOwners()
+ #owners.FromCVS(workdir = ownersworkdir)
+ if not owners.FromURL():
+ sys.exit(1)
+
+ solvers = {}
+
+ for dist in dists:
+ solver = MySolver(config = opts.config)
+ for repo in solver.repos.repos.values():
+ if re.sub('\D+', '', repo.id) != dist:
+ repo.disable()
+ else:
+ repo.enable()
+ solvers[dist] = solver
+
+ if os.geteuid() != 0 or opts.tempcache or opts.cachedir != '':
+ if opts.cachedir != '':
+ cachedir = opts.cachedir
+ else:
+ cachedir = getCacheDir()
+ if cachedir is None:
+ print "Error: Could not make cachedir, exiting"
+ sys.exit(50)
+
+ for repo in solvers.values():
+ repo.repos.setCacheDir(cachedir)
+
+ if not opts.quiet:
+ print 'Reading in repository metadata - please wait....'
+
+ for dist in solvers.keys():
+ try:
+ solvers[dist].readMetadata()
+ except yum.Errors.RepoError, e:
+ print 'Metadata read error for dist %s, excluding it' % dist
+ del solvers[dist]
+
+ pkgdict = {}
+ for dist in dists:
+ pkgdict[dist] = {}
+
+ enabled_dists = solvers.keys()
+ enabled_dists.sort()
+
+ allnames = {} # Python < 2.4 compat, otherwise we'd use sorted(set(...))
+ for dist in enabled_dists:
+ # Would use returnNewestByName() but it's broken in yum 3.0.1 (#220841)
+ # returnNewestByNameArch() works for our purposes as long as we only
+ # deal with one arch (src).
+ for pkg in solvers[dist].pkgSack.returnNewestByNameArch():
+ if pkg.name[-10:] == "-debuginfo": pass
+ allnames[pkg.name] = 1
+ pkgdict[dist][pkg.name] = {
+ "evr": (pkg.epoch, pkg.version, pkg.release),
+ "repo": pkg.repoid,
+ }
+ allnames = allnames.keys()
+ allnames.sort(lambda x, y: cmp(x.lower(), y.lower()))
+
+ report = []
+ missing_report = []
+ reports = {} # report per owner, key is owner email addr
+
+ for name in allnames:
+ pkgdata = map(lambda x: pkgdict[x].get(name), enabled_dists)
+ broken_paths = []
+
+ for i in range(len(pkgdata)):
+ curr = pkgdata[i]
+ if not curr:
+ # package missing from this dist, skip
+ continue
+
+ for next in pkgdata[i+1:]:
+ if not next:
+ if opts.missing:
+ # package missing from this dist, skip
+ # TODO: warn about holes in continuum?
+ missing = "%s %s %s not in next repo" % \
+ (name, evrstr(curr["evr"]), curr["repo"])
+ missing_report.append(missing)
+ koji_get_info(name, missing_report)
+ missing_report.append("")
+ continue
+
+ if compareEVR(curr["evr"], next["evr"]) > 0:
+ # candidate for brokenness
+ if not known_good.has_key(name):
+ known_good[name] = ()
+ if (curr["repo"], next["repo"]) not in known_good[name]:
+ # yep, it's broken
+ broken_paths.append((curr, next))
+
+ if opts.nextonly:
+ break
+
+ if broken_paths:
+ if owners:
+ owner = owners.GetOwner(name) or \
+ 'UNKNOWN OWNER (possibly Core package)'
+ else:
+ owner = ''
+ ownerprint = owner.replace('@',' AT ')
+ if not reports.has_key(owner):
+ reports[owner] = []
+ reports[owner].append(name)
+ report.append("%s: %s" % (name, ownerprint))
+ for broken in broken_paths:
+ what = " %s > %s (%s > %s)" % \
+ (broken[0]["repo"], broken[1]["repo"],
+ evrstr(broken[0]["evr"]), evrstr(broken[1]["evr"]))
+ reports[owner].append(what)
+ report.append(what)
+ koji_get_info(name, report)
+ reports[owner].append("")
+ report.append("")
+
+ # Insert "sorted by owner" report at the top.
+ oldreport = report
+ report = []
+ if not opts.noowners:
+ reportkeys = reports.keys()
+ reportkeys.sort()
+ for owner in reportkeys:
+ ownerprint = owner.replace('@',' AT ')
+ report.append(ownerprint+':')
+ for line in reports[owner]:
+ report.append(' '+line)
+ if report:
+ report.append('-'*70)
+ report.append('')
+ report += oldreport
+
+ report = "\n".join(report)
+ if report:
+ if mail_to and not opts.nomail:
+ msg = MIMEText(report)
+ msg["Subject"] = mail_subject
+ msg["From"] = mail_from
+ msg["To"] = mail_to
+ s = smtplib.SMTP()
+ if smtp_server:
+ s.connect(smtp_server)
+ else:
+ s.connect()
+ s.sendmail(mail_from, [mail_to], msg.as_string())
+ s.close()
+ else:
+ print report
+
+ if missing_report:
+ for line in missing_report:
+ print line
+
+if __name__ == "__main__":
+ main()
+
+# Local variables:
+# indent-tabs-mode: nil
+# py-indent-offset: 4
+# End:
+# ex: ts=4 sw=4 et