~ubuntu-archive/ubuntu-archive-scripts/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/python3
# Request re-runs of autopkgtests for packages

from datetime import datetime
import os
import sys
import argparse
import json
import urllib.parse

import amqplib.client_0_8 as amqp

#my_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
my_dir = os.path.expanduser('~ubuntu-archive/proposed-migration/code/b2')


def parse_args():
    '''Parse command line arguments'''

    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--config',
                        help='britney config file (default: britney.conf.ubuntu.<series>)')
    parser.add_argument('-s', '--series', required=True,
                        help='Distro series name (required).')
    parser.add_argument('-a', '--architecture', action='append', default=[],
                        help='Only run test(s) on given architecture name(s). '
                        'Can be specified multiple times (default: all).')
    parser.add_argument('--trigger', action='append', default=[],
                        metavar='SOURCE/VERSION',
                        help='Add triggering package to request. '
                        'Can be specified multiple times.')
    parser.add_argument('--ppa', metavar='LPUSER/PPANAME', action='append',
                        default=[],
                        help='Enable PPA for requested test(s). '
                        'Can be specified multiple times.')
    parser.add_argument('--env', metavar='KEY=VALUE', action='append',
                        default=[],
                        help='List of VAR=value strings. '
                        'This can be used to influence a test\'s behaviour '
                        'from a test request. '
                        'Can be specified multiple times.')
    parser.add_argument('--test-git',
                        metavar='URL [branchname]',
                        help='A single URL or URL branchname. '
                        'The test will be git cloned from that URL and ran '
                        'from the checkout. This will not build binary '
                        'packages from the branch and run tests against '
                        'those, the test dependencies will be taken from the '
                        'archive, or PPA if given. In this case the '
                        'srcpkgname will only be used for the result path in '
                        'swift and be irrelevant for the actual test.')
    parser.add_argument('--build-git',
                        metavar='URL [branchname]',
                        help='A single URL or URL branchname. '
                        'Like --test-git`, but will first build binary '
                        'packages from the branch and run tests against those.')
    parser.add_argument('--test-bzr',
                        help='A single URL. '
                        'The test will be checked out with bzr from that URL. '
                        'Otherwise this has the same behaviour as test-git.')
    parser.add_argument('--all-proposed', action='store_true',
                        help='Disable apt pinning and use all of -proposed')
    parser.add_argument('--bulk', action='store_true',
                        help='Mark this as a bulk (low priority) test where possible')
    parser.add_argument('package', nargs='+',
                        help='Source package name(s) whose tests to run.')
    args = parser.parse_args()

    if not args.trigger and not args.ppa:
        parser.error('One of --trigger or --ppa must be given')

    # verify syntax of triggers
    for t in args.trigger:
        try:
            (src, ver) = t.split('/')
        except ValueError:
            parser.error('Invalid trigger format "%s", must be "sourcepkg/version"' % t)

    # verify syntax of PPAs
    for t in args.ppa:
        try:
            (user, name) = t.split('/')
        except ValueError:
            parser.error('Invalid ppa format "%s", must be "lpuser/ppaname"' % t)

    return args


def parse_config(config_file):
    '''Parse config file (like britney.py)'''

    config = argparse.Namespace()
    with open(config_file) as f:
        for k, v in [r.split('=', 1) for r in f if '=' in r and not r.strip().startswith('#')]:
            k = k.strip()
            if not getattr(config, k.lower(), None):
                setattr(config, k.lower(), v.strip())
    return config


if __name__ == '__main__':
    args = parse_args()
    britney_conf = os.path.join(my_dir, 'britney.conf')
    if args.config:
        config = parse_config(args.config)
    elif os.path.exists(britney_conf + '.ubuntu.' + args.series):
        config = parse_config(britney_conf + '.ubuntu.' + args.series)
    else:
        config = parse_config(britney_conf)
    if not args.architecture:
        args.architecture = config.adt_arches.split()

    context = ''
    params = {}
    if args.bulk:
        context = 'huge-'
    if args.trigger:
        params['triggers'] = args.trigger
    if args.ppa:
        params['ppas'] = args.ppa
        context = 'ppa-'
    if args.env:
        params['env'] = args.env
    if args.test_git:
        params['test-git'] = args.test_git
        context = 'upstream-'
    elif args.build_git:
        params['build-git'] = args.build_git
        context = 'upstream-'
    if args.test_bzr:
        params['test-bzr'] = args.test_bzr
        context = 'upstream-'
    if args.all_proposed:
        params['all-proposed'] = True
    try:
        params['requester'] = os.environ['SUDO_USER']
    except KeyError:
        pass
    params['submit-time'] = datetime.strftime(datetime.utcnow(), '%Y-%m-%d %H:%M:%S%z')
    params = '\n' + json.dumps(params)

    creds = urllib.parse.urlsplit(config.adt_amqp, allow_fragments=False)
    assert creds.scheme == 'amqp'

    with amqp.Connection(creds.hostname, userid=creds.username,
                         password=creds.password) as amqp_con:
        with amqp_con.channel() as ch:
            for arch in args.architecture:
                queue = 'debci-%s%s-%s' % (context, args.series, arch)
                for pkg in args.package:
                    ch.basic_publish(amqp.Message(pkg + params,
                                                  delivery_mode=2),  # persistent
                                     routing_key=queue)