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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
#!/usr/bin/python
# rpmci_srpm_builder_main.py:
# Implementation of rpm-vcs-mirror
#
# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
# Copyright (C) 2010 Red Hat, Inc.
# Written by Colin Walters <walters@verbum.org>
import os
import sys
import time
import shutil
import optparse
from ConfigParser import SafeConfigParser
import logging
import tempfile
import subprocess
import urllib
import glib
import gobject
import gio
from . import msgqueue
from . import subtask
from . import versioned_repos
from . import artifact
from . import spec
from . import lame_vcs_abstraction
class SRPMBuilder(object):
def __init__(self, options, config):
self.config = config
self._options = options
mirror_dir = config.get('VCS', 'mirror_dir')
vcs_msgqueue_dir = config.get('VCS', 'msgqueue')
self._vcs_msgqueue = msgqueue.MessageQueue(vcs_msgqueue_dir)
srpm_msgqueue_dir = config.get('SRPM', 'msgqueue')
self._srpm_msgqueue = msgqueue.MessageQueue(srpm_msgqueue_dir)
self._artifactset = artifact.ArtifactSet.from_config(config)
self._target_vcs = {}
for target in self._artifactset.get_build_targets():
fedora_url = artifact.fedora_git_url_for_build_target(self.config, target)
upstream_url = artifact.upstream_vcs_url_for_build_target(self.config, target)
fedora_vcs = lame_vcs_abstraction.Vcs.new_from_spec(fedora_url)
fedora_vcs.set_directory(os.path.join(mirror_dir, urllib.quote(fedora_vcs.get_url_string(), '')))
upstream_vcs = lame_vcs_abstraction.Vcs.new_from_spec(upstream_url)
upstream_vcs.set_directory(os.path.join(mirror_dir, urllib.quote(upstream_vcs.get_url_string(), '')))
self._target_vcs[target] = (fedora_vcs, upstream_vcs)
self._srcdir = config.get('SRPM', 'srpm_dir')
if not os.path.isdir(self._srcdir):
os.makedirs(self._srcdir)
self._srcrepo = versioned_repos.VersionedRepo(self._srcdir)
def start(self):
self._vcs_msgqueue.connect(self._on_vcs_message)
def _get_base_rpmbuild_args(self, src_dirpath):
return ['--define', '_sourcedir ' + src_dirpath,
'--define', '_specdir ' + src_dirpath,
'--define', '_builddir ' + src_dirpath,
'--define', '_srcrpmdir ' + src_dirpath,
'--define', '_rpmdir ' + src_dirpath]
def _on_vcs_message(self, q, messages):
msg_list = list(messages)
num_msgs = len(msg_list)
logging.debug("Starting processing of %d messages" % (num_msgs, ))
for msg in msg_list:
url = msg.payload['url']
logging.debug("Processing update for VCS url %r" % (url, ))
self._handle_vcs_message_url(q, url)
q.consume(msg)
logging.debug("Processed %d messages successfully" % (num_msgs, ))
def _handle_vcs_message_url(self, q, url):
is_fedora = False
target = None
valid_urls = []
for iter_target,(fedora_vcs, upstream_vcs) in self._target_vcs.iteritems():
fedora_url = fedora_vcs.get_url_string()
is_fedora = (url == fedora_url)
if not is_fedora:
upstream_url = upstream_vcs.get_url_string()
if not url == upstream_url:
valid_urls.append(upstream_url)
continue
target = iter_target
break
assert target is not None, ("Couldn't find target for url %r; valid=%r" % (url, valid_urls))
(fedora_vcs, upstream_vcs) = self._target_vcs[target]
work_dir = tempfile.mkdtemp('.tmp', 'srpm-builder')
logging.debug("Creating new SRPM for %r in %r" % (target.module, work_dir))
fedora_dir = os.path.join(work_dir, target.module)
fedora_vcs.export_directory('HEAD', fedora_dir, sys.stderr)
specname = target.module + '.spec'
target_spec_path = os.path.join(fedora_dir, specname)
target_spec_obj = spec.Spec(target_spec_path)
latest_repopath = self._srcrepo.get_latest_path()
if latest_repopath:
orig_spec_path = os.path.join(latest_repopath, specname)
else:
orig_spec_path = None
if orig_spec_path is not None and os.path.isfile(orig_spec_path):
# Okay, we have a previous build, so now we "merge" by taking everything
# from the new spec file, except we use the Version/Release from the old
# one. This is necessary to pacify RPM's insistence on globally
# ordering versions, rather than simply having repository build versions.
orig_spec_obj = spec.Spec(orig_spec_path)
orig_version = orig_spec_obj.get_key('Version')
orig_release = orig_spec_obj.get_key('Release')
target_spec_obj.set_key('Version', orig_version)
target_spec_obj.set_key('Release', orig_release)
target_spec_obj.save()
exec_basedir = os.path.dirname(sys.argv[0])
args = [os.path.abspath(os.path.join(exec_basedir, 'rpmci-spec-vcs')),
'--vcsdir=' + upstream_vcs.get_directory(),
'set-revision', 'HEAD']
subtask.spawn_sync('rpmci-spec-vcs-%s' % (target.module, ),
args, cwd=fedora_dir)
args = ['rpmbuild']
args.extend(self._get_base_rpmbuild_args(fedora_dir))
args.extend(['-bs', specname])
subtask.spawn_sync('rpmbuild-srpm-%s' % (target.module, ),
args, cwd=fedora_dir)
srpm_path = None
srpm_basename = None
for filename in os.listdir(fedora_dir):
if filename.endswith('.src.rpm'):
srpm_basename = filename
srpm_path = os.path.join(fedora_dir, filename)
break
assert srpm_path is not None
self._srcrepo.commit([srpm_path])
self._srpm_msgqueue.append(msgqueue.Message(None, {'type': 'srpm'}, {'version': srpm_basename}))
def main():
glib.threads_init()
opts = optparse.OptionParser("usage: %prog [options]")
opts.add_option('-c', '--config', dest='config', help="Path to configuration file")
opts.add_option('', '--debug', action='store_true', help="Print verbose debugging")
(options, args) = opts.parse_args()
if options.config is None:
print "Must specify --config"
sys.exit(1)
config = SafeConfigParser({'home': os.environ['HOME']})
config.read(options.config)
level = logging.DEBUG if options.debug else logging.INFO
logging.basicConfig(stream=sys.stderr, level=level)
subtask.global_configure(config)
builder = SRPMBuilder(options, config)
builder.start()
logging.info("Awaiting events")
loop = glib.MainLoop()
loop.run()
|