]> git.pld-linux.org Git - projects/pld-builder.new.git/blame - PLD_Builder/rpm_builder.py
- rpm builder actually did something (immortal alien.spec) ;-)
[projects/pld-builder.new.git] / PLD_Builder / rpm_builder.py
CommitLineData
3ea4b156
MM
1import sys
2import os
3import atexit
4import time
5import urllib
6
7from config import config, init_conf
8from bqueue import B_Queue
9from acl import acl
10import lock
11import util
12import path
13import status
14import log
15import chroot
16import ftp
17import buildlogs
18
19# this code is duplicated in srpm_builder, but we
20# might want to handle some cases differently here
21def pick_request(q):
22 def mycmp(r1, r2):
23 if r1.kind != 'group' or r2.kind != 'group':
24 raise "non-group requests"
25 pri_diff = cmp(r1.priority, r2.priority)
26 if pri_diff == 0:
27 return cmp(r1.time, r2.time)
28 else:
29 return pri_diff
30 q.requests.sort(mycmp)
31 ret = q.requests[0]
32 q.requests = q.requests[1:]
33 return ret
34
35def handle_request(r):
36 def log_line(l):
37 log.notice(l)
38 util.append_to(spec_log, l)
39
40 def fetch_src(b):
41 src_url = config.control_url + "/srpms/" + r.id + "/" + b.src_rpm
42 log_line("fetching %s" % src_url)
43 start = time.time()
44 f = urllib.urlopen(src_url)
45 o = chroot.popen("cat > %s" % b.src_rpm, mode = "w")
46 bytes = util.sendfile(f, o)
47 f.close()
48 o.close()
49 t = time.time() - start
50 if t == 0:
51 log_line("fetched %d bytes" % bytes)
52 else:
53 log_line("fetched %d bytes, %.1f K/s" % (bytes, bytes / 1024.0 / t))
54
55 def build_rpm(b):
56 global spec_log
57 spec_log = tmp + b.spec + ".log"
58 status.push("building %s" % b.spec)
59 fetch_src(b)
60 res = chroot.run("rpm -U %s && rm -f %s" % (b.src_rpm, b.src_rpm),
61 logfile = spec_log)
62 if res:
63 log_line("error: installing src rpm failed")
64 else:
65 cmd = "cd rpm/SPECS; rpmbuild -bb %s" % b.spec
66 log_line("Building RPM using: %s" % cmd)
67 res = chroot.run(cmd, logfile = spec_log)
68 files = util.collect_files(spec_log)
69 if len(files) > 0:
70 all_files.extend(files)
71 else:
72 # FIXME: is it error?
73 log_line("error: No files produced.")
74 res = 1
75 buildlogs.add(logfile = spec_log, failed = res)
76 status.pop()
77 return res
78
79 tmp = path.spool_dir + r.id + "/"
80 os.mkdir(tmp)
81 atexit.register(util.clean_tmp, tmp)
82 user = acl.user(r.requester)
83 log.notice("started processing %s" % r.id)
84 all_files = []
85 for batch in r.batches:
86 log.notice("building %s" % batch.spec)
87 if build_rpm(batch):
88 # clean up
89 log.notice("building %s failed" % batch.spec)
90 chroot.run("rm -f %s" % string.join(all_files))
91 m = user.message_to()
92 m.set_headers(subject = "Binary: %s failed" % batch.spec)
93 # FIXME: write about other specs from group
94 m.write("Building RPM failed for %s.\nAttached log:\n" % batch.spec)
95 m.append_log(spec_log)
96 m.send()
97 buildlogs.flush()
98 return
99 log.notice("building %s finished" % batch.spec)
100 for f in all_files:
101 local = tmp + os.path.basename(f)
102 chroot.run("cat %s; rm -f %s" % (f, f), logfile = local)
103 ftp.add(local)
104
105 # FIXME: send notification?
106 buildlogs.flush()
107 ftp.flush()
108
109def check_load():
110 try:
111 f = open("/proc/loadavg")
112 if float(string.split(f.readline())[2]) > config.max_load:
113 sys.exit(0)
114 except:
115 pass
116
117def main():
118 if len(sys.argv) < 2:
119 raise "fatal: need to have builder name as first arg"
120 init_conf(sys.argv[1])
121 # allow only one build in given builder at once
122 if not lock.lock("building-rpm-for-%s" % config.builder, non_block = 1):
123 return
124 # don't kill server
125 check_load()
126 # not more then job_slots builds at once
127 locked = 0
128 for slot in range(config.job_slots):
129 if lock.lock("building-rpm-slot-%d" % slot, non_block = 1):
130 locked = 1
131 break
132 if not locked:
133 return
134
135 status.push("picking request for %s" % config.builder)
136 q = B_Queue(path.queue_file + "-" + config.builder)
137 q.lock(0)
138 q.read()
139 if q.requests == []:
140 return
141 r = pick_request(q)
142 q.write()
143 q.unlock()
144 status.pop()
145
146 # record fact that we got lock for this builder, load balancer
147 # will use it for fair-queuing
148 l = lock.lock("got-lock")
149 f = open(path.got_lock_file, "a")
150 f.write(config.builder + "\n")
151 f.close()
152 l.close()
153
154 msg = "handling request %s (%d) for %s from %s" \
155 % (r.id, r.no, config.builder, r.requester)
156 log.notice(msg)
157 status.push(msg)
158 handle_request(r)
159 status.pop()
160
161util.wrap(main)
This page took 0.280285 seconds and 4 git commands to generate.