summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Page <james.page@ubuntu.com>2017-06-15 13:24:06 (GMT)
committerJames Page <james.page@ubuntu.com>2017-06-15 13:24:06 (GMT)
commit15ffcee37b8039eef377e3488c57d348035f0efb (patch)
tree964fa600d93a9631440c49543ed7cbfdc0777861
parentb49319f3b1d5361784791471e776a01899a0e75a (diff)
Refactor things a little and automatically detect new versions in proposed for rechecks.
-rwxr-xr-xautopkgtest-triggers.py142
1 files changed, 126 insertions, 16 deletions
diff --git a/autopkgtest-triggers.py b/autopkgtest-triggers.py
index 28d2565..f76d8aa 100755
--- a/autopkgtest-triggers.py
+++ b/autopkgtest-triggers.py
@@ -6,36 +6,146 @@
# autopkgtest-triggers.py < update_excuses.yaml
-import urllib.parse
+import optparse
import yaml
import sys
+import functools
+
+import urllib.parse
+import urllib.request
+
+from apt_pkg import version_compare
+
+from ubuntutools.logger import Logger
+
+from ubuntutools.lp.lpapicache import (Launchpad, Distribution,
+ PackageNotFoundException)
+
+
+DEFAULT_RELEASE = 'artful'
+
+DEFAULT_ARCHS = [
+ 's390x',
+ 'amd64',
+ 'i386',
+ 'armhf',
+ 'ppc64el'
+]
+
+UPDATE_EXCUSES = (
+ "http://people.canonical.com/~ubuntu-archive/"
+ "proposed-migration/{}/update_excuses.yaml"
+)
+
+
+def get_lp():
+ if not Launchpad.logged_in:
+ Launchpad.login_anonymously()
+
+
+def query_distro(package, release=DEFAULT_RELEASE):
+ ''' Query the release for the version of package '''
+ get_lp()
+ archive = Distribution('ubuntu').getArchive()
+ pkgs = []
+ pockets = ['Release', 'Security', 'Updates', 'Proposed']
+ for pocket in pockets:
+ try:
+ pkg = archive.getSourcePackage(package, release, pocket=pocket)
+ pkgs.append(pkg)
+ except PackageNotFoundException:
+ pass
+
+ if not pkgs:
+ return None
+
+ versions = sorted([x.getVersion() for x in pkgs],
+ key=functools.cmp_to_key(version_compare),
+ reverse=True)
+ return versions[0]
def url_quote(string):
"""URL-encode package/version string"""
return urllib.parse.quote_plus(string).replace("/","%2F")
-def rerun_link(package, arch, triggers):
- """Create link for restarting autopkgtest for a given package, architecture with the list of trigger packages"""
- link = "https://autopkgtest.ubuntu.com/request.cgi?release=zesty&arch=" + arch + "&package=" + url_quote(package)
+
+def rerun_link(release, package, arch, triggers):
+ """
+ Create link for restarting autopkgtest
+ for a given package, architecture with
+ the list of trigger packages
+ """
+ link = (
+ "https://autopkgtest.ubuntu.com/request.cgi"
+ "?release={}&arch={}&package={}".format(release,
+ arch,
+ url_quote(package))
+ )
for trigger in triggers:
- link += "&trigger=" + url_quote(trigger)
+ link = "{}&trigger={}".format(link,
+ url_quote(trigger))
return link
def main():
- # extra dependencies to add for re-runs
- extra_deps = {'r-bioc-annotationhub/2.6.4-1' : ['r-bioc-genomeinfodb/1.10.3-1'],
- 'mathicgb/1.0~git20170104-1ubuntu1' : ['tbb/4.4~20160526-0ubuntu2']}
+ usage = 'usage: %prog [options] [pkg [pkg ...]]'
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('-r', '--release',
+ help='Ubuntu release to check for regressions',
+ dest='release', action='store', default="artful")
+ parser.add_option('-f', '--force',
+ help='Force recheck even if current latest version is in regression',
+ dest='recheck', action='store_true', default=False)
+ (opts, pkgs) = parser.parse_args()
+
+ Logger.normal("Downloading update excuse information for {}".format(opts.release))
+ with urllib.request.urlopen(UPDATE_EXCUSES.format(opts.release)) as response:
+ data_loaded = yaml.load(response.read())
+
+
+ # NOTE: arch.pkg indexed dicts of packages + triggers to recheck.
+ # used when a recheck of a pkg is required by multiple triggers
+ # to optimize use of autopkgtest infra.
+ rdeps_to_recheck = {}
- data_loaded = yaml.load(sys.stdin)
for pkg in data_loaded['sources']:
- if not pkg['is-candidate'] and 'autopkgtest' in pkg['reason']:
- for rdep, results in pkg['policy_info']['autopkgtest'].items():
- regressions = [ arch for arch, arch_res in results.items() if arch_res[0] == 'REGRESSION']
- if len(regressions) > 0 and rdep in extra_deps.keys():
- for arch in regressions:
- print(rerun_link(rdep.split("/")[0], arch, [pkg['source'] + "/" + pkg['new-version']] + extra_deps[rdep]))
-
+ pkg_name = pkg['source']
+ if pkg_name in pkgs:
+ Logger.normal('Inspecting {}'.format(pkg_name))
+ if not pkg['is-candidate'] and 'autopkgtest' in pkg['reason']:
+ for rdep, results in pkg['policy_info']['autopkgtest'].items():
+ regressions = [
+ arch for arch, arch_res in results.items() if arch_res[0] == 'REGRESSION'
+ ]
+ if len(regressions) > 0:
+ rdep_pkg_name, rdep_pkg_version = rdep.split('/')
+ latest_version = query_distro(rdep_pkg_name)
+ if (rdep_pkg_version != latest_version or opts.recheck):
+ trigger = '{}/{}'.format(rdep_pkg_name,
+ latest_version)
+ for arch in regressions:
+ if not arch in rdeps_to_recheck:
+ rdeps_to_recheck[arch] = {}
+
+ if (rdep_pkg_name in rdeps_to_recheck[arch] and
+ trigger not in rdeps_to_recheck[arch][rdep_pkg_name]['triggers']):
+ rdeps_to_recheck[arch][rdep_pkg_name]['triggers'].append(trigger)
+ else:
+ rdeps_to_recheck[arch][rdep_pkg_name] = {
+ 'triggers': [
+ pkg_name + "/" + pkg['new-version'],
+ trigger
+ ]
+ }
+
+ for arch in rdeps_to_recheck:
+ for rdep in rdeps_to_recheck[arch]:
+ recheck = rdeps_to_recheck[arch][rdep]
+ print(rerun_link(opts.release,
+ rdep,
+ arch,
+ recheck['triggers']))
+
if __name__ == "__main__":
main()