summaryrefslogtreecommitdiffstats
path: root/koji-build.py
blob: 2a1c99de543852559b5eeced826f4f2c6521b37a (plain)
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
#! /usr/bin/env python

import os
import sys
import errno
import koji
import optparse
import time
import random
import string
import urlgrabber
import urlgrabber.progress

HOME = os.getenv('HOME')
BASEURL = 'http://kojipkgs.fedoraproject.org/work/'
workingdir = os.getcwd()

def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST:
            pass
        else: raise

def _unique_path(prefix):
    """Create a unique path fragment by appending a path component
    to prefix.  The path component will consist of a string of letter and numbers
    that is unlikely to be a duplicate, but is not guaranteed to be unique."""
    # Use time() in the dirname to provide a little more information when
    # browsing the filesystem.
    # For some reason repr(time.time()) includes 4 or 5
    # more digits of precision than str(time.time())
    return '%s/%r.%s' % (prefix, time.time(),
                      ''.join([random.choice(string.ascii_letters) for i in range(8)]))


def _build_srpm(opts, srpm):
    session = koji.ClientSession('http://koji.fedoraproject.org/kojihub')
    session.ssl_login(HOME + '/.fedora.cert',
                      HOME + '/.fedora-upload-ca.cert',
                      HOME + '/.fedora-server-ca.cert')
    serverdir = _unique_path('cli-build')

    if not opts.quiet:
        print "Uploading %s" % srpm
    session.uploadWrapper(srpm, serverdir)
    source = "%s/%s" % (serverdir, os.path.basename(srpm))

    if not opts.quiet:
        print "Upload complete. Building."
    task_id = session.build(source, opts.target, {'scratch': True})

    '''Wait for it to finish'''
    finished = False
    while not finished:
        if opts.verbose:
            print "Waiting for task %s to complete. Sleeping 60 seconds" % task_id
        time.sleep(60)
        task = session.getTaskInfo(task_id, request=True)
        if task['state'] == koji.TASK_STATES['CLOSED']:
            finished = True
            succeeded = True
        elif task['state'] not in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']):
            finished = True
            succeeded = False

    if not succeeded:
        print "Build %d failed" % task_id
        return 1

    # Download the finished build
    tasks = session.listTasks(opts={'parent': task_id,
                                    'method': 'buildArch',
                                    'arch': ['i386', 'x86_64'],
                                    'state': [koji.TASK_STATES['CLOSED']],
                                    'decode': True})

    prog_meter = urlgrabber.progress.TextMeter()
    if opts.quiet:
        prog_meter = None

    for task in tasks:
        if (opts.build_id):
            basepath = '%s/%s' % (workingdir, opts.build_id)
        else:
            basepath = '%s/output' % workingdir
        outputpath = '%s/%s' % (basepath, task['arch'])
        mkdir_p(outputpath)
        os.chdir(outputpath)

        if not opts.quiet:
            print 'Downloading rpms from task %i: %s' % (task['id'], koji.taskLabel(task))

        base_path = koji.pathinfo.taskrelpath(task['id'])
        output = session.listTaskOutput(task['id'])
        for filename in output:
            download = False

            if filename.endswith('.rpm'):
                download = True
                if (filename.find('debuginfo') != -1):
                    debugpath = '%s/%s' % (outputpath, 'DEBUGINFO')
                    mkdir_p(debugpath)
                    os.chdir(debugpath)
                else:
                    if filename.endswith('.src.rpm'):
                        srpmpath = '%s/%s' % (basepath, 'SRPMS')
                        mkdir_p(srpmpath)
                        os.chdir(srpmpath)
                    else:
                        rpmpath = '%s/%s' % (outputpath, 'RPMS')
                        mkdir_p(rpmpath)
                        os.chdir(rpmpath)
            if filename.endswith('.log'):
                download = True
                logpath = '%s/%s' % (outputpath, 'logs')
                mkdir_p(logpath)
                os.chdir(logpath)

            if download:
                urlgrabber.grabber.urlgrab(BASEURL + base_path + '/' + filename,
                                           progress_obj=prog_meter)
    # Return to our original working directory
    os.chdir(workingdir)
    return 0

if __name__ == "__main__":
    usage = 'usage: %prog [options] <srpm> <target>'
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('--verbose', action='store_true',
                      default=False,
                      help="Display verbose progress")
    parser.add_option('--quiet', action='store_true',
                      default=False,
                      help="Only print errors")
    parser.add_option('--build_id', dest='build_id', default=None,
                      help='Specify a build_id for the output')
    parser.add_option('--target', dest='target', default='dist-rawhide',
                      help='Specify the target platform (default: dist-rawhide)')

    opts, args = parser.parse_args()

    if len(args) < 1:
        parser.error('Must specify SRPM to build')

    srpm = args[0]

    ret = _build_srpm(opts, srpm)
    sys.exit(ret)